Re: [csswg-drafts] Make things focusable in CSS (#3379)

---

Migrated from https://github.com/WICG/spatial-navigation/issues/25#issuecomment-375933065
Originally created by @bradkemper on *Sat, 24 Mar 2018 23:40:48 GMT*

---
## Brad’s Screed about Interactivity Being Part of CSS
So, I’d like to say that I am a big fan of separating content from presentation. But a certain amount of interactivity is part of the presentation that the Web designer has to consider when designing.  We should embrace that, and not be too hesitant about adding features to CSS that make it easy to add even more interactive control to the Web. 

When designing and creating a menu bar, for example, one has to design and create the different states its menus can be in. The easiest and most powerful way is declaratively, using CSS selectors and rules. So, for instance, this is easy:

```
.menubar > button:not(:hover) ~ .menu { display: none }
```

It could be argued that this is more about interactivity than presentation. The `display: none` is not really there to style anything. It, and the selector for this rule, exists entirely to make the menu interactive. In fact, I think it is likely that `display:none` is used more for interactive behavior than for anything that could be strictly described as stylistic.  It is often used in conjunction with `:hover` and `:focus`, which are *only* about interactivity, or with class names added via JavaScript that are *only* there to show or hide something, not to style it. 

But thank God. If these all only existed in JavaScript, and not CSS, life for authors would be far worse off. 

Note that `display: none` also prevents focusing it or its descendants. That’s a side effect now, but an important one that is lacking in, say, `opacity:0`  or `position: absolute; left:-100vw` . I want better control of that as a primary effect, without having to hide the element, and without having to resort to JavaScript (other than maybe using JavaScript to add or remove a class, sometimes). 

Note that we have a `pointer-events` property that can enable or disable the *clickability* of an element in CSS. Why not a property that can similarly enable or disable the focusability of an element, or set the level of focusability? Bring it on, I say. 

These aren’t the only examples of CSS being used more for interactivity than for static styling of how it looks:

* The `resize` property  lets an element become resizable by the user, and there is not even any author control of what that resizing widget looks like or where it is placed. It is purely about enabling interactive behavior. 
* The `will-change` property is more about performance optimizations than about visual style. 
* `overflow:auto|scroll|clip` is primarily about enabling or disabling interactivity of user scrolling. It is much more about interacting with the content than of visually styling it. 
* `user-select` is another behavior-altering property that doesn’t actually change visual style. It enables and disables the ability to select text or other elements on the page. Conceptually, it isn’t so different from my proposed property to enable and disable the ability to focus an element on the page. 
* `user-modify`, while not on a standards track, is supported by Safari, Chrome, and Edge. It is similar to the`contenteditable` html attribute, but somewhat easier to apply declaratively, because: selectors and the cascade.  A `read-write` value does make an element focusable, but it also, you know, makes it writable. And it can’t be used to turn off focusability of things like anchors or text inputs. 
---
Currently, supporting keyboard access by following ARIA recommendations for various component-like HTML constructions is not easy. It involves updating attributes, such as tabindex, on multiple elements at the same time, every time a key is pressed or focus is changed with that construction, based on event handlers that have to be added to those elements. These types of constant DOM updating can cause layout thrashing. It is also easy to sometimes end up with the wrong elements focusable/un-focusable, due to some tricky situations that the author’s code might not account for correctly, such as when the user clicks into another window and the blur event doesn’t have a relatedTarget, then the user clicks back in onto something else that takes the focus. 

Also, when arrowing through a component-like thing, you want it to either stop when it gets to the beginning or end, or to wrap around to focus the last or first focusable part. So, a CSS focus-containment property that could be set on a parent or ancestor  would make that a lot easier. This would be especially true if the user is using VoiceOver-keys or other means to advance the AT-focus to the next-previous element. In that case, there is no way to detect in JavaScript when the user has left the component, unless/until they advance to something that actually triggers a blur or focus event (using VoiceOver to advance to a paragraph that is non-focusable does not trigger any detectable events, AFAICT).  But a focus-containment property could potentially contain that kind of pseudo-focusing too, replicating the way VoiceOver stops advancing when it gets to the last OPTION in a SELECT. 

-- 
GitHub Notification of comment by frivoal
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/3379#issuecomment-443617800 using your GitHub account

Received on Monday, 3 December 2018 07:47:48 UTC