Build An Accessible Ratings Widget

This post originally appeared on the Yahoo! Accessibility blog.



Building accessible websites often means looking at how a widget functions and not what it looks like. We can always use CSS to change the look of a tool, but you can't always make the wrong elements work correctly.

Thierry Koblentz's article Developing an Accessible Star Ratings Widget for the Yahoo! Developer Network looks at the various rating widgets on the internet. He looks at how users can rate an article and the best way to display the aggregated rating.

example ratings for 1 to 5 starsrating example

This is how the ratings are displayed in the final version

Inaccessible solutions

Thierry found a wide variety of techniques for displaying ratings. Unfortunately, they fail one or more key accessibility tests.

You might think that most rating systems would be based on some markup proven to be semantic and "operational" across many User Agents — that is, that rating systems would be based on a specific set of HTML elements and attributes to which one applies behavior and style via JS and CSS. That would make sense, but it is far from the truth. When it comes to markup, authors try just about everything:

  • <a>
  • <img src="" >
  • <span>
  • <li>
  • <map>
  • <div>
  • <input>
  • and more…

Developing an Accessible Star Ratings Widget - Yahoo Developer Network

Display a rating with inline sprite


This image is used to display all rating values.

Instead, Thierry suggests using the TIP method with an inline sprite image. The CSS will determine what portion of the image is displayed.

Notice the image and text is included in a span. The span has a title for a tooltip and a class to determine the rating to display.

<span title="1 of 5" class="rating r1">
<img src="sprite.gif" width="0" height="1" alt=""/>1 out of 5
<span title="2 of 5" class="rating r2">
<img src="sprite.gif" width="0" height="1" alt=""/>2 out of 5
<span title="3 of 5" class="rating r3">
<img src="sprite.gif" width="0" height="1" alt=""/>3 out of 5
<span title="4 of 5" class="rating r4">
<img src="sprite.gif" width="0" height="1" alt=""/>4 out of 5
<span title="5 of 5" class="rating r5">
<img src="sprite.gif" width="0" height="1" alt=""/>5 out of 5

The CSS sets a width and height for the span using ems. This allows the rating to resize correctly. The image is positioned absolutely and sits on top of the text.

.rating {
position: relative;
height: 1.6em;
width: 8.1em;
overflow: hidden;
vertical-align: middle;
display: block;
.rating img {
position: absolute;
width: 40.5em;
height: 1.55em;
top: 0;
border: 1px solid #fff;
.r1 img { right: 0; }
.r2 img { left: -24.4em; }
.r3 img { left: -16.2em; }
.r4 img { left: -8.1em; }

Create an accessible rating form

Thierry also takes a similar approach to making the rating input form accessible. Sprite images are placed inside the labels for radio buttons and then CSS and JavaScript give the form the desired look and feel.

For this solution, we are using a smaller sprite than the one in the example above. It is now composed of two single stars (“on” and “off”).

We place img elements inside the labels. We assume they will have no value without CSS support, thus we "hide" them by setting specific dimensions via their width and height attributes. Note that using 0 with both attributes would show a broken image in some UAs... Note that with the above markup, we can expect (in most browsers) field selection via label selection.

Developing an Accessible Star Ratings Widget - Yahoo Developer Network

<form ...>
<label class="one" title="1 out of 5">
<input name="LandOf" value="1" checked="checked" type="radio">
1/5<img src="" alt="" height="0" width="0">
<label class="two" title="2 out of 5">
<input name="LandOf" value="2" type="radio">
2/5<img src="" alt="" height="0" width="0">
<label class="three" title="3 out of 5">
<input name="LandOf" value="3" type="radio">
3/5<img src="" alt="" height="0" width="0">
<label class="four" title="4 out of 5">
<input name="LandOf" value="4" type="radio">
4/5<img src="" alt="" height="0" width="0">
<label class="five" title="5 out of 5">
<input name="LandOf" value="5" type="radio">
5/5<img src="" alt="" height="0" width="0">

You can see the finished form on his demo page: Star Rating System

What you can do

When building a tool or widget consider the underlying function rather than the visual design. Tools that let users give feedback should use a form. Graphic representations of data should have images. There are times when we may want to change this rule, especially when we use progressive enhancement to remove a basic form interaction and replace it with a more complex JavaScript driven tool. However, keep in mind how this could affect the basic functionality and accessibility.

Visit the full article for complete information: Developing an Accessible Star Ratings Widget.