Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way to show drop down on focus with CSS

Tags:

html

css

I'm trying to make a keyboard accessible menu but I can't figure out how to get it to show the the drop down on focus.

I have

.main-menu li:hover ul,
.main-menu li:focus ul {
    display: block;
}

The issue is that when its focusing its focusing on the a that's nested in the li and not showing the ul. Tabbing is focusing on the a tags.

Here is my full code: http://jsfiddle.net/bxpe4/

like image 814
kel Avatar asked Sep 19 '13 19:09

kel


2 Answers

Another property that may be of use here is :focus-within. So if you do something like below, it should also work.

.main-menu li:hover ul,
.main-menu li:focus-within ul {
    display: block;
}

The focus-within psuedo-class not only cares about the current element but all of its children as well. I think its a pretty clean solution to this problem and it worked for my issue.

like image 57
Jon Black Avatar answered Oct 20 '22 00:10

Jon Black


When tabbing, you focus the anchor inside .main-menu li, not the list-item itself.

There are two workarounds:

a) using + selector

.main-menu li a:focus + ul {
    display: block;
}

However, that makes it problematic to tab to other anchors (on tabs press, it should go to the first anchor in submenu, but it gets undisplayed, so nothing happens).

b) using tabindex property

That would require you to set tabindex on menu anchors to negative value (remove them from tabbing) and set tabbing to list-items.

see Using tabindex demo

You would need to change the styling of anchors and list-items to show the red background too, adding a new selector:

.main-menu li a:hover,
.main-menu li a:focus,
.main-menu li.dropped > a,
.main-menu li:focus > a /* this one was added */ {
    /* your styles */
}

This however, is not really a good practice as focused list-items mean, that you can't access the anchor using keyboard. You could use JavaScript to simulate the event (bind keypress of the list-item to click on the anchor), in jQuery it would be something like this:

$('li[tabindex]').on('keypress', function() {
    $(this).find('a').click();
});

see Using tabindex with event simulation demo

This is not an issue if the top-level anchors don't have any action (are only used for drop down purpouses), in which case you wouldn't need them at all.

like image 21
Jakub Michálek Avatar answered Oct 20 '22 00:10

Jakub Michálek