Pure css for :hover only with mouse - javascript

:hovering on a touch screen can be an accessibility problem (dropdowns) or just muck up design elements (changing colour on a button press and not reverting due to the virtual hover).
So I've resolved to having different behaviour when an element is touched and when it is hovered with the mouse. This is easy enough to implement with Javascript and leveraging mousein and mouseout events, and adding a hover class where appropriate. There are two main problems with this:
It's Javascript based which has a number of implications. I wouldn't call not having hover functionality an accessibility issue, as there is a pointer cursor, though.
My main problem is that I will have to manually indicate which elements need the classes added outside of my CSS styling. This is extra work, adds an extra area to make mistakes and isn't semantically nice.
So my question is: is there any pure CSS way to detect if and only if the mouse has hovered over an element? One that doesn't respond to touches.
It is not sufficient to detect if a device is touch capable and remove hover functionality from them. Now that many devices have both mouse and touch, this will hinder a perfectly good mouse-enabled experience.

Method 1: Javascript
Why not start with the body having a .no-touch class on it, and then, using JS, detect the device, and remove the class if the device is mobile.
if(//Code to detect mobile)
$("body").removeClass("no-touch");
Then, in your CSS, code all :hover to be dependent on that parent class.
.no-touch a:hover
{
text-decoration: underline;
}
This will ensure that the hover styles are enabled by default if JS fails, as well as preventing the otherwise long process of delegating each and every element that you want to disable hover for.
The converse of this would be to add a class if the device is mobile, and then code the CSS to exclude the body that has that class:
body:not(.touch) a:hover
{
text-decoration: underline;
}
It's not perfect, as it still requires JS, but there is currently not a known purely-css way to detect touch events as opposed to mouse events, at least as I've been able to find through a somewhat extensive Google search.
Method 2: CSS Media Queries
The other option would be to use media queries, but this still leaves a lot to be desired, as devices continue to get better resolution; some tablets can have screen widths equivalent to some old monitors, and unfortunately, old technology dies very slowly.
This has the advantage of being purely CSS, but has its own pitfalls all the same.
You may have someone using an iPad in landscape # 1024x768 that would be considered a touch device, while an older gentleman is using a desktop on an old 3x2 lcd monitor that has the same resolution: 1024x768
Here's the code though, if you want it:
#media all and (min-width: 1024px)
{
a:hover
{
text-decoration: underline;
}
}

Solution with CSS only, without Javascript
Use media hover with media pointer will help you resolve this issue:
#media (hover: hover) and (pointer: fine) {
a:hover { color: red; }
}

Related

Disable css hover when touch end in touch device

In pure JavaScript, How can I disable the hover effect (of a div or btn ...etc) when user's touch end in touchable devices?
I have some anchors and buttons with effects on hovering, but on touch devices the effect of touch remains visible even after the user takes his finger off the screen.
I don't want the hover effect to be completely removed from touch devices... but what I want is for the hover to end after I stop touching the element.
I tried to play with the touchend in JavaScript but it don't work.
Can anyone help?
:hover is for pointing devices. You shouldn't be trying to optimize it for other types. Here is a definition from mdn:
The :hover CSS pseudo-class matches when the user interacts with an element with a pointing device, but does not necessarily activate it. It is generally triggered when the user hovers over an element with the cursor (mouse pointer).
A wise thing to do to avoid this weird behavior for non-pointing devices, is to apply the hover effect only for those who support it with #media (pointer: fine), like so:
button {
/* Styles for all type of devices */
}
#media (pointer: fine) {
button {
/* Styles for pointing devices */
}
button:hover {
/* Hover effects for pointing devices */
color:red;
}
}

Does iOS/mobile Safari provide a javascript event or a media query for its font resizing control?

A responsive website that I style uses js to determine font sizes then applies classes that are used by css for various layout adjustments. In a nutshell, my js detects the resize of a span wrapped around a text character. The newest version of mobile Safari provides a font resize control and its zoom mechanism isn't triggering my detection js. Any ideas about events or other changes that I can use to detect mobile Safari's font resizing? Maybe a css media query? I tried a solution based on js intersectionobserver: worked on desktop but not mobile :-(
According to MDN
The text-size-adjust CSS property controls the text inflation
algorithm used on some smartphones and tablets. Other browsers will
ignore this property.
Be sure to include CSS properties such as
/* Keyword values */
text-size-adjust: none;
text-size-adjust: auto;
/* <percentage> value */
text-size-adjust: 80%;
/* Global values */
text-size-adjust: inherit;
text-size-adjust: initial;
text-size-adjust: unset;
However, only non-percentage values are supported in Safari for iOS.
Also, consider looking at Apple's documentation.
which explains how percentages for a text-resize factor can be used.
html {-webkit-text-size-adjust:200%}
I am not sure which one of these is correct since they conflict each other. You would have to true for yourself and see what works best for you.
PS: Be sure to include -webkit- prefix for mentioned properties to make sure it works for safari and other WebKit browsers.
So what mobile safari does is: when the font is enlarged, it's actually the viewport becoming narrower. There is a widely supported window.matchMedia(media query here) method that returns a "media query object" to which a listener can be added. In my case, I want to know when the viewport is narrower than apx. 320px ... in which case I'll apply my styling classes.

How to hide hover-effects on a website which occure while scrolling on elements on a mobile device?

on my website I got a navigation with many elements. The navigation is scrollable and if you hover over an element, it gets highlighted.
The Problem: If I visit my website with my iPad, while scrolling in the navigation, the element I drag on shows its hover-effect and gets highlighted. I don't want this to happen, whats a good solution for this problem?
Thanks in advance!!
I have not try this yet but you can consider this:
Add an on-scroll function to <body>, in the function, set the color of all elements in navigation list to normal color(the color when not hovered at), so that when you scroll the page on your Ipad, even you drag the element it will still not highlighted.
<body onscroll="scroll_function()">
<script>
function scroll_function(){
document.getElementByClassName("element_name").style.backgroundColor = ... (your normal color)
}
</script>
Create an CSS media query that will use custom css on devices smaller or a larger screen than x pixels
#media only screen and (max-width: 600px) {
some-element:hover{
text-decoration:none;
}
}
Hover effects are pointless on mobile devices and tablets because you do not use a mouse to hover over elements.
Use all you hover effects as such:
#media screen and (min-width: 1024px) {
/* STYLES HERE */
}
If you still use the hover effects on all media queries, when you click on elements, the hover effect will take place.
Working without your code (always good to include that in a question btw), I'm gathering that the hover effect will be entirely CSS in spite of the javascript tag in the question, if that is the case you can use media queries to resolve this by simply creating a profile for devices you don't want the hover effect to happen on.
WRT the somewhat troublesome larger resolutions on modern handhelds, here is a quite extensive list of media query resolutions for differing handheld devices which should be helpful if you were to go down the route of attempting an MQ solution.

Can't get this CSS transition to properly function on an iPhone

I'm currently working on a CSS transition and I'm struggling to find the proper Javascript to make it function properly on a mobile device.
http://seancrater.com/test/
In the section, "The Dirty Dozen Plus", the transition can be seen. I currently have
ontouchstart="this.classList.toggle('hover');
added to each of the DIVs but it currently requires you to hold down your finger on it from a mobile device to keep it on the transition state. I was wondering if anybody could give me some insight on how to make it a single click to make it stay in the transition state. I tried the pseudo :focus and it stopped it from functioning all together.
Thanks! -Sean
As others have stated, you'll need to avoid :hover.
The easiest way to address your issue is to update your CSS like so:
.top:hover,
.top.touched {
-webkit-transform:translateY(-150px);
-webkit-transition: all .5s;
}
And then add touched as a class to your elements on touchstart or touchend. My guess is you'll want to maintain which element currently is touched, so you can remove the transitioned state when a user scrolls or touches another element.
(EDIT: Updated fiddle to allow user to tap close the element)
http://jsfiddle.net/4n6Z4/1/
Shell, for easier testing on a smartphone:
http://fiddle.jshell.net/4n6Z4/1/show/
ontouchstart="this.classList.toggle('click'); There are no hover events in mobile. You need to turn your hover event into a click event for mobile phones. Use javascript to detect if it's a phone or not. Setup a constant var phone = false and if it's a phone and set it to true and if not it remains false. Then use it in your function that controls / or triggers that animation.
You cannot use :hover on mobile.
more info
As you know, :hover behavior doesn’t exist on touch screen devices. So
when you design a responsive website, you should carefully plan when
and where to use :hover interactions. Simple links that open some URL
will loose their :hover effect on some touch screen devices. On iOS
:hover is triggered before the click event, so you will see the hover
style for a brief moment before the page changes. Those are minor
things, they don’t affect the functionality of the site. The real
problem is a :hover that either hides or shows another element using
display or visibility CSS properties. This type of :hover will
transform into the double tap behavior on touch screens.
http://www.prowebdesign.ro/how-to-deal-with-hover-on-touch-screen-devices/

Touch device HTML element :hover state

There is a HTML button, with 3 backgrounds - each for normal, hover and clicked states. Of course, it works fine with non touch device. If the button is clicked on touch device, the :hover state is also triggered and stays until another element is touched.
Is it possible to programmatically remove :hover state from element after it was clicked or prevent it from activating on touch devices?
Sorry, but suggestions to a detect mouseover and mouseout events and add artificial classes are not accepted.
One possible solution is to add "no-touch" class to html element in advance and remove it if only touch device is detected. In that case, CSS selector "html.no-touch button:hover" will not match for touch device.
Do you know more elegant solutions you may suggest?
I would try to overwrite the :hover state in an additional style-sheet for handheld devices like:
<link rel="stylesheet" type="text/css" href="handheld.css" media="handheld">
and in handheld.css put something like:
#some_selector:hover {
background: none; /* if you are setting a background in the main css file for example */
}
However, I´m not sure if handheld and touch screen are completely the same, there might be devices that have a touch screen and are not qualified as a handheld.
Edit: It seems you cannot detect touch screen devices 100% reliably, also see this question.
Seems that this issue can be resolved by overwriting the :hover state for a given element in media query - see this question:
CSS hover not being ignored on touch screen devices

Categories

Resources