The
<menu>
HTML element is a semantic alternative to <ul>
intended for interactive items.<menu>
HTML element is a semantic alternative to <ul>
intended for interactive items.A teenage boy works on his new Roblox game... Is this the beginning of a programming career?
I recently overheard a conversation between a Roblox Game Developer and some of his testers. As he demonstrated his game, he identified bugs, things that weren't actually bugs (features 😅), and characteristics of the environment.
What got my attention was his concern when he found a bug, relief when it wasn't a bug, and excitement about not only what he had already done, but also what he plans to do in the future... Just like me when I discover a new programming language, API, or framework.
Over the years, I've had the good fortune to participate in conversations with people working in every facet of the Software Engineering industry. Some of them would laugh me outta the room for even posing the question. They might say that you need logic, control flow, a well-documented API, or some other arbitrary and highly-opinionated features in order to be considered programming. I won't debate the point, but Roblox Game Development (along with Luau) might still qualify.
Programming gives me the opportunity to continuously learn, take what I've learned and make something new with it, break it, fix it, and share it with others before learning the next new thing. That's what I love about it. There's much less rinse & repeat than in other professions. That's what makes it awesome it seems to me that Roblox has this quality in spades.
I saw a post on Mastodon where the author, Marius Gundersen, used CSS to create a 0 to 5 star rating widget with an animated gradient and no JavaScript. It's really neat, but the code is hard to read and it's completely inaccessible.
There seems to be a growing sentiment within the Web Development community that JavaScript should be eliminated at all costs. Well, the cost is often accessibility. And accessibility is essential for all websites. Don't take my word for it, though. As detailed by Adrian Roselli, CSS-only Widgets Are Inaccessible and a key takeaway from Sara Soueidan's experience learning and teaching accessibility is that JavaScript is imperative for creating truly accessible custom interactive components.
I really liked the animated-star demo. I respect Marius for creating something I wouldn't have even thought of and I respect the anti-JS perspective even though I don't fully support it. But I wanted an accessible version. So, I decided to make my own:
This is all based on an unmodified fork I made of the original because people often fix or improve things right after sharing an initial version. Besides that, I'm kinda slow and I worried that it would change before I finished writing this 😅
In the original animated-star demo, the stars were formed by a large blob of encoded SVG code in a CSS background-image
and a different blob to define the clip-path
of the gradient. It's long, unnecessarily complex, and would be difficult to reproduce without copying and pasting. The stars are hard-coded to be exactly 24px
and changing that would require complex changes to both the SVG and clip-path
.
Although the stars are interactive components of the page, they aren't in the HTML at all. The HTML for the stars is just radio buttons that aren't even visible on the page. Combining :has()
with the squiggle selector (subsequent-sibling combinator) makes it look like more than one star is selected, but there's really only ever one radio button checked. It's really clever, but it means that assistive technology has no way to tell how many stars are selected.
The user can select between 0 and 5 stars, but the widget shows seven stars and the purpose of those extra two isn't immediately clear. The first one is rendered on a row by itself and doesn't do anything when it's clicked. For each selected star one fifth of this star is filled in. The second extra star is never filled in and clicking on it allows the user to select zero stars.
The other five stars would usually represent a rating. Clicking on an empty star selects it and those that precede it. The only way to deselect a star is to click on the star before it.
Assistive technologies such as screen readers work best if every visual component of the page is present in the HTML and has an accessible name. That's not as esoteric as it might seem. Properly written HTML has built-in accessible names. For example, radio buttons should have labels that give them accessible names.
When I test this page with a screen reader (NVDA), it just says "radio button not checked" 5 times and "radio button checked" once. It doesn't say anything about stars. In this context, that's totally fine. Marius was only doing a neat conic-gradient()
animation and it does that very well. I'm gonna steal that idea for my version, but I'm gonna focus on accessibility.
Each star in my demo is a toggle button. They're laid out with flexbox and sized with relative units so they can shrink and grow to match user preferences and the space provided. The star shapes themselves are inline SVG elements simple enough to reproduce by hand even with minimal SVG experience.
I use the same animation technique as Marius, but my gradient is applied to a pseudo-element. It can't be applied directly to the star because SVG doesn't support conic gradients and shapes don't have background
properties (they use fill
).
Like the original, the user can select between 0 and 5 stars, but there aren't any extra stars. To deselect a star, just click on it. Clicking a selected star that isn't on the end will deselect all the stars after it. The stars each have an offset transition-delay
so that they seem to be selected sequentially.
All of the stars are present in the HTML and visually hidden button text provides them with accessible names that identify them as "One Star", "Two Stars", and so on. There's also a live region that allows assistive technology to announce changes in the current rating.
When I test my version with a screen reader, it reads each of the stars, which ones are pressed, and the current rating.
If you're a hobbyist or enthusiast, either choice is really fine. They both look nice and work well. I think the CSS-only version might earn you a little more geek cred.
If you're a professional, though, there's no choice. Accessibility is legally mandated and that requires JavaScript. An inaccessible website could subject you or your employer to fines or lawsuits. Again, don't take my word for it. Just do a web search for "accessibility lawsuits".
If you do use JavaScript, you may as well take advantage of the additional capabilities; like I did with the offset transition-delay
. Just don't go overboard. Poorly implemented JavaScript can really ruin both the performance and accessibility of an otherwise excellent website. The key concepts are progressive enhancement and graceful degradation.