Blog
Making jQuery Cycle Accessible
Pixo recently launched the new website for Disability Resources and Educational Services at the University of Illinois (DRES). DRES is one of the international leaders in providing accessible residential and academic services in a university environment, so this project was just the kind of challenge we've been waiting for at Pixo — building an accessible, beautiful site that's as easy to use as to administer.
We relied on the jQuery Cycle plugin to add interactivity to the front page, specifically the 'Spotlight' and 'History of Firsts' carousels. One of the assets of Cycle is the plugin's relative indifference about the code it manipulates. This matters for accessibility, since we want to avoid using inappropriate tags anywhere in our code. The DRES Spotlight carousel will provide us with a few nice examples of how to produce ARIA-friendly cycles and how screen readers parse this code for their users.

What makes the Spotlight accessible?
If we use a code debugger, such as Firebug, we find ARIA in use in a few key places in our Spotlight. The first is to help users understand what the spotlight container DIV is, thanks to aria-labelledby.
<div id="spotlight" class="spothist" role="region" aria-labelledby="spotlight-title"> ... <h3 id="spotlight-title">Spotlight</h3>
aria-labelledby refers to an ID on the page — the "spotlight-title" H3, in this case.
We're also using an ARIA attribute on the unordered list containing our slides.
<ul class="spotlight-slides" style="position: relative;" aria-live="assertive">
The aria-live attribute tells the screen reader that the content of that UL can dynamically change, and "assertive" tells the reader to interrupt itself to read the newest contents, when a change occurs.
There's one more use of ARIA in the spotlight that we should note:
<div id="spotlight-title-0" class="views-field views-field-title">
<strong class="field-content">
AHS Distinguished Alumni - Harold Scharper Awards presentation
</strong>
</div>
...
<a href="/spotlights/AHS Distinguished Alumni - Harold Scharper Awards presentation" aria-describedby="spotlight-title-0">More »</a>Here, we use aria-described-by on the "More »" link to create a logical relationship between that link and the title of the slide.
This is really all we need to do with ARIA — remember that we use ARIA to codify relationships between content that may not be obvious to users with screen readers. Fortunately, nothing about ARIA interferes with Cycle, so they're a good match.
Avoiding anchor tags
One of the challenges we faced in writing this Spotlight was avoiding the use of anchor tags for navigation, which is a common approach with Cycle. Screen readers, however, place special emphasis on links because they're navigation elements. When a screen reader encounters a link, it tells the user that clicking it will take them somewhere. That is not how paging works with Cycle.
Fortunately, the solution was simple. If we look at our jQuery invocation code, we see pagers specified not as elements but just as IDs:
$('ul.spotlight-slides').cycle({
fx: 'none',
speed: 'fast',
timeout: 0,
next: "#spot-next",
prev: "#spot-prev",
});And, in our code for the pager, we see BUTTON elements used for navigation:
<div class="fp-block-pager">
<div class="fp-block-pager-prev">
<button id="spot-prev">
<div class="fp-block-pager-prev-img">
Previous Spotlight Story
</div>
</button>
</div>
<div class="fp-block-pager-next">
<button id="spot-next">
<div class="fp-block-pager-next-img">
Next Spotlight Story
</div>
</button>
</div>
</div>By using buttons, we avoid confusing a screen reader with unnecessary links.
Populating your Cycle with a View and Templates
In the above example, we're turning an HTML list into a paging cycle. We create this list using Views. The View is uncomplicated — we select an HTML List display and populate it with fields including title, image (with alt text), teaser text and more link.
We do have a template for this view - views-view-list--front-spotlight--block.tpl.php.
<?php print $wrapper_prefix; ?>
<div class="fp-block-titlebar">
<h3 id="spotlight-title">Spotlight</h3>
<div class="fp-block-viewall">
<a href="spotlights">All Spotlights »</a>
</div>
</div><!-- /.fp-block-title -->
<div class="clearfix"></div>
<?php if (!empty($title)) : ?>
<h3><?php print $title; ?></h3>
<?php endif; ?>
<?php print $list_type_prefix; ?>
<?php foreach ($rows as $id => $row): ?>
<li class="<?php print $classes_array[$id]; ?>">
<?php print $row; ?>
</li>
<?php endforeach; ?>
<?php print $list_type_suffix; ?>
<div class="fp-block-pager-wrapper">
<div class="fp-block-pager">
<div class="fp-block-pager-prev">
<button id="spot-prev">
<div class="fp-block-pager-prev-img">
Previous Spotlight Story
</div>
</button>
</div>
<div class="fp-block-pager-next">
<button id="spot-next">
<div class="fp-block-pager-next-img">
Next Spotlight Story
</div>
</button>
</div>
</div> <!-- /.fp-block-pager -->
</div> <!-- /.fp-block-pager-wrapper -->
<?php print $wrapper_suffix; ?>We see our pager here, as well as our link to all Spotlights. We also use a few custom classes to make design easier.
What we don't see are ARIA attributes — we place most of these with Javascript, both to avoid validation problems and to target content without making a template for every element we need to touch. It's often easier to apply attributes with jQuery than to override Drupal code output.
$("#spothist #spotlight .spotlight-slides").attr({ 'aria-live': "assertive" });
$('.view-front-spotlight .views-row').each(function(index, value) {
$(".views-field-title",this).attr("id","spotlight-title-" + index);
$(".views-field-nothing a",this).attr("aria-describedby","spotlight-title-" + index);
});With this code, we apply aria-assertive tags to the UL and sequentially relate every spotlight title to every "More »" link. Feel free to use and expand upon this code for your own projects.
What's the end result?
Now that we've created the Cycle and populated it with our View and template, we can examine our results in a screen reader like JAWS. We see what we'd expect: JAWS reads the content of the Spotlight as it moves down the page. When you click the "Next" Spotlight button, it interrupts itself and then reads the spotlight that has come onscreen. Whether you move backwards or forwards, JAWS reads the new text that appears on screen.
When you're building your own Cycle, here are some things you can do to ensure an accessible result:
- Know which ARIA tags you'll need to use in order to logically relate the different elements of your cycle.
- Make sure images have ALT tags.
- Use BUTTON elements for navigation instead of anchors.
- Avoid using effects, as you may have two Cycle slides visible at the same time (e.g. during a crossfade, both slides are displayed). This can confuse screen readers.
- Use jQuery to place ARIA attributes instead of hacking Drupal templates.
-
Don't overcomplicate things. Screen readers are much like human readers - they want concise code that is logically and clearly related. A minimum of aria tags combined with a straightforward design goes a long way.




Comments
Post new comment