DEV Community

Cover image for 5 star rating system - ACTUALLY accessible, no JS, no WAI-ARIA and Semantic HTML! ⭐⭐⭐⭐⭐ [Easily converted to any framework too!]

5 star rating system - ACTUALLY accessible, no JS, no WAI-ARIA and Semantic HTML! ⭐⭐⭐⭐⭐ [Easily converted to any framework too!]

GrahamTheDev on July 02, 2021

In this article I will explain how I built a star rating system that is ACTUALLY accessible, easy to style for your own needs and easy to integrate...
Collapse
 
anevins12 profile image
Andrew Nevins

I support the idea of the need for an accessible rating system, but I don't believe this is a final product. It's not "accessible" if it fails other user groups and it's worth running through the criteria on WCAG 2.1. For instance, the chosen ratings are only distinguishable through color (1.4.1) and there are no visible labels (3.3.2.)

Collapse
 
grahamthedev profile image
GrahamTheDev

I think it works and would pass WCAG AAA, but I am always open to a discussion on stuff!

I think you may have misunderstood "distinguishable by colour", an empty star with an outline vs a filled star with no outline vs a filled star with an outline is visually different even with Achromatopsia (complete colour blindness). It could be black and white and still perfectly obvious which stars are filled and which are empty due to side differences and fill differences. Where it would fail is if I used a red star initially and then turned them green when selected, then there is no visual difference, only a colour difference.

Also the stars have a visible label in that they are in a fieldset with a legend, which labels the controls purpose, and for knowing what is selected: visually the number of ratings is easily determined by the number of filled stars.

However you could address both quite easily by updating the legend with the current rating in brackets (Your rating (current: 0 out of 10): ) and provide additional instructions via aria-labelledby or aria-describedby if you believe that a star rating pattern is not a recognised and understood pattern in your Country or within a community (as that would be the biggest problem, unfamiliarity with a star rating system would make this hard to understand).

I would say this passes the 99% rule - 99% of people will both understand and be able to use the control as nothing is "perfect" when it comes to accessibility (for example this may not be the best design for eye-gaze technology if the stars are smaller).

I would pass it on a VPAT, but as always I am more than willing to make improvements if you have any suggestions, as I love when people blow my mind with something I hadn't considered or a novel idea! 💪❤

Collapse
 
anevins12 profile image
Andrew Nevins • Edited

Good point on the border for 1.4.1, I hadn't noticed the subtle border change between chosen and other star shapes.

You are mistaken on 3.3.2 Labels or instructions when you mention programmatic structure, accessible names, or accessible descriptions. This criterion is not intended for screen readers.

Look man, I'm on your side, but it peeves me that you mentioned it is accessible and do not take feedback.

Edit: I would caution you about using the words that it works for the majority of users, as people with disabilities will always be a minority group.

Thread Thread
 
grahamthedev profile image
GrahamTheDev • Edited

Yes you are correct, I had the wrong rule in mind, however the principle is the same.

If it was deemed that the stars themselves do not provide a clear enough indication of behaviour then a set of instructions which explains the usage of the control would be beneficial. These would be linked using aria, but I did indeed look at it from the wrong perspective, they need to be visible instructions.

The argument I was making (not well evidently) is that a star rating system is a widely used and understood UI pattern and the "labels" for each of the options are the stars themselves, so this is not a necessary step. However that would certainly be a great "belts and braces" accessibility improvement to add instructions for usage!

You could improve this further by adding a visible label under each star to denote the number, but then you have to consider whether that adds confusion when it shows all possible star rating numbers (as you are still relying on the stars themselves to convey the number selected), i.e. if we have 5 stars and 3 are selected, a visible label under each of the stars could cause confusion as it says "1 star, 2 star, 3 star, 4 star, 5 star".

As for taking feedback...I also said I am willing to listen and welcome any suggestions to improve it in the last paragraph, at the moment you are only giving me potential problems (which isn't useful feedback I can action as I do not agree (yet)...but I may be misunderstanding the point you are trying to make). Points that I would argue are covered. I will always improve my solution if there is a better alternative and really would like to hear what you think would make it better.

Perhaps the alternative is simply to not use a star rating system at all, but I am still quite confident in saying this is an accessible (as far as is possible with current technology) star rating widget...the argument for whether star rating widgets themselves are accessible is an interesting one though.

And the majority wording yet again I was very careful with - nothing is 100% accessible, so the 99% rule is the best we can do.

Finally I want to be clear, I am not ignoring you, neither am I not listening, I welcome feedback like this as it helps me learn and grow, I am just not understanding where you think this pattern can be improved. Please do continue to elaborate on where you think improvements can be made and I will action them once I understand the benefit / improvement!

Collapse
 
link2twenty profile image
Andrew Bone

Are... Are you using SVGs?! I'm telling @afif ...

Collapse
 
afif profile image
Temani Afif

He made the effort to integrate it inside the CSS so I will forgive him this time ... but the real issue is the ton of HTML used here ... more than what I used for my loaders 😩

Collapse
 
grahamthedev profile image
GrahamTheDev

Throw accessibility out the window and I am sure you could do a single div star rating system. I couldn't but I am sure you could 😋

Thread Thread
 
afif profile image
Temani Afif

I already did it here: dev.to/afif/another-100-css-loader... I simply need to add the inputs and it will be interactive. Maybe I will write a post about 🤔

Thread Thread
 
grahamthedev profile image
GrahamTheDev • Edited

For the love of God...noooooo, I promise I will be good and not use SVG in my next post!

If you do it people won't read any warnings you put on that it is just for fun and just copy paste it. Then I will have to republish this post every week to undo the damage (especially as lots more people read your stuff than mine, so I would need to work twice as hard 😋)!

I mean it is that bad that somebody literally just posted an article with a star rating system using <li> that isn't accessible (not even joking!) so I have an uphill battle as it is 😋🤣

(only kidding BTW, go for it if you have the time as I may be able to simplify my CSS from the tricks you use!)

Thread Thread
 
lakbychance profile image
Lakshya Thakur • Edited

Hey I am that person who posted about <li> star rating system and yes its fully JS based and is a really amateur implementation with regards to css and accessibility. I will surely re-read this blog again and again to understand things in better depth and maybe go ahead with building an accessible component. I actually wanted someone to comment about how my implementation lacks accessibility so I could get tips. I am glad you made this blog :D.

Thread Thread
 
grahamthedev profile image
GrahamTheDev • Edited

Wasn’t meant to be a dig by the way (well not a mean dig, just a playful one!😜), Temani and I have good banter that is all and your timing was just too good releasing that post!

If you want I can have a look at your post and offer some suggestions on how you could make it accessible and keep you current design (or close to it).

Or better yet why not take the principles from this design and Use the revealing-module-pattern to turn into a component, more than happy to link to it / include your fiddle in this post if you do and happy to help if you need any guidance from an accessibility perspective! ❤️

Thread Thread
 
lakbychance profile image
Lakshya Thakur

I will try to understand the principles of your design first. And surely leave a comment for any help needed to understand accessibility. I am trying to learn it by reading blogs from web.dev and other online content. Let's see if I get a chance to make a revamped accessible one using same pattern :D.

Thread Thread
 
grahamthedev profile image
GrahamTheDev • Edited

The key principle is using radio buttons with properly associated labels from an accessibility perspective (that are within a fieldset to group them). That covers 80% of the accessibility!

Once you have that as a base the only other thing that is a bit unusual is the way I hide the inputs (and the label text) so that is the key thing to investigate. If you search google for “screen reader only text” or “visually hidden text” the first articles should explain that technique in detail. this article explains the principles reasonably well to get you started

Once you have had a fiddle and poke around then let me know if anything still doesn’t make sense!

Collapse
 
grahamthedev profile image
GrahamTheDev

Don't cause him undue harm, he might have missed that I use SVG and now he might notice and cry.

Then he might look at my CSS skills and cry some more.

Then in a fit of rage he will create the same item with one CSS selector and some CSS voodoo just to feel better. I don't want him to have to do that just to get through the day, I am sure he is busy! 😋🤣

Collapse
 
link2twenty profile image
Andrew Bone

Just noticed a problem on @afif 's version so came here to see if you have the same problem, and you do, but @madsstoumann doesn't 😲

Using the radio buttons the up and down arrow keys are inversed. Up makes the rating go down and vice versa.

Because Mads is using a range element it behaves as expected.

Collapse
 
grahamthedev profile image
GrahamTheDev

It is expected behaviour though as you are cycling through a list of radio controls. If you inline radio inputs the behaviour is the same.

To be fair if user testing said it was an issue then our old friend JS can rescue us 😀

Collapse
 
mindplay profile image
Rasmus Schultz

Very cool!

Didn't work quite correctly with touch on a mobile phone though. Look here what happens if you tap and drag over the control, trying to scroll the page - it gets into some very weird states.

dev-to-uploads.s3.amazonaws.com/up...

Collapse
 
grahamthedev profile image
GrahamTheDev

If you click elsewhere it would be fine, the red stars are for hover state and so you activated that.

I don’t think I ever saw someone drag on a star rating before but if you expect it to happen we can use media queries to fix it easily

Collapse
 
mindplay profile image
Rasmus Schultz

People will put their finger anywhere in the screen to scroll, because this does not normally translate to interactions with controls. I can put my finger on the submit-button in this comment form and scroll the page. This is fundamental to how touch interactions are expected to work, so it's going to look like a bug when it happens. Most internet devices are touch devices, so keeping things touch friendly is important when we design custom controls. 🙂

Collapse
 
mikemai2awesome profile image
Mike Mai

I love your intro. It is so true for a lot of devs to copy paste solutions without understanding them (everyone is guilty, my young self included). The problem is that the outdated posts have such high search talking, search engines really need to build something in their algorithm to counter that.

Collapse
 
grahamthedev profile image
GrahamTheDev • Edited

The impossible task until true AI exists, find the best resource but then strip it from the internet when it is out of date while still having loads of shares!

I will keep carving away at the problem a few thousand views at a time until our AI overlords are born!

Collapse
 
magikmaker profile image
Bjørn

Interesting, I created something very similar about 3 years ago:
bjorn.wikkeling.com/199/pure-css-s...

It also only uses HTML and CSS for the stars, no SVG but just plain and simple UTF-8 stars. JS is only used for posting the values to an API.

Collapse
 
grahamthedev profile image
GrahamTheDev

There is a star rating war on and this is useful information.

I like the simplicity so I am going to see if I can take some of this idea and use it! Nicely done! ❤

Collapse
 
mvoloskov profile image
Miloslav 🏳️‍🌈 🦋 Voloskov

Very good, but my screenreader just tells me “3 of 5”, “4 of 5” and so on. Wouldn't it be nicer to make it tell “Rating: 4 out of 5”? It should be easily achievable.

Nice work though! If it can be done without ARIA, it should, because otherwise my colleagues tend to make two conceptually different versions: one for so-called “normal” users and another for “not normal” ones 🤦 it's just like all those “mobile versions” over a proper responsive design. Core principle of a11y goes out the window.

Collapse
 
grahamthedev profile image
GrahamTheDev

It would be expected that when you enter the control it is announced as rating and then just the numbers as you change.

You can change it to read as you want by changing the labels to include the text or by using `aria-label=“IDofLegend IDofLabel” and giving them IDs...but I wouldn’t do that unless user testing said it was an issue (and as it is currently expected behaviour I wouldn’t suggest it).

Screen readers can reannounce the current control if needed.

Collapse
 
barelyhuman profile image
Reaper

That’s nice!

Collapse
 
grahamthedev profile image
GrahamTheDev

Thanks Reaper, (great name by the way), I hope you find a use for it in the future!

Collapse
 
barelyhuman profile image
Reaper

I’ll use it for sure

Collapse
 
blackjyn profile image
ZVHR El Ekhsaan

Nice.
In today's web development "DIET" is the whole key

Collapse
 
grahamthedev profile image
GrahamTheDev

Not familiar with the acronym “DIET”, or did I miss a joke...either way can you explain and educate me 😜🤣

Collapse
 
blackjyn profile image
ZVHR El Ekhsaan

It is a satire.
many developers are using complicated-big sized library/frameworks for things that native HTML/CSS/JS solutions are available.

Collapse
 
afif profile image
Temani Afif • Edited

#webdev would be better than #codepen (there is no codepen in your post)

Collapse
 
grahamthedev profile image
GrahamTheDev • Edited

done

Collapse
 
zaxwebs profile image
Zack Webster

This is pretty neat.

Collapse
 
grahamthedev profile image
GrahamTheDev

Thanks Zack, it was the best approach I could come up with, that doesn't mean there isn't a cleaner way to achieve the same though 😋

Collapse
 
vikkrantxx7 profile image
Vikrant Sharma

Nice article.. for the last point though you could have used event delegation 🤔.

Collapse
 
grahamthedev profile image
GrahamTheDev

There are a hundred ways to tap into it, essentially I was just showing that all it is is a radio group and so you can attach it in any way to your application simply by accessing the :checked value on the group.

Same principle applies for displaying them, you can just set the checked value with JS.

I perhaps should have come up with a better JS example, it was just something I threw in after I wrote the article as I know some people get put off when they see a CSS and HTML only component thinking they can't use it with a framework / access the value with JS on the front end.

Collapse
 
grahamthedev profile image
GrahamTheDev

If there is anything I haven't explained well then please let me know! I hope some of you get to use this in your own projects (and if you do let me know in the comments!)