:active and activating via the keyboard
Spinning off from https://github.com/whatwg/html/issues/6635#issuecomment-1006097434 . Question: when does :active match? https://github.com/whatwg/html/pull/7465 takes care of some of the current interop problems, but isn't merged yet due to lack of tests; let's use https://whatpr.org/html/7465/semantics-other.html#selector-active as the working definition for this issue.
https://jsbin.com/cifugag/1/edit?html,output shows that the spec does not match either Firefox or Chrome:
-
Spec: pressing spacebar on the
<input type=radio>must not match:active, since it's not on the special list of elements for which "in a formal activation state" applies. Pressing spacebar on the<button>must match:active, since it is on that list. -
Firefox: pressing spacebar never causes any elements to match
:active. Only the "being actively pointed at" clause applies. -
Chrome: pressing spacebar causes both the
<input type=radio>and the<button>to match:active. It does not cause the<div>to match:active. Chrome appears to be applying the "in a formal activation state" definition to any element with activation behavior, which includes radio buttons but not divs. -
Safari: ???
I personally think the Chrome behavior makes the most sense (as it gives keyboard users and mouse users the same experience). The next step is to test Safari to see if that can give us any input.
The "normal a" link in https://output.jsbin.com/hujeguhivo throws a wrench into this ontology. Apparently keydown on the Enter key will navigate a link, and will not cause that link to match :active. So there's no "in a formal activation state" for <a> elements, really. Fun...
Ah, I was going to file an issue about this stuff because @dshin-moz and I were looking at some :has() interop-2023 failures, and found yours, @domenic :)
Other things that are funny about this:
- On WebKit and Blink,
:activeon buttons doesn't propagate the active state through the ancestor chain. test case - On WebKit and Blink, if you
preventDefault()the keyup event, the:activestate persists. test case - The timing at which the flag is set and cleared is not interoperable either, even on click. test case. @mfreed7 do you know when stuff is set / unset in Blink?
It'd be nice to get better spec text for how this is supposed to work... cc @smaug----
- The timing at which the flag is set and cleared is not interoperable either, even on click. test case. @mfreed7 do you know when stuff is set / unset in Blink?
The behavior of :active is definitely odd and could use some attention. I know Blink has several bugs in this area. The code is this one, calls to which are sprinkled everywhere.
A bunch of pointers to related things here:
- I dug into the code in Blink that does this activation (as part of investigating nested interactive content inside of
summary) and wrote up crbug.com/1361983 comment 5. (Also see related crbug.com/1469699.) I found that there are a bunch of elements where space and enter activation work differently. In Chrome the code for this exists in two different places (see the commit message in crrev.com/c/4673631). In Blink this applies tobutton,summary,permission(experimental), and some types (checkbox,radio, button types, temporal types with a chooser,color, andfile) ofinput. I also found equivalent code in Gecko that appears to make the same space/enter difference, although it doesn't lead to the samesummarybug, which makes me think at least parts of the difference in space/enter handling might not be possible to change for web compatibility reasons, although I could imagine making some incremental improvements. My initial reaction is that the space behavior is better for its:activebehavior (supported for space activation but not enter activation) and its handling of key repetition (don't repeat), and the enter behavior (in Blink, although Gecko has some solution for this) is better for its interaction with nested text inputs (don't activate the outer element for key presses in the inner one). (But composing with other types of nested content might have different pluses/minuses, and we may want a better solution to those problems... but it's also a space where changing the behavior could be difficult given compatibility constraints.) - I do like the idea of making
:activework for keyboard activation, and agree that it would make more sense if it works hierarchically like it does for the mouse. I'm not entirely sure how simultaneous keyboard and mouse activation should work but it feels like it might be possible for two different element hierarchies to be implemently:active(one from the keyboard and one from the mouse) although it might be hard to reach this state given focus behavior. - If we do standardize keyboard activation triggering
:active, we should be careful about what events start and end the active state, make sure the behavior when focus changes between key down and key up is correct, and hopefully get reasonable behavior for key repetition.
Hi @domenic,
Chrome, Firefox, and Safari now match :active when pressing the space key on <input type="radio"> and <input type="checkbox">.
Do you think it’s worth considering adding these two input types to the special list of elements for which “in a formal activation state” applies?
I did some testing regarding the keydown → keyup → click interaction:
https://github.com/w3c/aria-practices/issues/1229#issuecomment-3601957593
It seems like only Internet Explorer is bug free.