Mobile Safari applies :active on touchstart and clears it on touchend. This has some surprising consequences including:
- A page with no touch event handlers doesn't get :active effects at all
- A button with an :active effect will be triggered while scrolling over top of it (even though native platform convention is not to trigger active effects in such cases)
I changed this for chromium back in 2012 (see bug 96060 and http://crbug.com/133928). Basically we set :active after a short delay when tap starts (what we call "GestureShowPress"), and clear it when a tap completes or is aborted (but we may also delay this to ensure :active is shown long enough to be visible when the user taps quickly).
What do you think, is it perhaps worth changing Safari to do something more rational here? I'm open to changing chromium again if we can come up with a model we agree is better. One thing I don't like about our current model is that it's difficult to implement the same behavior from JS (unlike IE and Safari, there are no DOM events associated directly with the application and removal of :active for touch).
Thanks for filing this.
In the docs we have this:
You can also use the -webkit-tap-highlight-color CSS property >>>in combination with setting a touch event<<< to configure buttons to behave similar to the desktop. On iOS, mouse events are sent so quickly that the down or active state is never received. Therefore, the :active pseudo state is triggered only when there is a touch event set on the HTML element—for example, when ontouchstart is set on the element as follows:
<button class="action" ontouchstart="" style="-webkit-tap-highlight-color: rgba(0,0,0,0);">Testing Touch on iOS</button>
Now when the button is tapped and held on iOS, the button changes to the specified color without the surrounding transparent gray color appearing.
Currently in iOS (just confirmed in 8.1 but I believe it's the same in 9), when any touch* event is set to the document (or any parent container) all child elements are also affected and start showing the :hover/:active styles immediately if we touch them even if we just want to scroll the page. This can be quite annoying on specific pages where :hover/:active styles are applied on big elements and even more when transitions, etc. are used (example: scroll to the footer of http://phonegap.com/ and then try scrolling the page up by touching any of the big white links). This issue affects large amount of websites and popular frameworks like jQuery mobile, etc.
I don't see any logic why setting any touch* event handler to an element would trigger this behavior change. This looks more like an actual documented hack. It would have been much better if, for example, a vendor prefixed -webkit-* CSS property was introduced for the purpose instead.
IMHO it should be fixed like in Chrome/Android with the timeout logic Rick Byers describes above. According to my testing it works really well the way they've implemented it.