govuk-frontend
govuk-frontend copied to clipboard
[Spike] Investigate updating the accordion to use the `hidden="until-found"` attribute
What
Investigate whether we can update the accordion to use the hidden="until-found"
attribute, as originally raised by @injms in https://github.com/alphagov/govuk-design-system-backlog/issues/1#issuecomment-1127769827:
The
hidden="until-found"
attribute looks to be an interesting new feature that the accordion could benefit from in a backwards compatible manner:By adding hidden=until-found to the container for your hidden content, you make it possible for the browser to search text in that hidden region, and reveal the section if a match is found.
https://developer.chrome.com/blog/hidden-until-found/
Why
Using hidden="until-found"
makes it possible to search the hidden content within the accordion using the browser's in-page search feature (in browsers that support it).
At the time of writing, only very recent versions of Chromium-based browsers support the attribute.
According to Chrome Platform Status, Firefox consider it worth prototyping but there are no signals from Safari.
Chrome and Edge account for approximately 47% of visits to GOV.UK.
Assumptions
We should firm this section up before starting the spike.
- Despite the lack of clear signals from other browsers, this attribute will continue to be supported and is worth adopting.
Timebox
TBC
Who is working on this?
Spike lead: TBC
Spike buddy: TBC
Questions to answer
We should firm this up before starting the spike, but things we might want to look at include:
- behaviour in browsers that don't support the
hidden="until-found"
attribute - how using ‘content-visibility: hidden’ instead of ‘display: none’ (because of the use of the attribute) affects how the content appears in the accessibility tree (or hopefully doesn't appear when the accordion is closed)
- whether this change can be made without breaking changes to the component
Done when
- [ ] Questions have been answered or we have a clearer idea of how to get to our goal
- [ ] Findings have been reviewed and agreed with at least one other person
- [ ] Findings have been shared, e.g: via a write-up on the ticket, at a show & tell or team meeting
I've made a very mild spike into this, essentially changing the Accordion component JS to add and remove hidden="until-found"
on each sections content container (.govuk-accordion__section-content
) instead of using class toggles and CSS to do so.
My answers to the above appear to be:
- In browsers that don't support
hidden="until-found"
, the previoushidden
boolean functionality is used. The content has thedisplay: none
UA style applied, and the accordion works pretty much identically to the current production version. -
content-visibility: hidden
indeed removes the content from the accessibility tree in Chrome when collapsed, and reinstates it when expanded. It also results in a visual difference as (accurate to the name) it only collapses and hides the content—any other parts of the box model (margins, padding and borders) on the content container are not hidden. This currently results in a large amount of negative space in Chromium browsers. - We may need to counteract 2 by having each section's content wrapped in two containers—one that handles the show/hide function and another for styles. We could probably do this without a breaking change if we inject one of those containers, an approach which would make sense from a progessive enhancement perspective, as one of them is exclusive to JS functionality.
As a possible implementation caveat: In my experiment, the state of each section's content was no longer directly tied to the header. Using Chrome's find-in-page functionality only expanded the content container, causing the two to become desyncronised.
The beforematch
JS event can be used to find which container is going to be opened (as event.target
) and to manually sync the two, but this isn't something I tried in my experiments.
document.addEventListener('beforematch', (event) => console.log(event.target));
// => Logs element that matches when a search is ran
This only returns one element at a time, with the event potentially firing every time the user uses the next/previous result buttons or presses the Enter key.
Curiously/unexpectedly this event only fires if it's content within a hidden="until-found"
container. It doesn't fire for already visible text.