- From: James Craig <jcraig@apple.com>
- Date: Thu, 14 May 2009 16:03:16 -0700
- To: Henri Sivonen <hsivonen@iki.fi>
- Cc: Janina Sajka <janina@rednote.net>, CSS <www-style@w3.org>, W3C WAI Protocols & Formats <w3c-wai-pf@w3.org>
- Message-Id: <122B547B-B384-4EA1-811C-54C9568D173C@apple.com>
On May 14, 2009, at 5:48 AM, Henri Sivonen wrote: > On May 8, 2009, at 03:02, Janina Sajka wrote: > >> We ask that there be support for ARIA states and properties [1] as >> pseudoclasses. Many of these are similar to things that are >> currently supported as pseudoclasses, in that they can be set in >> multiple ways. For example, "checked" can be set from an HTML >> attribute, from aria-checked, or by user action. It is useful for >> a CSS author to be able to style all checked things the same, >> regardless of how they came to be checked. Ask whether the CSS WG >> thinks it's better to make that part of the selectors spec, part of >> the ARIA spec, or something else. Is there an extensibility >> mechanism for psudoclasses. > > Considering that all of ARIA state is in the attribute in the DOM > and, as a design principle, ARIA doesn't affect browser operation > except for the exposure of content to accessibility APIs, isn't it > sufficient and in accordance with the ARIA design principles to use > attribute selectors? For most purposes attribute selectors are sufficient, but attribute selectors get tricky in a few scenarios. Take @lang, for example. CSS provides a handy pseudo-class: q:lang(fr) { /* angle quotes */ } For non-nested instances of @lang (and ignoring @xml:lang), the following attribute selectors would be a sufficient equivalent of that pseudo-class. q[lang^="fr"], [lang^="fr"] q { /* angle quotes */ } But given a set of nested quotes, you may need to override the previous selector. <q lang="fr"> le foo <q lang="en"> the bar </q> </q> q[lang^="fr"], [lang^="fr"] q { /* angle quotes */ } q[lang^="en"], [lang^="en"] q { /* straight quotes */ } Which then wouldn't work for the opposite nesting (It would render straight quotes on French inside English), and you'd need to have as many overridden rules as you could have possible depth in the DOM, multiplied by the number of possible languages your web site supports [1]. Instead, the browser does all that work on the author's behalf, and simplifies it into the :lang pseudo-class. q:lang(fr) { /* angle quotes */ } With that example in mind, consider a menuitemcheckbox [2] that can be checked in a number of ways, and be nested in a series of menus, each of whose parent menu item may also be a menuitemcheckbox in a different "checked" state. The CSS attribute selectors would be extremely verbose. Note: shorthand example uses role as tagName (e.g. <menu> might actually be <ul role="menu">) <menubar> <menuitemcheckbox aria-checked="true"> <span class="check"></span> <menu> <menuitemcheckbox aria-checked="mixed"> <span class="check"></span> <menu> <menuitemcheckbox aria-checked="false"> <!-- this element may represent the visual checkmark in a GUI browser --> <span class="check"></span> </menuitemcheckbox> … </menu> </menuitemcheckbox> … </menu> </menuitemcheckbox> … </menubar> Assuming the checkmark was always going to be a direct child of the menuitemcheckbox, the selectors may be somewhat terse. [aria-checked="true"] > .check { /* checked icon */ } [aria-checked="false"] > .check { /* unchecked icon */ } [aria-checked="mixed"] > .check { /* partially checked icon */ } But a developer may want to figure out the checked state of an element no matter how deep it was nested inside the closest ancestor menuitemcheckbox. Even ignoring a host language equivalent of @aria- checked (like @checked) and given that the ancestors :checked states may be in any combination, you'd need CSS selectors at least as complex as: [aria-checked="true"] .check, [aria-checked] [aria-checked="true"] .check, [aria-checked] [aria-checked] [aria-checked="true"] .check { /* checked icon */ } [aria-checked="false"] .check, [aria-checked] [aria-checked="false"] .check, [aria-checked] [aria-checked] [aria-checked="false"] .check { /* unchecked icon */ } [aria-checked="mixed"] .check, [aria-checked] [aria-checked="mixed"] .check, [aria-checked] [aria-checked] [aria-checked="mixed"] .check { /* partially checked icon */ } In this case, the UA could/should probably do the work of walking up the DOM and determining the closest element that set the checked state. It'd be much better to be able to specify that type of ruleset as: .check:checked, .check:checked(true) { /* checked icon */ } .check:checked(false) { /* unchecked icon */ } .check:checked(mixed) { /* partially checked icon */ } Of course there isn't a need for pseudo-class replacements of all ARIA attributes, but there are several places where it may make sense and should be considered. 'checked' and 'selected' are probably good examples. 'required' and 'invalid' may also be worthwhile. There are even some special implicit value cases, such as 'aria-haspopup' [3] which is false by default but has an implicit value of true if left unspecified on an element with the role 'combobox' [4]. Footnotes: 1. Non-Engligh quotation marks: http://en.wikipedia.org/wiki/Quotation_mark,_non-English_usage 2. 'menuitemcheckbox' role: http://www.w3.org/TR/wai-aria/#menuitemcheckbox 3. 'aria-haspopup' property: http://www.w3.org/TR/wai-aria/#aria-haspopup 4. 'combobox' role: http://www.w3.org/TR/wai-aria/#combobox
Received on Thursday, 14 May 2009 23:03:58 UTC