DEV Community

Cover image for Nearly Accessible* ANIMATED Accordion: in pure CSS??? No way! 😱

Nearly Accessible* ANIMATED Accordion: in pure CSS??? No way! 😱

GrahamTheDev on October 01, 2023

A few days ago I designed an accordion in 1 minute, 5 minutes and 10 minutes that was far more accessible than most! (perfect? not quite, but certa...
Collapse
 
thejase profile image
Jason Featheringham

Cool design! But I wouldn't consider this accessible without JS. Accessibility means giving everyone an equal experience, and showing and hiding lists without communicating that state to assistive tech users is not providing an equal experience. You could add JS to include ARIA states, but I don't recommend this.

Instead, please utilize the details/summary elements. They provide the accordion experience, but they are also accessible for assistive tech users.

Collapse
 
merri profile image
Vesa Piittinen

I would say please, remove the word "Accessible" from the title of this article. It is false advertising.

Collapse
 
grahamthedev profile image
GrahamTheDev

I consider this accessible, by the definition I use:

  • Does it pass all SC on WCAG 2.2
  • Can you access all the same information no matter what medium you are using to interact with the page (SR, eye gaze, keyboard, voice control).
  • Is the pattern easy to understand and familiar enough that people will be able to use it easily.

Those are my criteria for "accessible".

I made it very clear at the beginning of this article that there are better patterns, even linking to a better pattern in the very first sentence. But there is a valid edge case to use this pattern.

Thread Thread
 
merri profile image
Vesa Piittinen • Edited

Accessibility - or usability in general - isn't about meeting your criteria and definitions. It is about meeting the needs of others. It has to work for users and be understandable regardless how they experience it.

For some feedback:

It is annoying to use with a keyboard. You can't toggle the link again to hide the content. You can't open the accordion with a space bar which is a common expectation of an accordion.

It is hard to follow with a screen reader. Upon clicking a link you start hearing the target content but get no indication what this content relates to. Also, when going to a link you only hear that it is a link: no indication that it would open anything or if anything is open or closed.

On technical side this does not implement the accordion pattern.

I could be far less constructive about this, because I'm rather angry about what you have done here. I know that you wrote the code AND did not test it with a SR a single time. If you did you would have immediately caught a bug. You didn't even test it with multiple browsers! Is this really the level you want to suggest anything even as "edge case pattern"?

The fact is nobody should ever use this pattern. If JS is blocked you use details + summary. There is no reason to go for this. Nada.

Now, if you instead presented this as a technical exploration then I'd think this is cool. Because this is that: an attempt to push the boundaries, even if it falls short of being truly usable. That would be the right context and it would have given a good lesson for readers about the possiblities of CSS, and how and why it falls short.

Thread Thread
 
grahamthedev profile image
GrahamTheDev • Edited

Thank you for taking the time, it was really appreciated.

I agree with what you have said and have updated the the title a bit and added a large disclaimer.

The only part that I want to respond to is the screen reader part, I did test it there, but decided that the behaviour was expected when dealing with links and any attempt to fix that would only make things worse.

However, you have given me pause for thought on exposing some extra information to expose state. (I am thinking I can use some visually hidden text and have 2 links that I swap display: none on depending on state. Due to the behaviour of the links moving focus I do not think it will cause any issues, but I will test!)

I am happy to hold my hands up and say I failed here, but hopefully I can correct my mistakes. It is hard considering how long I have been at this to have missed so many obvious things (over exuberance combined with complacency on my part), but I hope you appreciate that I will work on improving them and will certainly be redoubling my efforts to not make such silly mistakes.

Thank you, once again, for taking the time, it is humbling sometimes when you miss some obvious stuff! πŸ™πŸΌπŸ’—

Thread Thread
 
merri profile image
Vesa Piittinen

Thank you for taking the feedback well! The bug you have is that you have hash # in id. That is why aria-labelledby points nowhere, and does not announce the text in the link.

However even with that fix it still is a bit odd to use due to lacking state. You need a toggle, open/closed state. So using :target for accordions is like trying to use screwdriver on a nail. And this boils down to the basics of links vs buttons: links are for navigation, buttons for interaction. This is why details is better: summary element is a button-like (it removes all semantics inside it just as buttons do).

I guess the "best" use case you can make :target work with is some kind of multiple step form where you use Previous and Next links to move around. Then you would be using links as they are intended to be used: to navigate around. You'd even get the benefit of scrolling the content visible.

Collapse
 
rouilj profile image
John P. Rouillard

Very nice. I like the implementation. Opening all accordions on print and allowing the user to open all accordions is very nice.

One thing to note is that Firefox had limited/incomplete support for :has(). So most of the examples don't work as expected under Firefox 8-(. Hopefully, they will get their act together someday.

I expect this will work for Safari and any Chromium based browsers.

Collapse
 
grahamthedev profile image
GrahamTheDev

Oh wow, I somehow missed :has not working. in FF

Thanks for that, I am sure I can rework it and do it the hard way so it still works in Firefox.

But first I need to go check some production code as I had marked :has as "safe for use" at my side πŸ˜±πŸ’—

Collapse
 
rouilj profile image
John P. Rouillard

Yeah, it's caused me some issues as well.

connect.mozilla.org/t5/ideas/when-...

seems to indicate that firefox nightly (119) has things working, but it may still be behind a flag. I have the flag enabled: layout.css.has-selector.enabled (IIUC) in about:config with FF 118.0.1.

Also in 2022, :has() was changed to an unforgiving selector. It used to be forgiving up til 2022 or so.

css-tricks.com/has-is-an-unforgivi...

so that might be an issue as well.

Thread Thread
 
grahamthedev profile image
GrahamTheDev

Yeah, that I was aware of, lucking I am only using one selector here within the :has so that certainly won't be an issue.

Grrrr, CSS support has always been the most annoying part of development lol! πŸ€£πŸ’—

Collapse
 
starkraving profile image
Mike Ritchie • Edited

This is a nice dive into the challenges you encountered making a pure-CSS accordion, thanks for the article! I've used :target before for a pure-CSS modal (before <dialog> was introduced) and the only thing I didn't like about it was that it appended your interactions to the browser history. It's a bit of a break in UX when users would likely expect to hit the back button to go to the previous page, and instead the screen just "rewinds" their interactions with the component. I think there is a need for at least some progressive enhancement here, to hook into the History API and replace the current URL instead of append it.

Collapse
 
grahamthedev profile image
GrahamTheDev

Yeah, overall I was over zealous and got too excited with this pattern.

I literally just updated the article to say "do not use" and I am actually going to add an additional bullet point under the "why not" part to account for the browser history part, as that is another valid observation.

Thank you. πŸ™πŸΌπŸ’—

Collapse
 
starkraving profile image
Mike Ritchie

Ahh, don’t be too hard on yourself, maybe it’s just a work in progress, so β€œdo not use yet”.

Collapse
 
rajaniraiyn profile image
Rajaniraiyn R

This could have much better if you use details and summary tags. those gives semantics and makes it more accessible with less CSS and functionality

Collapse
 
grahamthedev profile image
GrahamTheDev

Sadly you cannot do the animation part CSS only using details summary and that was what I was trying to achieve in the article.

In the first sentence of the article I link to an accordion using details and summary though if you want to check one out built properly.

Collapse
 
rajaniraiyn profile image
Rajaniraiyn R

Yes, we cannot do animations you done with details and summary tags but we can use some other animations on them. In most of the cases they will be enough.

Collapse
 
z2lai profile image
z2lai

Lifesaver! Hacks are always needed in the real world and this looks to be a great one. I have a bunch of form sections which I need to make collapsible like details/summary HTML element but I dont have access to the markup and I don't think I can use jquery to move each section into a details/summary element because it recreates the section but breaks all the event listeners. Will have to try a CSS only hack like this.

Collapse
 
crystalzenyth profile image
Crystal Scott

Accordion is not WCAG conformant and does not follow accessible best practices.
Accordion buttons are coded as links.
Missing toggling aria-expanded attributes.
Missing aria-controls attributes.
Tabindex has been inappropriately added to non-actionable elements.

Please change the name - it is misleading.

Collapse
 
cezarytomczyk profile image
Cezary Tomczyk

I'd use details and summary HTML elements to get most accessible code.

Collapse
 
grahamthedev profile image
GrahamTheDev

New dev? Experienced Dev? If you learned something in this article, please do let me know, I always love hearing when people stumble across something new, it makes writing the articles worth it! πŸ’ͺπŸΌπŸ’—

Collapse
 
kkm000 profile image
Cy "kkm" K'Nelson

I'm doing R&D and as far away from UI dev as likely possible, but I never miss a sweet article on the UI in the modern browser: A single .html file is a nice way to send an interactive presentation of your work. matplotlib has CVS output, which is also a plus, it can be embedded very nicely. And I'm simply a fan of aesthetic and functional UI. FWIW, this works is FF 119.0b4, with the flag layout.css.has-selector.enabled β€”Β probably, they aren't considering the has() support ready for prime time.

For nitpicking, a click on the only expanded opener arrow doesn't collapse itβ€”I'd expect that, so it's a violation of The Least Surprise Principle in design. Also, such a click causes the whole thing to readjust vertically, scrolling the page and content.

Collapse
 
lexiebkm profile image
Alexander B.K.

Seeing good use of the :has pseudo class, I am annoyed why Firefox does not support it. I also see Firefox does not support CSS Houdini such as Typed OM and defining/declaring custom properties.