Forum Moderators: not2easy

Message Too Old, No Replies

Advanced Keyboard Selector

Works with :hover but not :focus?

         

JAB Creations

2:55 am on Feb 17, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The example code below works with with :hover but not :focus. I'm hoping someone can point out what I'm missing to get the keyboard to emulate the same behavior. Thanks!

- John

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>CSS Keyboard Advanced Selector</title>
<style type="text/css">
#widget1:hover #widget2 {
background-color: #ddd;
display: block;
}
#widget1 a:focus #widget2 {
background-color: #ddd;
display: block;
}
div.prompt {
display: none;
}
</style>
</head>

<body>

<div id="widget1"><a href="#" tabindex="1">Widget One</a>
<div class="prompt" id="widget2"><a href="#" tabindex="2">Widget Two</a>
</div>
</div>

</body>
</html>

JAB Creations

3:38 am on Feb 17, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



PS - I know only Gecko browsers (Firefox, SeaMonkey, etcetera...) support :focus so I actively know and acknowledge this point that will be made if I don't mention this. If it only works in Gecko browsers for now that is fine with me. Thanks.

- John

SuzyUK

3:49 pm on Feb 17, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi JAB

#widget1 a:focus #widget2 {
...
}

your selector is trying to target #widget2 as a descendant of the focussed link - however #widget2 is a sibling so you could try the sibling selector

#widget1 a:focus + #widget2

fwiw, I thought it might working using

:active
for IE7 too, it kind of does but there's a weird redraw clause needed - you need to hover over ANYTHING, another element, the browser chrome? when the link is active (focussed) to trigger the drop :o

Robin_reala

5:13 pm on Feb 17, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



That won’t actually work Suzy: #widget2 is a sibling of #widget1, not the <a> inside it. The only way John can do what he wants is to put a tabindex attribute on #widget1 itself, but that’s probably not great for accessibility.

[edited by: Robin_reala at 5:14 pm (utc) on Feb. 17, 2007]

SuzyUK

5:51 pm on Feb 17, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hey Robin.. I agree, I don't think it's going to do what John wants it to, I think he might then want to be able to tab to the second link and for it to stay in view, was waiting to see what he says about the first part (that selector was never going to work as it was)

The main thing being I suppose that

:hover
is applied to the whole of
div#widget1
therefore can affect/target all of its children but
:focus/:active
can only apply to an anchor so advanced selectors will have to come into play..

>>#widget2 is a sibling of #widget1, not the <a> inside it.
am I cracking up or are you? :o

Robin_reala

7:04 pm on Feb 17, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



OK, you’ve got me confused. Doesn’t:

#widget1 a:focus + #widget2

select siblings of the <a> which have an id of widget2? Seeing as the <a> has no siblings then that will always fail?

SuzyUK

8:52 pm on Feb 17, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Doesn’t:

#widget1 a:focus + #widget2

select siblings of the <a> which have an id of widget2?

Yes, as far as I can see that will select the first anchor's sibling (the keyboard tab focus?) which is #widget2 and by order of the cascade the anchor within.

#widget2 is a sibling of #widget1

isn't #widget2 is a child of #widget1?

John if you're still watching then please feel free to interject & discuss your code

[edited by: SuzyUK at 8:54 pm (utc) on Feb. 17, 2007]

Robin_reala

2:52 am on Feb 18, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



OK, I’m being an idiot and completely misreading the original code! Yes, Suzy’s selector will work then.

iamlost

5:18 pm on Feb 18, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



JAB Creations spends far too much time investigating the far limits and then enticing me out to play too.

SuzyUK is correct - her code (#widget1 a:focus + #widget2) change makes the OP code work.

However, it does not scale:


<div id="widget1"><a href="#" tabindex="1">Widget One</a>
<div class="prompt" id="widget2"><a href="#" tabindex="2">Widget Two</a>
<div class="prompt" id="widget3"><a href="#" tabindex="3">Widget Three</a>
<div class="prompt" id="widget4"><a href="#" tabindex="4">Widget Four</a>
</div>
</div>
</div>
</div>

The :hover scales up without problem. I have spent far too many hours not getting :focus to do the same. By all means please jump in and point out the simple solution so obvious that I am oblivious. Please.

SuzyUK

5:28 pm on Feb 18, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



hehe iamlost..

don't think there is a simple solution. It will not scale because you can't select parents of focused links and once the focus is off them they're gone

most solutions I've seen also use a bit of javascript although you can get it at least accessible without it

I think the key is *not* to use "display: none;" to hide the links as this makes them inaccessible by tabbing (or keyboard cycling) try it with Absolute Positioning off the screen and them bring them back on.

had an imperfect solution open but it's gone lemme see if I can find it again

SuzyUK

6:23 pm on Feb 18, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



k.. here's the imperfect solution in all it's glory - although it is guess work in regards the OP as I'm still not sure that this is the intention - it's what happens when we play with possibilities heh :)

a Javascript which applies the :focus/:active capability to any element is the key to the scalability I think, I did find one but it's not included here this is just the bare bones

This little snippet sort of works in IE7 too! The nested UL doesn't drop, but the individual links it contains do activate and are at least accessible, might play around with that a bit more

haven't built it up but am thinking it would have to be very width specific for both horizontal and vertical evolutions?

OH and it's in UL form because I find that easier more logical but anyway feel free to add/detract/play etc..

note

:active
is for IE7 it treats it like
:focus
- however one of the rules doesn't work it's noted in the CSS ;)


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>Untitled</title>
<style type="text/css" media="screen">
body {
font-family: arial, helvetica, serif;
}

ul {
padding: 0;
margin: 0;
list-style: none;
line-height: 1.6;
position: relative;
}

li a {
display: block;
width: 9em;
padding: 0 0.5em;
color: #000;
text-decoration: none;
}

li li a {color: #fff; background: #dad;}

li {
float: left;
width: 10em;
}

li ul {
position: absolute;
background: #dad;
width: 10em;
left: -1000em; /* using left instead of display to hide menus for accessibility */
}

li:hover {text-indent: 0;} /* IE hover bug needs a hover rule b4 it will apply an extended hover rule as below */
li:hover ul {left: 0;}

/* limited keyboard accessibility for no javascript */

li a:focus + ul,
li a:active + ul {left: 0;} /* not working in IE? see note */

li li a:focus,
li li a:active {
position: absolute; left: 1000em;} /* this brings it out of the ul which is still -1000em off the screen */
</style>
</head>
<body>
<ul><li><a href="#" tabindex="1">Widget One</a>
<ul>
<li id="widget2"><a href="#" tabindex="2">Widget Two</a></li>
<li id="widget3"><a href="#" tabindex="3">Widget Three</a></li>
<li id="widget4"><a href="#" tabindex="4">Widget Four</a></li>
</ul>
</li>
</ul>
</body>
</html>

Suzy

iamlost

8:18 pm on Feb 18, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month




/* limited keyboard accessibility for no javascript */

When javascript (or any clientside application) is a requirement rather than an enhancement I put the nice idea in the closet.

I did get :focus to scale using visibilty: [hidden¦visible]; in place of display: [none¦block]; but it is buggy: while it will tab up or down appropriately the intermediate links return invisible which is disconcerting. Also, of course, the 'invisible' space is obvious by it's placeholder blankness unlike display: none;.

For future personal reference:
* Do not read JAB Creations posts.
* If read, do not replicate, do not attempt solution, go straight to migrane, do not pass go.
* Take three days 'vacation' in a quiet padded room.
* Do not read JAB Creations posts...

JAB Creations

5:15 am on Feb 27, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The problem is not a rendering engine, a validator, but the standard itself. Why would the W3C allow keyboard events on a divisible element but not the tabindex attribute?

There are two solutions I suggest neither of which are pretty.

1.) Figure out how to create a modified version of XHTML 1.1 and rename it 1.2 (HTML 5 does not count).

2.) Cloaking: simply hide it from the validator but serve the tabindex attribute on the necessary divisible elements.

The W3C could remedy this keyboard inaccessibility one of two ways...

1.) Simply allow the tabindex attribute on any and all elements allowed to use keyboard events.

2.) Allow parent selectors in CSS3.

The more likely possibility would be that the W3C (might) choose the first step and simply add (validation) support for tabindex on all elements that are allowed keyboard events.

The reason being is that I've read there is a stubborn blockade against parent selectors in CSS. While it would be great for accessibility purposes I hear that...

1.) It would create an enormous complexity in browsers by forcing the rendering engines to rescan the entire page when A CSS parent selector is found.

2.) It has been argued that the 'C' CSS stands for Cascading and that [insert vague arguments I can't recall here].

Until I can figure out how the heck to modify and validate my own custom DTDs it looks like cloaking is the way to go temporarily. I did write about this error in the standard to the open discussion group but have not (to my knowledge) received a reply.

I suppose I should have interjected this information a few days ago but I have been working odd hours (for me).

I tend to attempt things in waves based on versions of my own site. With the target attribute improperly removed from XHTML along with this bug I think I will give customizing the XHTML 1.1 DTD a serious look in the 29th version.

I found bugs in rendering engines and thought I was good. Then I found bugs in validators and thought I was great. But now I'm finding bugs in standards and so I think it's time to review my hourly caffeine intake.

- John

Setek

5:30 am on Feb 27, 2007 (gmt 0)

10+ Year Member



The argument about cascading was you shouldn't be able to select parent selectors because cascading was intended to head deeper, cascade downwards, not back up.

Though I think it would be cool to be able to select parents :)

Then again, I'd just be happy if every browser supported (properly) all properties in CSS 1 and CSS 2.1.

I still drool after

nth-child
, but I can't realistically believe Microsoft will get around to fixing their bugs and supporting CSS 1, 2.1 and 3 for many years to come.