Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use :focus as a :hover replacement for keyboard navigation

WCAG 2.0 recommends to also use :focus when :hover is used on link elements to support keyboard navigation. This works well for link elements, but there are a couple of differences between the two.

  • any element can have the :hover state while only very few can be focused
  • when hovering over an element, you also hover over all of its parent elements. This is not the case with focus

This question is strictly about css. Is there a way to simulate the behavior of :hover (as described above) for keyboard navigation? Or are there any strong reasons why one would not want that?

To make it more clear here is an example:

html:

<div id="box">
    foo bar
    <a href="#">click me</a>
</div>

css:

#box {
    opacity: 0.3;
}
#box:hover {
    opacity: 1;
}
#box a:focus {
    opacity: 1;
}

When using a mouse I will hover over the link element before using it. Since the :hover state propagates upwards #box will be fully opaque.

When using a keyboard I will focus the link element before using it. Since the :focus state does not propagate upwards #box will not be fully opaque.

like image 512
tobib Avatar asked Oct 22 '13 16:10

tobib


1 Answers

This can be done in JavaScript with focusin/focusout events (they are just like focus and blur except they bubble). Here is a fiddle.

It boils down to this function:

var deepFocus = function(element, cls) {
    cls = cls || 'deep-focus';

    element
        .on('focusin', function() {
            element.addClass(cls);
        })
        .on('focusout', function() {
            var value = !!element.find(':focus').length;
            element.toggleClass(cls, value);
        });
};

Update: There is a draft spec that contains the :focus-within selector which would exactly do what is required here.

like image 65
tobib Avatar answered Oct 21 '22 04:10

tobib