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...
For further actions, you may consider blocking this person and/or reporting abuse
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.
I would say please, remove the word "Accessible" from the title of this article. It is false advertising.
I consider this accessible, by the definition I use:
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.
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.
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! ππΌπ
Thank you for taking the feedback well! The bug you have is that you have hash
#
in id. That is whyaria-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.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.
Oh wow, I somehow missed
:has
not working. in FFThanks 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 π±π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) inabout: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.
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! π€£π
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.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. ππΌπ
Ahh, donβt be too hard on yourself, maybe itβs just a work in progress, so βdo not use yetβ.
This could have much better if you use
details
andsummary
tags. those gives semantics and makes it more accessible with less CSS and functionalitySadly 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.
Yes, we cannot do animations you done with
details
andsummary
tags but we can use some other animations on them. In most of the cases they will be enough.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.
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.
I'd use
details
andsummary
HTML elements to get most accessible code.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! πͺπΌπ
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.
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.