In the previous article in this series we looked at the first principle of accessibility: ensuring content must be available in a format which can be readily perceived by the user. If a user is using assistive technologies, one way of making that possible is to make it easier for those technologies to parse and understand your site and its content. In this article we'll be focusing on one particular way of doing this: ARIA.
WAI-ARIA (Web Accessibility Initiative—Accessible Rich Internet Applications), or ARIA, is a W3C protocol which improves your site's interaction with assistive technologies. It does this in a number of ways:
- Provides a way of declaring a page's structure (for instance labelling the purpose or role of a section of the page—navigation, search, main content, etc.).
- Improves accessibility of interactive controls (such as tree menus, drag and drop, sliders, sort controls, etc.) by declaring their 'state', (e.g. enabled/disabled, hidden, required fields).
- Provides a way of declaring regions where content may be updated dynamically (called live regions), so that updates may be brought to the attention of the user.
Legacy browsers don't present a problem here: ARIA is supported by most modern browsers and screen readers, and for the rest there are no compatibility issues.
In this series we'll focus on the first of the above bullet points, declaring an element's role as part of the page structure.
Roles
If a page's structure can be programmatically determined, and each 'region' of the web page be identified (e.g. the site's navigation, the main content, the sidebar, etc.), then assistive technologies can do a better job of presenting that structure to the user. For instance, "skip to content" links (which we'll cover in the next article) could become obsolete if a screen reader knew where the main content was. HTML, however, provides no way of identifying the purpose of a region on the page. This is where ARIA roles step in.
An ARIA role is simply an attribute value which identifies the purpose of the element. The most straightforward example would be a search form:
<form role="search"> ... </form>
The role 'search' identifies this <form>
as being a form for searching the site's content, and a screen-reader that is able to recognise that knows where to take the user if they want to search for content. Some screen-readers, for example, provide a shortcut key to jump to the search form. Equally, awareness of the structure of the page allows assistive technologies to generate a meaningful 'tree' of the page. The JAWS screenreader, for instance, uses the semi-colon key to skip between these roles, allowing the user to quickly jump between the site's regions (its header, navigation, main content, etc.).
This type of attribute is called Document Landmark Roles, and among the available values there are:
Banner
Content related to the website, for example the website name and/or company logo. In most themes this information is in header.php
, and labels an element that wraps the site title, description and logo with this role:
<div id="branding" role="banner"> <p class="site-title"> <a href="<?php echo esc_url( home_url( '/' ) );?>"> <?php echo get_bloginfo('name'); ?> </a> </p> <p class="site-description"> <?php echo get_bloginfo( 'description' );?> </p> </div>
Navigation
This role identifies the part of the page that contains the navigation links for the document or web site. A theme can have multiple navigation locations, and each one can be wrapped in a element with the navigation role:
<nav role="navigation"> <?php wp_nav_menu( array( 'theme_location' => 'primary' ) ); ?> </nav>
According to the HTML5 specifications, role="navigation"
is supposed to be implicit in the use of <nav>
, and so not required. However, there is no harm in being explicit.
Main
The main content of the page. This must only appear once on a page. Each theme will vary, but the relevant template files will typically include:
- index.php
- single.php
- page.php
Your 'main loop', for instance may look something like:
<div id="main" class="hfeed" role="main"> <?php if ( have_posts() ) : ?> <?php while ( have_posts() ) : the_post(); ?> //The loop content <?php endwhile; ?> <?php endif; ?> </div>
and your page templates might look something like:
<div id="main" role="main"> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <h1 class="entry-title"> <?php the_title(); ?> </h1> <div class="entry-content"> <?php the_content(); ?> </div> </div> </div>
Search
This identifies the search form(s) on your site, and it can be used more than once. Most themes do not 'hardcode' a search form into their theme, but instead rely on widgetised regions where the user can add the search widget. In this case (and assuming you're running WP 3.6 or higher), you don't need to do anything: WordPress's default search form already adds the search role appropriately. Furthermore it handles the form labels and submit button in an accessible manner too.
If you do hardcode a search form in your theme, be sure to use get_search_form()
(see codex). Finally, if you require your theme to change the default search form, you can create a template file called searchform.php
—but be sure to add the search role. The default search form template is:
<form role="search" method="get" class="search-form" action="<?php echo home_url( '/' ); ?>"> <label> <span class="screen-reader-text"><?php echo _x( 'Search for:', 'label' ); ?></span> <input type="search" class="search-field" placeholder="Search …" value="<?php echo get_search_query(); ?>" name="s" title="<?php echo esc_attr_x( 'Search for:', 'label' ); ?>" /> </label> <input type="submit" class="search-submit" value="<?php echo esc_attr_x( 'Search', 'submit button' ); ?>" /> </form>
Article
This identifies a piece of stand-alone content that makes sense in isolation. A good example of this would be the blog posts that appear on your 'posts' page. Equally each comment could be considered an 'article'. It can be nested too: for instance a comment (article) can sit inside the blog post (article).
<?php while ( have_posts() ) : the_post(); ?> <article id="post-<?php the_ID(); ?>" <?php post_class();?> role="article"> //Post title / excerpt... </article> <?php endwhile; ?>
Complementary
This identifies a region that has been described as "supporting content for the main content". In a WordPress context, this can be taken to mean any sidebars. Your sidebar.php
template, therefore, may look something like:
<div class="sidebar" role="complementary"> <?php if ( is_active_sidebar( 'right-sidebar' ) ){ dynamic_sidebar( 'right-sidebar' ); } ?> </div>
Contentinfo
This is typically used to identify the footer. Officially it is described as:
A large perceivable region that contains information about the parent document.
For example, it could include footnotes, copyrights, links to privacy statements, etc. However, it is generally used to label the footer of the page, regardless of its content. Firefox, Safari and Chrome automatically assign the contentinfo role to <footer>
tags:
<body> ... <footer role="contentinfo"> //Footer </footer> <?php wp_footer(); ?> </body>
ARIA and HTML5
Although it is increasing, support for HTML5 by screen readers varies. On the other hand, support for ARIA landmarks is typically much better. So although more and more browsers are automatically mapping semantic HTML5 tags to their appropriate role, it's still a good idea to explicitly state the role. However, care should be taken not to alter the native 'role' of a semantic element. For example, you should avoid doing something like:
<h1 role="button">Click Me!</h1>
Below is a list of some of the HTML5 elements, together with their implicit ARIA roles.
HTML5 element | Implied ARIA landmark role | Other notes |
---|---|---|
<header> |
role="banner" |
There should be only one instance of banner |
<nav> |
role="navigation" |
|
<main> |
role="main" |
There should be only one instance of main |
<article> |
role="article" |
|
<aside> |
role="complementary" |
|
<footer> |
role="contentinfo" |
There should be only one instance of contentinfo |
<button> |
role="button" |
When using HTML5, you should use a script like HTML5 Shiv v3.6, as used in the Twenty* themes, to provide support for legacy browsers.
Conclusion
Declaring ARIA roles is an incredibly easy way to aid users of assistive technologies to interpret your site's layout and find the content they're after. In the next part of this series we'll be looking at the principle of ensuring your theme is Operable. Loosely speaking this states that users should be able to be easily and safely navigate their way through your site.
Comments