I know this is "by design", but what is the best practice for dealing with this, in a web app and especially Polymer?
I use on-tap and sometimes on iOS etc. it takes a few taps to fire whatever event. This makes for terrible UX and we web app developers are already fighting an uphill battle relative to native apps.
Related:
https://developers.google.com/mobile/articles/fast_buttons
https://www.polymer-project.org/0.5/docs/polymer/touch.html
Thanks for the help folks! This seems to have resolved it for me:
body {
-ms-touch-action: none;
touch-action: none
}
From https://developers.google.com/web/fundamentals/input/touch/touchevents/#control-gestures-using-touch-actions:
The CSS property touch-action allows you to control the default touch
behavior of an element. In our examples, we use touch-action: none to
prevent the browser from doing anything with a users’ touch, allowing
us to intercept all of the touch events.
touch-action allows you to disable gestures implemented by a browser.
For example, IE10+ supports a double-tap to zoom gesture. By setting a
touch-action of pan-x | pan-y | manipulation you prevent the default
double-tap behavior. This allows you to implement a double-tap gesture
yourself. In the case of IE10+, it also eliminates the 300ms click
delay.
What is the reliable approach to develop a website that is used on the computer that is a hybrid, in other words have both a mouse (or a touch pad) and a touch screen and can be used by a user in both ways at the same time.
Especially the question is how to deal with the mouse cursor, that must be seen when using a mouse and is distracting once the user uses her finger.
The goal is to develop a single page, not two separate pages, one for mouse and other for the touch. Style cursor = 'none' is killing the cursor over the specified elements completely, this is not desired.
I am not talking about scrolling or zooming, but about clickable/touchable divs/spans/images, that can react some how. For instance I have a table where each cell could be clicked to mark (change color). Same with buttons, once you touch the button with the finger, the mouse cursor will stay on top of it and distract.
HTML5 does support the concept of touch events, perhaps you can dynamically change behavior/style etc in javascript based on detected events (e.g. turn your page into touch mode "cursor = none" if you detect a touch event but switch back to mouse visible style if you detect mouse move events).
This is by no means completely reliable as touchevent implementation is browser (somewhat patchy support at that), OS and possibly hardware dependent. e.g. Older OSes might translate touch event into mouse click events or older browsers might not support OS's touch events and OS fallsback to mouse click events.
See Touch And Mouse for more info that might help you.
I am doing a simple :hover slide-in cover as shown in picture, it's supposed to slide in a "favorite article" control, which user can then click to favorite this item.
While it work well on desktop with mouse hover and click, I am not sure if it can be used as an effective control on mobile or other device (ie. click to toggle, then click again to favorite item) .
If I understand correctly, at least on iOS (Safari) and Android (Chrome), the default browser behaviour is to emulate touch as both hover and click. But is it a standard? eg.
Will Windows Phone or maybe a Wii U does the same?
Will click be fired about 300ms after hover, so there can be ghost click issue?
I can certainly bind a click/touch event on this element, just wondering if css :hover is sufficient nowadays.
To clarify: I am not asking about :hover support, which only make senses in a pointer driven environment. I am asking if devices can and should handle hover-able element as users click/tap (as iOS/Android do)
Your question isn't totally clear and I cannot understand whether you're asking "Can I use :hover across all the devices?" or "Will :hover behave the same across all the devices?" or "Is :hover a standard element on the web?"
Also it greatly depends of your concept of "all devices", if you have in mind the currently most used devices or you are taking in account also the less-known and used devices.
I will quote you the following, but I am pretty sure you have already read that:
Interactive user agents sometimes change the rendering in response to
user actions. CSS provides three pseudo-classes for common cases:
The :hover pseudo-class applies while the user designates an element
(with some pointing device), but does not activate it. For example, a
visual user agent could apply this pseudo-class when the cursor (mouse
pointer) hovers over a box generated by the element. User agents not
supporting interactive media do not have to support this pseudo-class.
Some conforming user agents supporting interactive media may not be
able to support this pseudo-class (e.g., a pen device). The :active
pseudo-class applies while an element is being activated by the user.
For example, between the times the user presses the mouse button and
releases it.
CSS does not define which elements may be in the above states, or how
the states are entered and left. Scripting may change whether elements
react to user events or not, and different devices and UAs may have
different ways of pointing to, or activating elements.
5.11.3 The dynamic pseudo-classes: :hover, :active, and :focus
http://www.w3.org/TR/CSS2/selector.html#dynamic-pseudo-classes
As you can see on the W3C specification it claims that the :hover pseudo-class is not required to a non-interactive media user agents as well as some interactive media user agents.
Therefore is safe to assume :hover is not always supported.
To dig deep on the matter, take a read at the following specification for Safari Mobile:
Additionally, Safari on iOS users interact with your web content
directly with their fingers, rather than using a mouse. This creates
new opportunities for touch-enabled interfaces, but does not work well
with hover states. For example, a mouse pointer can hover over a
webpage element and trigger an event; a finger on a Multi-Touch screen
cannot. For this reason, mouse events are emulated in Safari on iOS.
As a result, elements that rely only on mousemove, mouseover, mouseout
or the CSS pseudo-class :hover may not always behave as expected on a
touch-screen device such as iPad or iPhone.
You can handle touches directly or even detect advanced gestures in
Safari on iOS, using the DOM Touch events touchstart, touchmove,
touchend, and touchcancel. Unlike mouse events which are emulated, DOM
Touch events are specifically designed to work with touch interfaces,
so their behavior is reliable and expected.
5. Prepare for a touch interface
https://developer.apple.com/library/content/technotes/tn2010/tn2262/_index.html
Apple clearly states here that they tend to emulate the pointer with the touch gestures, however they clearly suggest to avoid using the :hover pseudo-class as won't behave the same on their touch device.
We could dig deeper and fetch every documentation for each user-agent existing on earth but the previous two are enough to assume the following:
Non interactive devices do not have to support :hover
Interactive devices can support the pseudo-class (but it's not mandatory and they can ignore it, for example screen-readers or braille screens)
Apple touch devices in absence of a pointer emulates :hover
It is safe to assume current touch devices also emulates :hover
It is safe to assume any other browser/device don't necessarily have to support :hover depending on their interface.
Very likely the recent browsers will all support :hover because is a visual aid for the user.
So to answer to all the question(s) I have assumed above:
"Is :hover a standard element on the web?"
Hover is a standard W3C in fact it claims it must be triggered by a pointer event, but isn't required for some interfaces.
"Can I use :hover across all the devices?"
Yes you probably can. The devices which won't support :hover very likely are devices/users that probably aren't your main target. Better ask yourself "Who will be the end-user of my product?" if they are only mobile users or only blind people or only people who like to browse using the Nintendo DS then don't use :hover events, otherwise do.
"Will :hover behave the same across all the devices?"
No, as Apple stated on their devices will not behave the same as a desktop would, and that probably reflects the same behaviour on all devices without a pointer.
If you plan to have an user action via a hover state don't do it. This is generally bad practice and it should avoided in any case, including desktop devices. Hover is not an call to action, click is. Hover should not be treated as a "toggle" but more like a visual helper for the user making him/her understand that element, if clicked, triggers an action.
If I understood your application then hover isn't reliable and in your specific case you should rethink on how it should work.
Use a more reliable method (and expected from your user)
Hovering your cursor over a webpage element is a common action when browsing with a mouse and keyboard, but there is no equivalent when it comes to touch-based browsing. This topic demonstrates how to use the aria-haspopup Document Object Model (DOM) property to simulate hover on touch-enabled devices with Internet Explorer 10 on Windows 8.
This behavior is not applicable to Internet Explorer 10 on Windows 7 (which does not support hover simulation with aria-haspopup) or Internet Explorer 11 on Windows 8.1 (which has built-in touch hover support).
In touch scenarios, hover is applied to an element while it is being touched. However, tapping an element can also activate an element, such as navigating a link. Effectively, a tap is both hover and activation in one action. This makes interactive content hidden behind hover inaccessible for touch users. The interaction model is completely different, and there is no touch analog to hovering the cursor over a page element.
The best practice is to not use hover to hide content that a user can
interact with. Instead, consider using the onclick event to toggle the
visibility.
It seems to me that part of this question hasn't yet been answered, namely what is the actual behaviour of Windows phones in relation to 'hover'. To clarify:
Consider a web page written for desktop/mouse use in which there is css markup so that 'hover' changes a style applied to an object. If one views that page on iPhone or Android and taps on the object the style change occurs. (i.e. it is behaving as if the object had an onClick() event handler to change the style). Does the same thing happen on a Windows Phone?
I can answer that question, at least for the Nokia Lumia 630 running Win 8.1:
No. As you press down with your finger in the initial part of a tap the style change does occur, but when you release your finger at the end of the tap the style reverts to the original. (This is arguably a more valid interpretation of 'hover' for touch, although whether it is of any practical use is another matter.)
I would add that the iPhone/Safari interpretation of hover also has an 'off' state. This is triggered when you tap on another object.
To show this and allow testing on different devices/browsers I have set up a demo page at www.davidleader.net/mobiledemo.html. This implements onClick(), onMouseover() and :hover to change the opacity of an image, revealing a different one underneath. (It therefore depends on support for opacity, but this has been around for a while.) There is also a 'dumb graphic' to click on to demonstrate the end of hover on the iPhone.
To summarize, as well as there being no de jure standards for interpretation of hover on mobile devices there are no de facto ones either. Therefore if you are targetting mobiles, avoid 'hover'.
Theres none at the moment that has a good support for :hover state in mobile
See related question about this
I havent use Modernzr.js for mobile , but it says it can detect if the browser supports touch events , so basically it adds ".touch" class in the html tag if the user uses mobile device.
so you'll use it like this, for e.g
.touch a:active{ /*css code here */ }
hopefully this would help somehow
When it comes to mobile phones, I doubt there is any standard. Yes it is very common for a touch device to apply a hover state while is is being touched, but you can never tell if a user could be using any number of browsers that may interpret a hover state differently.
I would say your best bet would be to shoot for the lowest common denominator and just assume that every touch device can only respond to touch actions.
The answer to that, of course, is to write media queries and/or javascript to force the browsers to act the way you want it to.
That's just my personal philosophy, for what it is worth.
I'm making my own little Javascript library that makes it easy to replace the default scrollbars for your Website (and mine) with custom ones. Part of that means giving the BODY element an "overflow:hidden" style to hide the normal scrollbars. However, this prevents all scrolling except for that which is done in code.
I have everything working in terms of showing the bar and having it scroll when you click/drag it. However, many touchpads (like on the computer I'm testing this with) have a feature where you can scroll by sliding a finger along the right side of the pad. I need the library not to break that, so I need some way of detecting when the user tries to scroll this way.
I thought it would be interpreted by the browser as a mouse wheel, so I set up an onmousewheel event, but that doesn't seem to capture it at all. For the record, I'm testing with Firefox 25.0.1.
Is there any way to capture the trackpack scrolling, preferably without an external library? I'm trying to keep this as self-contained and lightweight as possible, but if I absolutely need to, I guess I can use jQuery and its mousewheel extension...
Some browsers use the onwheel event instead of onmousewheel. So, it's usually a good idea to listen for both events.
See this MDN article for more about onwheel.
I'd like to detect in some "nice" way (Modernizr most likely, but whatever) whether a layout should have embedded scrollable regions of the page, or else (for some mobile use) should just flow all content as one scrollable mass.
The specific case is a "EULA"-like page, where there's a form with an "I ACCEPT" button or whatever, and then a mass of hideous all-caps legal stuff. On a big screen I'd like the whole form visible, so I'd like to put the legal stuff in its own scrolling box. However, on a mobile device that would be kind-of ugly (though I'm no mobile ux expert), so I was thinking of just dropping it all in-line so that the user could read the text (LOL) with simple swipes to scroll, and then at the bottom the buttons would scroll into view.
I suppose I could just check for touch with Modernizr, but that doesn't seem quite right.
edit — though I'm pretty sure that what I described would probably be a usability win anyway, the thing is I'm finding that my Android devices won't pay any attention to "overflow: auto" on a <div> in the middle of a page.
The approach I've taken is to rely on Modernizr.touch and Modernizr.overflowscrolling tests. If Modernizr inserts the touch and no-overflowscrolling classes in the html element in the DOM (or just check Modernizr.touch and Modernizr.overflowscrolling directly), then I avoid overflow:auto. This means that Android devices that mishandle overflow:auto do not get it.
This might be an imperfect solution; there might be devices that can handle overflow:auto that don't get it in this case. But that's not exactly the end of the world, at least in my case. And it seems to work correctly for all the most common devices/browsers.
And it has the virtue of being simple. I already had Modernizr loaded for other uses.
As others have said, the Modernizr.overflowscrolling checks for the overflow-scrolling css property, not for whether the device can scroll content within a div using overflow: auto.
In fact, in my recent testing, the Nexus 5 actually returns Modernizr.overflowscrolling as false, so it cannot be relied on.
This very small script (with no dependencies) seems to enable touch scrolling for devices (Android 2.3) lacking support...
http://chris-barr.com/2010/05/scrolling_a_overflowauto_element_on_a_touch_screen_device/
Link to repo:
https://github.com/chrismbarr/TouchScroll