• Home
  • Quick Start
    • Configurator
    • Download YUI 3
  • Documentation
    • User Guides
    • Examples
    • Tutorials
    • API Docs
  • Community
    • Gallery
    • Blog
    • Forums
    • YUI Theater
    • Calendar
  • Contribute
    • YUI on GitHub »
    • File a Ticket
    • View Tickets
    • Dashboard
  • Other Projects
    • YUI 2
    • YUI Compressor
    • YUI Doc »
    • YUI Builder
    • YUI PHP Loader
    • YUI Test
    • YUI Website
  • YUI
  • Blog
  • Accessibility

Blog: Category ‘Accessibility’

« Older Entries

Making Search Direct Accessible

A few months ago we launched the first beta release of Search Direct. This new product explores the concept of real-time feedback, instantly delivering answers to the user with each keystroke. Given the diversity of Yahoo!’s audience, we wanted to make Search Direct as accessible as possible. Initially, we believed that this would be an easy task since this product would be based on YUI 3, a JavaScript library with accessibility baked into its DNA. Contrary to my expectations as an engineer, this task turned out to be more difficult than we anticipated.

Introducing Search Direct

Although Search Direct is built from the ground up using YUI’s component infrastructure, its most visibly prominent interface is based on the YUI AutoComplete widget which includes many accessibility features right out of the box. Suggestions related to a particular query are displayed in this autocomplete implementation. Search Direct also features a content panel, a.k.a. the rich panel, where suggestion-related content is displayed. The intention of the rich panel is to provide a direct answer to the user when a suggestion from the autocomplete list is selected.

Search Direct Screenshot - Query: jen, Soft-selection: Jennifer Aniston

A new set of suggestions is displayed in the list on every keystroke, and the first suggestion is selected by default. This default selection is called a soft selection. Soft selections and subsequent interactions with the suggestion list dictate the content that is rendered into the rich panel. In reality, things are a bit more complicated (performance optimizations, additional cache layers, etc), but for the sake of simplicity we can assume that this is the common workflow.

Accessibility features

In the quest for making Search Direct accessible, we looked at the implementation of Search Assistant, a technology that Yahoo! pioneered a few years back, as well as the native accessibility features of YUI.

After this investigation, three primary accessibility features were proposed for Search Direct:

  • Using the YUI Internationalization utility to serve localized content.
  • Setting role and aria-* attributes on elements within the autocomplete widget, that need to be identified and processed by screen readers.
  • Using a hidden div that represents a live region (aria-live) to notify the user when something happens. E.g., the number of available suggestions, the selected suggestion, etc.

The plan was to notify the user of any changes in the Search Direct interface, and provide a set of keyboard shortcuts to navigate the following visual components:

  • Searchbox
  • Submit button
  • Suggestion list
  • Rich panel

Sounds like a breeze, right? Well, let’s take a step back.

The problem

What we have here are two asynchronous processes — one of them for updating the suggestion set and the other one for retrieving corresponding answers — and they’re both really fast. We’re talking about 250ms end to end. Since the interface is changing at such a rapid pace, keeping track of everything can be difficult for a screen reader user. It gets an order of magnitude more complicated when updates happen in an asynchronous, near real-time manner. Because the screen reader was being notified of every change in the interface, the resulting chatter made it difficult to make sense of what was going on.

Lacking an acceptable solution, we started collaborating with Yahoo!’s resident accessibility guru, Victor Tsaran (@vick08) to try and come up with something better.

The first time we watched Victor interact with Search Direct, it was immediately clear to me that a majority of his focus was on the rich panel instead of the suggestion list. This was a surprise for me, as we viewed the list as the “source of truth”. During one of our sessions, we had a stroke of luck when we happened to disable all the accessibility features of the list. As soon as the noise introduced by the list was cut out, Search Direct started to make sense to Victor!

How users of screen readers perceive Search Direct

After realizing that we were trying to solve the wrong problem, we went back to the original user story: “As a user, I can get an answer as I type”. Getting the answer across to the user was the priority. After redefining the problem, we concentrated our accessibility efforts on an implementation where the screen reader prioritized the rich panel content over the suggestion list.

For example, if the user types "miami wea", the screen reader will tell them two things:

  • 10 suggestions.
  • WEATHER MIAMI, FL. TODAY, Scattered Thunderstorms, 89°F 77°F. TOMORROW, Isolated Thunderstorms, 90°F 74°F…

It will then continue reading out the rest of the rich panel content. The user doesn’t need to know all 10 suggestions up front, every time the list updates. If they do want to know, the information is readily accessible via keyboard navigation.

To ensure that the suggestion list is adding value to the experience, we make sure that the first phrase in the rich panel is closely related to its corresponding suggestion. For instance, based on the previous example, "weather miami" is the first phrase in the rich panel for the suggestion: “miami weather”.

Victor Tsaran, of the Yahoo! Accessibility Lab, shows how it works on FireFox with the NVDA screen reader:

The screen reader experience for our application is easier to follow since we now only focus on the following two visual components:

  • Searchbox
  • Rich panel

Changes to the autocomplete list as a whole are no longer tracked, and the submit button is ignored since the user can always hit enter for the current query or use a keyboard shortcut (tilda access key: [control, alt or shift] + ~) to switch between the input element and the rich panel. These keyboard navigation options are revealed to the user when the searchbox is acknowledged by the screen reader.

From an engineering perspective, this change greatly simplified things. The amount of DOM manipulation in the most active component was drastically reduced, improving the overall performance of Search Direct. Here is an example of the implementation:

function SDAAria () {
    var node = this._liveRegion = Y.Node.create('<div role="status" class="off-screen" aria-live="assertive"></div>');
    // Create the ARIA live region...
    Y.one('body').append(node);
    // listening for aria:live messages to update the live region
    this.on('aria:live', this._handlerMsg, this);
    // listening for gossip:refresh to announce how many suggestions
    this.on('gossip:refresh', this._handleGossipRefresh, this);
}
SDAAria.ATTRS = {
     strings: {
         valueFn: function () {
             return Y.Intl.get('sd-aria');
         }
     }
};
SDAAria.prototype = {
    _ariaSay: function (stringId, subs) {
        var message = this.get('strings.' + stringId) || '';
        this._liveRegion.setContent( subs ? Y.Lang.sub(message, subs) : message );
    },
    _handlerMsg: function (e) {
        if (e.id) {
            this._ariaSay(e.id, e.subs);
        }
    },
    _handleGossipRefresh: function () {
        var size = this.get('suggestions').size();
        this._ariaSay( (size > 0 ? 'SUGGESTIONS' : 'NO_SUGGESTIONS'), {
            n: size
        });
    }
};

Lessons learned

When creating an accessible interface, it’s important to ask the right questions. Making every bit of your application accessible may not be the right approach.

Request early feedback from users of screen readers — don’t assume that you have your bases covered until you get some user feedback. Utilizing every tool and feature at your disposal may not have the intended effect.

Users of screen readers may have difficulty keeping track of real-time updates, especially if screen readers are bombarded with notifications. In these scenarios, less can be more. Identify and focus on what is important for the user instead of trying to replicate the raw experience of the application for the screen reader.

Caridy PatiñoAbout the author: Caridy Patiño, Principal Frontend for Yahoo! Search Direct. He has been a longtime YUI Contributor and creator of Bubbling Library YUI Extension, as well as guest blogger at YUIBlog.com sharing some of his extensive experience building high performance web applications. Loading strategies, event-driven architectures and SSJS are some of the subjects where Caridy spends most of his time these days.

By Caridy PatinoAugust 8th, 2011

Developing an Accessible Star Ratings Widget

In a hurry? Skip to the demo page.

Many ecommerce sites, social networking services, and online communities include rating or assessment features. Soliciting people’s opinion has even become a business model; there are now sites dedicated to rating products, services, businesses, and more.

The most common interface used to display votes is the “star rating system,” in which a particular number of points (often expressed as stars) is assigned to an item by each reviewer. We find this model on many sites, from Amazon to Yelp.

Examples of star rating systems

Figure A. Star rating examples from Amazon and Yelp.

As Figure A shows, both visual interfaces are similar, but what makes these two solutions interesting is their markup base. One relies on <map>, the other on <img>.

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>,
  • <span>,
  • <li>,
  • <map>,
  • <div>,
  • <input>,
  • and more…

The case of Microformats

Before presenting a few image-based techniques to mark up ratings, I think it is worth mentioning a basic and straightforward approach (from Microformats) that uses characters:

<abbr class="rating" title="3 stars">***</abbr>
Pros
It is straightforward and semantic.
The markup is minimal.
The method is not reliant on CSS.
The method is not reliant on images.
There is no HTTP request.
Cons
It is impossible to represent half values (i.e. 3.5 stars)
It "works" only with asterisks ("star rating").
Screen-readers, by default, do not expand abbreviations (which may not be a big deal in this case).

Note: I use "*" rather than ★ (★) because screen-readers (at least JAWS and NVDA) seem to ignore html entities.

Markup to display image-based ratings

When it comes to display images, authors have many options.

One image per rating

Using a single image:

<img src="4stars.png" alt="4 out of five">
One star
1 out of five
Two stars
2 out of five
Three stars
3 out of five
Four stars
4 out of five
Five stars
5 out of five
Pros
Using one image per rating is straightforward and semantic.
The method is not reliant on CSS.
Minimal markup.
Cons
It creates many HTTP requests as there are many different images.
On top of the performance issue, it can be a maintenance nightmare as authors have to deal with more assets (images to create, to push to a CDN, to modify when site colors change, etc.).
Text selection is not possible in Opera (at least in version 9.52) as the alternate text is ignored

One image per unit

From the whatwg‘s working draft:

<img alt="4 out of 5" src="one-star.png">
<img alt="" src="one-star.png">
<img alt="" src="one-star.png">
<img alt="" src="one-star.png">
<img alt="" src="no-star.png">
One star
1 out of five
Two stars
2 out of five
Three stars
3 out of five
Four stars
4 out of five
Five stars
5 out of five
Pros
Using two img elements per rating diminishes the number of HTTP requests.
The method is not reliant on CSS.
Cons
In Opera, when images are disabled, alternate text is not selectable, and (in small-screen view) that text is rendered with a border which makes it less legible.

Note that this is taken from a controversial working draft. In my opinion, this method is not acceptable because the alternate text does not describe the image accurately and succinctly. Besides, if the basis of this approach is that these images represent content, then why leave some of them with no alt text?

On Ajaxian, for example, the author is using alternate text with every single image, which makes a lot of sense if he considers that each one is content:

<img [snip] alt="+" src="star1.png"/>
<img [snip] alt="+" src="star1.png"/>
<img [snip] alt="+" src="star1.png"/>
<img [snip] alt="-" src="star0.png"/>
<img [snip] alt="-" src="star0.png"/>

In any case, using as many images as there are stars versus using a single element (an img or something else) has the main advantage of facilitating voting mechanisms – where a user selects one of the stars to cast his vote. So we should keep this in mind…

A sprite for background images

The following technique is a adaptation of a strategy originally implemented by developers at Yahoo! Music:

Markup
<span class="rating r1 stars">1 of 5</span>
<span class="rating r2 stars">2 of 5</span>
<span class="rating r3 stars">3 of 5</span>
<span class="rating r4 stars">4 of 5</span>
<span class="rating r5 stars">5 of 5</span>
CSS
.stars {
  background: transparent url(img/sprite.png) no-repeat; 
}
.rating {
  font-size: 0;
  height: 19px;
  overflow: hidden;
  vertical-align: middle;
  width: 96px; 
  display: block;
}
.r1 { background-position: -385px 0; }
.r2 { background-position: -288px 0; }
.r3 { background-position: -192px 0; }
.r4 { background-position: -96px 0; }
One star
1 of 5
Two stars
2 of 5
Three stars
3 of 5
Four stars
4 of 5
Five stars
5 of 5
Pros
This method requires a single HTTP request as it relies on a single sprite image.
Minimal "foot print".
Cons
Content is not revealed with images off.
Nothing shows when the page is printed (a print stylesheet could take care of this issue).
In Opera, the high contrast stylesheet makes all the stars disappear; the same is true in High Contrast Mode Optimization.
Text selection is possible, but it’s not obvious (via highlighting).

A sprite in the markup

This approach is based on the TIP method, which uses a sprite image as an <img> element rather than a background image:

Markup
<span title="1 of 5" class="rating r1"><img width="0" height="1" src="sprite.gif" alt=""/>1 out of 5</span>
<span title="2 of 5" class="rating r2"><img width="0" height="1" src="sprite.gif" alt=""/>2 out of 5</span>
<span title="3 of 5" class="rating r3"><img width="0" height="1" src="sprite.gif" alt=""/>3 out of 5</span>
<span title="4 of 5" class="rating r4"><img width="0" height="1" src="sprite.gif" alt=""/>4 out of 5</span>
<span title="5 of 5" class="rating r5"><img width="0" height="1" src="sprite.gif" alt=""/>5 out of 5</span>
CSS
.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; }
One star
1 out of 5
Two stars
2 out of 5
Three stars
3 out of 5
Four stars
4 out of 5
Five stars
5 out of 5
Pros
This method requires a single HTTP request.
This technique is the only one of the four methods above that reveals content when Firefox users select "hide images" or "make images invisible" (from the developer’s toolbar).
When images are unavailable a red "x" appears only in the highest rating (i.e. 5 out of 5) instead of in each one as it is the case with other solutions that rely on img elements.
Cons
The display of images is reliant on CSS.

It is worth noting that unlike other Image Replacement techniques, this method allows:

  • images to scale depending on text-size settings.
  • images to be printed.
  • alternate text to be easily selected as the whole image appears highlighted (Firefox).
  • the image to not disappear in a high-contrast setting/stylesheet.
  • alternate text selection in Opera (when images are disabled).
  • borderless alternate text in Opera’s small screen view.

Markup to cast votes

Starting with a native mechanism

To cast votes, we need a low-level voting mechanism that allows simple user selection and submission. For this, we can rely on using a form with labels and controls:

Markup
<fieldset>
  <legend>Rating</legend>
  <label><input type="radio" name="movie" value="1_5">1/5</label>
  <label><input type="radio" name="movie" value="2_5">2/5</label>
  <label><input type="radio" name="movie" value="3_5">3/5</label>
  <label><input type="radio" name="movie" value="4_5">4/5</label>
  <label><input type="radio" name="movie" value="5_5">5/5</label>
</fieldset>
Result
Rating






Adding breaks and whitespace

For better legibility, we add <br> and whitespace.

Markup
<fieldset>
<legend>Rating</legend> <label><input type="radio" name="movie" value="1_5"> 1/5</label><br> <label><input type="radio" name="movie" value="2_5"> 2/5</label><br> <label><input type="radio" name="movie" value="3_5"> 3/5</label><br> <label><input type="radio" name="movie" value="4_5"> 4/5</label><br> <label><input type="radio" name="movie" value="5_5"> 5/5</label> </fieldset>
Result
Rating






Introducing the sprite image in the markup

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.


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

Note that with the above markup, we can expect (in most browsers) field selection via label selection.

Considering Accessibility

Unfortunately, as is, this markup creates issues in at least two screen-readers: JAWS and NVDA (see test case for these bugs). The problem is related to the use of a title attribute and an empty string for alternate text.

The workaround to not confuse screen-reader users is to use "stars" as alternate text (alt) and use JavaScript to insert title on mouseover.

Better Markup
<fieldset>
<legend>Rating</legend> <label><img src="img/small-sprite.gif" width="0" height="1" alt="stars"><input type="radio" name="movie" value="1_5"> 1/5</label><br> <label><img src="img/small-sprite.gif" width="0" height="1" alt="stars"><input type="radio" name="movie" value="2_5"> 2/5</label><br> <label><img src="img/small-sprite.gif" width="0" height="1" alt="stars"><input type="radio" name="movie" value="3_5"> 3/5</label><br> <label><img src="img/small-sprite.gif" width="0" height="1" alt="stars"><input type="radio" name="movie" value="4_5"> 4/5</label><br> <label><img src="img/small-sprite.gif" width="0" height="1" alt="stars"><input type="radio" name="movie" value="5_5"> 5/5</label> </fieldset>
Result
Rating






Styling

Giving dimensions to the image via CSS

We use em to allow the image to grow or shrink depending on font-size.

Markup

Unchanged

CSS
img {
  width:2.8em;
  height:1.4em;
}
Result
Rating






As you can see already, clicking on an image selects the corresponding radio button. There is no need for scripting as implicit labeling produces this behavior (except in IE).

Removing the image from the flow

Styling the label with position:relative and the image with position:absolute with top/left values is enough to hide input and text inside the labels.

Markup

Unchanged

CSS
label {
  position:relative;
}
img {
  width:2.8em;
  height:1.4em;
  position:absolute;
  top:0;
  left:0;
}
Result
Rating






Displaying one star per label

We style the label so its dimensions match the height and width of a single star.

Markup

Unchanged

CSS
label {
  position:relative;
  height:1.4em;
  width:1.4em;
  overflow:hidden;
  display:block;
}
img {
  width:2.8em;
  height:1.4em;
  position:absolute;
  top:0;
  left:0;
}
Result
Rating






Displaying the stars horizontally

We remove the brs and we float the labels.

Markup

Unchanged

CSS
br {
  display:none;
}
label {
  position:relative;
  height:1.4em;
  width:1.4em;
  overflow:hidden;
  display:block;
  float:left;
}
img {
  width:2.8em;
  height:1.4em;
  position:absolute;
  top:0;
  left:0;
}
Result
Rating






Displaying the sprite image depending on rating

To set a "3 out of 5" rating, we apply the same class to the last two labels. This class will shift the position of the image inside the label.

Markup
<fieldset>
<legend>Rating</legend>
<label><img src="img/small-sprite.gif"  width="0" height="1" alt="stars"><input type="radio" name="movie" value="1_5"> 1/5</label><br>
<label><img src="img/small-sprite.gif"  width="0" height="1" alt="stars"><input type="radio" name="movie" value="2_5"> 2/5</label><br>
<label><img src="img/small-sprite.gif"  width="0" height="1" alt="stars"><input type="radio" name="movie" value="3_5"> 3/5</label><br>
<label class="no_star"><img src="img/small-sprite.gif"  width="0" height="1" alt="stars"><input type="radio" name="movie" value="4_5"> 4/5</label><br>
<label class="no_star"><img src="img/small-sprite.gif"  width="0" height="1" alt="stars"><input type="radio" name="movie" value="5_5"> 5/5</label>
</fieldset>
CSS
br {
  display:none;
}
label {
  position:relative;
  height:1.4em;
  width:1.4em;
  overflow:hidden;
  float:left;
}
img {
  width:2.8em;
  height:1.4em;
  position:absolute;
  top:0;
  left:0;
}
.no_star img {
  left:-1.4em;
}
Result
Rating






Not relying on image alone to display information

It’s important to offer an alternative to the display of stars in case images are not available. This is because labels and radio buttons are styled to be on top of each other. A simple solution is to move input and text off-screen (i.e. using text-indent:-999em) and apply a background color to the labels.

Markup

No change

CSS
br {
  display:none;
}
label {
  position:relative;
  height:1.4em;
  width:1.4em;
  overflow:hidden;
  float:left;
  background:teal;
  margin-right:1px;
  text-indent:-999em;
}
img {
  width:2.8em;
  height:1.4em;
  position:absolute;
  top:0;
  left:0;
}
.no_star {
  background:#ccc;
}
.no_star img {
  left:-1.4em;
}

Note:

  • text-indent also fixes a upwards jump of the image each time the controls get focus.
  • the right margin is to make sure background colors create squares and not rectangles (which would happen with adjacent labels sharing the same background color).
Result
Rating






Finishing touch

  • We use the pseudo-class :hover to create some rollover effect,
  • We hide the fieldset border,
  • We hide the legend,
  • We style the cursor.
Markup

Unchanged

CSS
br {
  display:none;
}
label {
  position:relative;
  height:1.4em;
  width:1.4em;
  overflow:hidden;
  float:left;
  background:teal;
  margin-right:1px;
  text-indent:-999em;
}
input {
  position:absolute;
  left:-999em;
  top:.5em;
}
img {
  width:2.8em;
  height:1.4em;
  position:absolute;
  top:0;
  left:0;
  cursor: pointer;
}
.no_star {
  background:#ccc;
}
.no_star img {
  left:-1.4em;
}
label:hover {
  opacity:.5;
  filter:alpha(opacity=50);
}
fieldset {
  border:0;
}
legend {
  text-indent:-999em;
}

Note: label:hover is ignored by IE6 and in Opera the background color bleeds through the images. In the demo page, instead of using opacity, I am using a different sprite that shows four states.

Result

Rating






Displaying the ratings without allowing user interaction

We can make the ratings "read-only" by adding disabled and checked attributes in the appropriate input fields.

Markup

<fieldset>
  <legend>Rating</legend>
  <label><img src="img/small-sprite.gif"  width="0" height="1" alt="stars"><input type="radio" name="movie" value="1_5" disabled> 1/5</label><br>
  <label><img src="img/small-sprite.gif"  width="0" height="1" alt="stars"><input type="radio" name="movie" value="2_5" disabled> 2/5</label><br>
  <label><img src="img/small-sprite.gif"  width="0" height="1" alt="stars"><input type="radio" name="movie" value="3_5" checked="checked"> 3/5</label><br>
  <label class="no_star"><img src="img/small-sprite.gif"  width="0" height="1" alt="stars"><input type="radio" name="movie" value="4_5" disabled> 4/5</label><br>
  <label class="no_star"><img src="img/small-sprite.gif"  width="0" height="1" alt="stars"><input type="radio" name="movie" value="5_5" disabled> 5/5</label>
</fieldset> 

CSS

The rule using :hover has been removed

h4>Result

Rating






Giving more thought to the process

At this point, it is possible to cast votes without script support, but sighted users have no clue about their selection. So we use JavaScript to:

  • give feedback to the user regarding his selection,
  • give keyboard users a visual clue while they navigate through the radio buttons.

At the same time, we take advantage of using a script to insert title attributes that will create "tooltips" when users hover over the labels/stars.

Because of the lack of feedback regarding selection without JavaScript, we style labels and form controls only if there is script support. To do so we use JavaScript to set a flag on the html element and then we create a rule based on descendant selectors containing that hook. If the flag is missing, that rule does not apply and elements are not styled.

This is the demo page, the final product. To see how this solution behaves according to various settings, you may want to use your favorite developer tools to increase text-size, break image paths, disable JavaScript, turn CSS off, and more…

Wrap up

Coming up with a "acceptable" solution requires to identify users’ needs, User Agents’ peculiarities, User Agents’ settings and more – which means extensive testing.

In this process, users’ feedback is essential because following best practices is not always a sure thing. For example, as mentioned earlier, setting no value for the alt attribute of the images within the labels seem to be the safe thing to do, but it turns out that it creates issues with at least two screenreaders (see test case).

Also, feedback from assistive devices’ users allows to ignore some validation error messages – as the one that the Firefox Accessibility Toolbar reports (according to http://bestpractices.cita.uiuc.edu/html/nav/form/).

The goal here was not to fix everything, though. Being able to cast votes without a pointing device was one of my priorities, but improving the look and feel of the solution in Opera when images are disabled is not something I consider essential.

The most interesting part of this "journey" was to make the solution accessible to many users under various conditions, addressing issues such as:

  • images off,
  • javascript off,
  • CSS off,
  • a combination of the above.

It is also nice to know that this technique relies on img elements rather than background images, which allows the stars to:

  • resize themselves according to the user’s settings,
  • show in high contrast mode,
  • be printed by default (unlike background images).

All of this comes without sacrificing performance, as this solution relies on this single sprite: stars

Late finding

I recently discovered the system Amazon has built for its voting page. It is quite interesting as they serve a different solution depending on script support. If there is script support, they use an image <map> (interesting approach), if there is no script support they use radio buttons. In both cases, the solution is accessible to keyboard users, and this helps to maximize access to a feature that is a core differentiator for the Amazon platform.

Note that they do not use JavaScript to replace the radio buttons with a image <map>; instead, they use noscript elements in which table markup contains radio buttons.

"Out of the box" solutions

Dreamweaver®
Spry Rating Widget
YUI
Star Rating Script for YUI
Star Rating script with YUI
JQuery
Half-Star Rating Plugin
jQuery Ajax Rater
Simple Star Rating System
5 star rating system in PHP, MySQL and jQuery
WordPress
GD Star Rating System for WordPress
GD Star Rating
Star Rating for Reviews
Flash
5 Star rating system component
Misc.
How a star rating should be
Starry widget 2

Special thanks

Special thanks to Victor Tsaran and Todd Kloots for their valuable feedback.

By Thierry KoblentzAugust 24th, 2010

YUI Theater — Nicholas Zakas and Victor Tsaran: “Accessibility on the Yahoo Homepage (58 min.)”

Nicholas Zakas and Victor Tsaran's Talk at the BayJax event at Yahoo! in June, 2010.

In June, Yahoo! hosted a BayJax meetup dedicated to web accessibility. Nicholas Zakas, Yahoo! homepage developer, and Victor Tsaran, Yahoo! senior accessibility program manager, gave a talk on the process of making Yahoo!’s homepage highly accessible.

We apologize for the uneven audio levels: there were technical issues with the microphones that we unfortunately were only able to adjust towards the second half of the talk.

If the video embed below doesn’t show up correctly in your RSS reader of choice, be sure to click through to watch the high-resolution version of the video on YUI Theater.

  • Download HD video (480p ~1.4GB)
  • Download video (m4v)

Other Recent YUI Theater Videos:

  • Dennis Lembree: Making JavaScript Accessible — Dennis Lembree, an accessibility expert and the creator of AccessibleTwitter discusses the challenges of making JS-enabled sites accessible. The talk took place at the June 2010 BayJax meetup at Yahoo.
By Allen RabinovichAugust 16th, 2010

YUI Theater — Dennis Lembree: “Making JavaScript Accessible (26 min.)”

Dennis Lembree's Talk at the BayJax event at Yahoo! in June, 2010.

In June, at the BayJax meetup on web accessibility hosted by Yahoo!, the accessibility expert Dennis Lembree gave a talk on the challenges of making JavaScript-enabled websites accessible.

If the video embed below doesn’t show up correctly in your RSS reader of choice, be sure to click through to watch the high-resolution version of the video on YUI Theater.

  • Download HD video (480p ~682MB)
  • Download video (m4v)

Other Recent YUI Theater Videos:

  • Nicholas Zakas and Victor Tsaran: Accessibility on the Yahoo Homepage — Nicholas Zakas, a principal developer of the Yahoo! homepage, and Victor Tsaran’s, Yahoo!’s senior accessibility manager, discuss the strategies and methods that made one of the most visited websites in the world fully accessible. The talk took place at the June 2010 BayJax meetup at Yahoo.
  • Nicholas Zakas, Stoyan Stefanov, Ross Harmes, Julien Lecomte, Matt Sweeney: High Performance JavaScript — Five contributors to O’Reilly’s High Performance JavaScript discuss advanced JavaScript and DOM scripting optimizations at the April 2010 BayJax meetup at Yahoo.
  • Christian Heilmann: YQL and YUI: Building Blocks for Quick Applications — The Yahoo! Developer Network’s international evangelist Christian Heilmann discusses his philosophy for creating fast, powerful, compelling applications using the Yahoo Query Language (YQL) and the Yahoo User Interface Library (YUI).
By Allen RabinovichAugust 16th, 2010

YUI Theater — Todd Kloots: “Building Accessible Widgets with YUI 3″

YUI engineer Todd Kloots speaks at YUICONF 2009, held at the Yahoo! HQ in Sunnyvale; October 28, 2009.

We wrap up YUI Theater coverage of YUICONF 2009 with a talk from Todd Kloots (@toddkloots) on the accessibility features of YUI 3: “Building Accessible Widgets with YUI 3.” Todd covers YUI’s support for keyboard handling, focus styling and management, ARIA roles and states, and much more. (Don’t miss Todd’s other YUICONF talk, “YUI 3 Sugar,” which is a great primer on other hidden gems in the library.)

If the video embed below doesn’t show up correctly in your RSS reader of choice, be sure to click through to watch the high-resolution version of the video on YUI Theater; the downloadable version is much smaller, optimized as it is for iPods, iPhones, and other handheld devices.

  • Download video (m4v)
  • Download slides

The Full Roster of YUICONF 2009 Videos on YUI Theater:

  • Douglas Crockford: The State and Future of JavaScript — Yahoo! JavaScript Architect Douglas Crockford discusses the recent ECMA5 development process and efforts to improve the language in the future.
  • Brendan Eich: ECMA Harmony and the Future of JavaScript — Brendan Eich, the creator of the world’s most popular programming language, talks about the struggle over the ES4 proposal and how it resulted in a specific set of proposals for ES5.
  • Luke Smith: Events Evolved — YUI engineer Luke Smith provides a deep introduction to the YUI 3 event system including its support for DOM events, event delegation, synthetic events, and custom events.
  • Todd Kloots: YUI 3 Sugar — YUI engineer Todd Kloots presents an indispensable introduction to YUI 3′s powerful suite of tools.
  • Isaac Schlueter: Solving Problems with YUI 3 — YUI engineer Isaac Schlueter works through a real-world use case of building YUI 3′s forthcoming AutoComplete widget.
  • Dav Glass: Contributing to YUI — YUI engineer Dav Glass introduces you to the YUI Gallery and steps through the process of making contributions to the YUI project.
  • Allen Rabinovich: YUI 3 Infographics — YUI engineer Allen Rabinovich discusses the YUI 3 Charts implementation, currently under development.
  • Reid Burke: Building YAP Applications with YUI — YUI engineer Reid Burke discusses the Yahoo! Application Platform and how you can use it, along with YUI, to reach Yahoo!’s vast audience.
  • Matt Sweeney: YUI 3 Performance — YUI architect Matt Sweeney reviews principles of high-performance web development and looks at how best to implement those principles in YUI 3-based projects.
  • Satyen Desai: A Widget Walkthrough — YUI engineer Satyen Desai provides a detailed tour of the YUI 3 widget subsystem.
  • Todd Kloots: Building Accessible Widgets with YUI 3 — YUI engineer Todd Kloots demonstrates the accessibility toolkit built into YUI 3.
  • Chad Auld: Introducing PHP Loader — Chad Auld of Yahoo! introduces the YUI PHP Loader, a flexible tool for loading modular JavaScript and CSS projects.
  • Eric Ferraiuolo: Web App Development with YUI 3 — Eric Ferraiuolo of Oddnut Software talks about the nuances of deploying real-world web applications using YUI 3.
  • Ron Adams: Automated Integration Testing with YUI Test, Selenium and Hudson — Yahoo! engineer Ron Adams discusses the creation of automated QA workflows that combine YUI Test, Selenium and Hudson to automate JavaScript unit tests.
  • Stephen Woods: Creating Beautiful Documentation with YUI Doc — Yahoo! frontend engineer Stephen Woods provides a guided tour to YUI’s documentation engine, YUI Doc. YUI Doc is language-agnostic and can be used to document a variety of project styles.
  • Matt Snider: Introducing the YUI 2.8.0 Storage Utility — Matt Snider, the lead frontend engineer for Mint.com (recently acquired by Intuit), contributed the YUI Storage Utility in the 2.8.0 release. In this session, he provides an overview of the Storage Utility’s features and the nuances of the various storage backends.
  • Luke Smith: Debugging in YUI 3 — YUI engineer Luke Smith discusses the fine art of debugging web applications, looking at general tools and techniques and providing a few specific hints about debugging in YUI 3.

Subscribing to YUI Theater:

  • YUI Theater RSS feed
  • YUI Theater on iTunes
By Eric MiragliaNovember 23rd, 2009

YUI’s Todd Kloots in London for Accessibility/ARIA Tech Talk on Nov. 17

Yahoo! accessibility specialist Todd Kloots will be in London in November for a tech talk hosted by Skills Matter. The talk, “More Accessible User Interfaces with ARIA,” will offer practical tips and design patterns for using ARIA to create accessible user interfaces that work across all of the various combinations of browsers and assistive technology that support ARIA.

The event is free; you can register on the Skills Matter website.

If you can’t wait until November to start diving into ARIA, Todd has you covered with a good library of blog posts and tech videos on the subject.

Todd Kloots: "Developing Accessible Widgets Using ARIA" @ Yahoo! Video

By Eric MiragliaSeptember 17th, 2009

ARIA Made Easier With YUI 3

As mentioned in my talk Developing an Accessible Web 2.0 Widget Framework, one of the goals of YUI 3 is to make it easier for developers to build accessible user interfaces. To that end we’ve taken accessibility into consideration from the very start while building YUI 3, and the recent YUI 3.0.0 beta 1 release introduces several new additions that make it easier for developers to build ARIA-enabled widgets.

ARIA Attribute Support Added to Node

The Node Utility is YUI 3′s primary interface for interacting with the DOM, and it provides not only an abstraction model but built-in support for CSS Selector queries as a means of accessing HTML elements. Support for ARIA attributes has been added to the Node interface in the YUI 3.0.0 beta 1 release, allowing developers to use the expressive power of CSS Selector queries to apply and manage an element’s ARIA roles and states and properties.

Apply any of the ARIA attributes via Node’s set method. For example, to apply the role of toolbar to a <div> with an id of “toolbar”:


YUI().use('node', function(Y) {
    var node = Y.get('#toolbar').set('role', 'toolbar');
});

In addition to Node’s built-in support for CSS selector queries, it also supports chaining and the ability to set multiple attributes on a single Node. When used together, these features of Node make it especially easy to apply the ARIA roles, states, and properties when building DHTML widgets with a large subtree.

For example, when building a menubar widget it is necessary to apply a role of menubar to the root DOM element containing the menubar, and the role of menu to the root DOM element containing each submenu. Additionally, as each submenu is hidden by default, the aria-hidden state will need to be applied to each submenu as well. The Node interface makes it possible to do all of this in one line of code:


YUI().use('node', function(Y) {
    Y.get('#rootmenu').set('role', 'menubar').queryAll('.menu').setAttrs({ role: 'menu', 'aria-hidden': true });
});

Keyboard Support with the New Focus Manager Node Plugin

To work, ARIA requires developers provide keyboard access for widgets, since users of screen readers rely on the keyboard to navigate web sites and applications. As outlined in the ARIA specification and corresponding Best Practices document, providing keyboard access requires, in part, that each widget has one tab stop by default and is responsible for discretely managing focus for its descendants. Following these guidelines enables users to quickly navigate a page or application by using the tab key to move between widgets. Once a user has tabbed into a widget, they can then use other keys (the arrow keys for example) to move focus amongst the widget’s descendants.

The Focus Manager Node Plugin, which is available as of the YUI 3.0.0 beta 1 release, makes it easy to define a Node’s focusable descendants, define which descendant should be in the default tab flow, and define the keys that move focus among each descendant. Additionally, since the CSS pseudo class :focus is not supported on all elements in all A-Grade browsers, the Focus Manager Node Plugin provides an easy, cross-browser means of styling focus.

New ARIA Examples

For YUI 3.0.0 beta 1 we’ve also added a handful of examples that demonstrate the power of the Focus Manager Node Plugin to implement keyboard support to existing widgets and exercise Node’s new ARIA-related APIs.

  • ARIA-Enabled Toolbar
  • ARIA-Enabled TabView
  • ARIA-Enabled Menu Button

Developers wishing to experience the benefits that ARIA provides can download the open-source NVDA Screen Reader and Firefox to test each example themselves. Alternatively, I’ve made screencasts of each example running with NVDA and Firefox.

YUI 3 Beta 1 ARIA Toolbar Video


YUI 3 Beta 1 ARIA Toolbar @ Yahoo! Video

YUI 3 Beta 1 Menu Button Video


YUI 3 Beta 1 ARIA Menu Button @ Yahoo! Video

YUI 3 Beta 1 ARIA Tabview Video


YUI 3 Beta 1 ARIA Tabview @ Yahoo! Video

The Road Ahead

While YUI 3 is presently composed mostly of utilities, we are hard at work polishing our widget infrastructure and will soon begin building out widgets. With YUI 3 our goal is to make it as easy as possible to build accessible user interfaces, whether you are building a widget from scratch, or implementing one of ours. We think we’re off to a good start with ARIA support incorporated into the Node interface and the Focus Manager Node Plugin. So, I want to encourage developers to start using these interfaces, and to let us know what’s missing, what’s not working, and what it is.

Additional Resources

  • Developing Accessible Widgets Using ARIA
  • Improving Accessibility Through Focus Management
  • Configuring Your Machine For Testing With A Screen Reader
By Todd KlootsAugust 3rd, 2009
« Older Entries

Pages

  • About
  • Contribute
  • YUI Jobs

Recent Posts

  • YUI Weekly for May 24th, 2013
  • YUI Weekly for May 17th, 2013
  • Yahoo’s International Team Is Hiring!
  • YUICompressor 2.4.8 Released
  • YUI 3.10.1 Released to Fix SWF Vulnerability

Archives

Categories

  • Accessibility (25)
  • CSS 101 (6)
  • Design (51)
  • Development (590)
  • Frontend Jobs at Yahoo (13)
  • Graded Browser Support (8)
  • In the Wild (63)
  • Miscellany (11)
  • Open Hours (44)
  • Performance (23)
  • Releases (26)
  • Target Environments (11)
  • Yeti (4)
  • YUI 3 Gallery (29)
  • YUI Events (45)
  • YUI Implementations (55)
  • YUI Theater (146)
  • YUI Weekly (38)

Meta

  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
© 2013 YUI Blog