Problem/Motivation
The CSS :focus-within
pseudo-class looks very handy, but we don't use it in core yet. It's particularly useful as a way to achieve better parity between mouse and keyboard interaction, by pairing :hover
with :focus-within
styles for container elements.
It has good support, but will need a polyfill for some of the browsers we support, in particular Internet Explorer (the forthcoming Chromium-based Edge supports it).
- Several polyfills are available. Most of these work by programmatically adding an atttribute to all ancestors of the element which matches
:focus
. - Stylesheets need extra selectors to target the polyfill's attribute, but there are utilities for SASS/Post-CSS to manage this.
- Modernizr has a test for
:focus-within
support, since version 3.6.0. Core currently has version 3.3.1, but an update is coming in #3042182: Update core JavaScript libraries before 8.9.0/9.0.0.
Examples where :focus-within could help
- Highlighting table rows. The Seven theme already has this style rule in
tables.css
, and Claro has something similar:tbody tr:hover, tbody tr:focus { background: #f7fcff; }
Mouse users get a highlight on the row currently being hovered over, which is a useful aid to reading, comprehension, and hitting the correct checkboxes and drop-buttons. The
tr:focus
is intended to provide an equivalent effect for keyboard users too; but it fails because table rows aren't normally focusable, so the selector never matches. What's really needed here istr:focus-within
. - Media library truncates long names, but expands them when a keyboard user tabs to a media item, so they can read the whole name. Currently JS events are used to manage a class on a container element, but this could be simplified by a
:focus-within
approach.// Adds is-focus class to the click-to-select element. .on('focus blur', ({ currentTarget, type }) => { $(currentTarget) .closest('.js-click-to-select') .toggleClass('is-focus', type === 'focus'); });
.media-library-item--grid.is-focus .media-library-item__name { white-space: normal; }
- Highlighting the label and description associated with a form input. For example a coloured background on
div.form-item:focus-within
. (The input itself would still use a:focus
style.) - Highlighting a group of related controls, e.g. date/time, shipping address. Use
:focus
to style the current control, and style the containing fieldset with:focus-within
Proposed resolution
- Add a focus-within polyfill to core, make it available as a core library which CSS libraries can depend on.
- Optionally load it via modernizr?
- Follow-up issue: change
tr:focus
totr:focus-within
in Seven's table style. - Follow-up issue: change
tr:focus
totr:focus-within
in Claro's table style.
Remaining tasks
Decide which focus-within polyfill to use. What criteria to evaluate this?
Change record.