Archive of February 2013

Mobile Browsers lost their :FOCUS


I had been hoping to display a CSS user interaction technique that would make context sensitive drop-down menus, but it unfortunately doesn't work on current mobile phones (webkit based ones, at any rate). The problem is the mobile browsers don't recognize :FOCUS on any element other than text entry areas.

See, according to W3C's HTML5 recommendation (and implemented in all modern desktop browsers), any element can receive user focus if they have a "tabindex" attribute assigned to them. If that value is a positive number, they then also enter the tab sequence for keyboard navigation. It also means that, in desktop browsers, clicking on the element allows the client to render special :FOCUS selector, that is normally reserved mostly for form elements and links. With a little bit of work, one can create a nice little context menu as follows:


<div tabindex="1" class="opt-sel">Options
  <ul tabindex="0"><!-- this needs a tabindex too, to allow styling it's :ACTIVE state to allow for a complete "click" of it's children -->
    <li><a href="#1">Option 1</a></li>
    <li><a href="#2">Option 2</a></li>
    <li><a href="#3">Option 3</a></li>
    <li><a href="#4">Option 4</a></li>

CSS (the effective bits):

.opt-sel UL {
.opt-sel:NOT(:FOCUS) UL { /* only hide the sub-menu in modern browsers */
.opt-sel:FOCUS UL,
.opt-sel UL:ACTIVE { 
A child element's mousedown event causes said element to pull focus away 
from the parent div and disappear immediately, and disables any "click" 
from occurring. Styling the UL's :ACTIVE state keeps the child elements 
around until mouseup, and lets the click happen.

And, on desktop browsers, this works great. Click on the word "options", and a list of options appears and stays open until you click somewhere else. If you click one of the available options, the desired action occurs and the list nicely disappears. Now, it's not perfect — you can't tab through the options, for example (though, you should be able to) but it's no worse than current :HOVER menus.

Now, one would expect this to work beautifully on a touchscreen/mobile environment. Unfortunately it doesn't. Instead, what happens is clicking (or touching) on a tabindex'ed element results in the rendering of a :HOVER selector — :FOCUS is completely ignored. Not only that, but :FOCUS doesn't even effect the usual suspects. Only elements that accept keyboard interaction are allowed to use :FOCUS state — and only when they do need a keyboard; setting readonly="readonly" removes the :FOCUS state. I assume that the reason for this is that many pre-mobile site's navigation systems broke when :HOVER disappeared. And it makes sense. Touch screens can't tell you if you're hovering, only if you're touching. So, instead of following standards, mobile browsers rewarded laziness, and changed the rules. Problem is, the only way to make something recognize :HOVER is by setting a tabindex value, which means it still won't be used by the lazy coders this change was trying to appease — and it hijacks the first click on an element to set :HOVER, requiring users to click (or touch) twice.

What should happen, in my opinion (and the W3C's as well, if I read the latest recommendation correctly) is that :HOVER should be ignored (or at least mimic :ACTIVE) on touch screens, since they don't use "pointing devices" and :FOCUS should work on any element that accepts tab navigation. Don't break things to appease lazy coding. That's what made IE6 and quirks mode happen to us.

Tags: , ,
2013.02.04 09:51 AM | Permalink 0 Comments