CSS, JavaScript and XHTML Explained

Estelle Weyl’s Blog of quirks, random thoughts and funky finds discovered in day-to-day coding

 

WAI-ARIA: Accessible Rich Internet Applications basics March 14, 2009

Filed under: AJAX, Accessibility, Best Practices, Web Development — Estelle Weyl @ 10:57 pm

What is ARIA?

ARIA stands for Accessible Rich Internet Applications. With the proliferation of internet applications, there has been an increase in the number of sites requiring javascript that update without page refreshes. This imposes accessiblity issues that weren’t addressed by WCAG 1, as those specifications were written when “sites must work without javascript” was a reasonable accessibility specification. With the increase of web based “applications” (versus “sites”) requiring JavaScript, and improved support of javascript in assistive technologies, new accessibility issues have emerged. ARIA attempts to handle some of those issues. Through the inclusion of roles, states and properties your dynamically generated content can be made accessible to assistive technologies. Additionally, static content can be made more accessible thru these additional, enhanced semantic cues.

Why use ARIA?

By including ARIA accessibility features on your website you are enhancing the accessibility of your site or application. By including roles, states and properties, ARIA enables the developer to make the code semantically richer for the assistive technology user. ARIA enables semantic description of element or widget behavior and enables information about groups and the elements within them. ARIA states and properties are accessible via the DOM.

Similar to including the title attribute, ARIA is purely an enhancement and will not harm your site in any way. In other words, there is no valid reason to not include these features! DojoTools currently supports ARIA. Now that IE8 and Firefox 3 (both in beta at the time of this writing) support ARIA, the other JavaScript libraries should soon follow suit.

The easiest to include and most important properties of ARIA are the inclusions for the role attribute, and inclusion of states and properties.

How to incorporate ARIA

  1. Use XHTML the way it was meant to be used wherever possible. Limit ARIA usage to augment XHTML: only use it when XHTML does not support all the semantics required .
  2. Apply ARIA the role attribute in cases where the XHTML needs to be semantically enhanced and in cases where elements are being employed outside of their semantic intent. This includes setting up relationships between related elements (grouping)
  3. Set ARIA states and properties. Set the properties and initial state on dynamically and user changing elements. States, such as “checked”, are properties that may change often. Assistive technology that supports ARIA will react to state and property changes. role changes, on the other hand, may confuse the assistive technology
  4. Support full, usable keyboard navigation. Elements should all be able to have keyboard focus. I am not covering this here, but you can read up on this at For a more in-depth understanding of keyboard navigation see ARIA Best Practices
  5. Make the visual user interface visually match the defined states and properties in browsers that support the ARIA CSS pseudo-classes.

The ARIA role attribute

The role attribute enables the developer to create semantic structure on repurposed elements. While to a sited user, the above example of a span repurposed as a checkbox is not noticeable, the role attribute makes this seemingly non-semantic mark up accessible, usable and interoperable with assistive technologies. Two notes about roles: 1) once set, a role should not be dynamically changed, since this will confuse the assistive technology, and 2) roles take precendence over element default semantic meaning.

Example: Your designer insists that they want the checkboxes on your page to look a certain way. “Impossible” you say. You know that you can use CSS to make a span look like a checkbox. The sited user would never know that your weren’t using <input type="checkbox"...., but for accessibility concerns, you know a screen reader user will not know it’s a checkbox. With the ARIA role attribute included in your code, a both a browser and screen reader that support ARIA, you can make your repurposed span accessible with:

Of course, this case makes me cringe, since it doesn’t work without javascript and it is not inherintly semantic. However, if you are creating a web application requiring javascript, and you are coding this when browsers actually support ARIA, then you gotta do what you gotta do. If you include spans transformed into checkboxes, you will need to include equivalent unobtrusive onkeydown and onclick events.

Implementation of the ARIA role attribute

<ul role="navigation">

  <li><a href="mypage.html">My Page</li>
  <li>....</li>
</ul>

Values for the ARIA role attribute (For descriptions, roll over the items below)

Note: when i have time to populate a dB, i will add a little ajaxian explanation as to the possible parents and children of each role. In the meantime, please visit WAI-ARIA Roles.

ARIA states and properties

Whereas roles are a static attribute of elements, states are properties that can change with user and server interactions. Properties include both dynamic states that need to be updated, and static properties, such as “required”.

Values for the ARIA States (For descriptions, roll over the items below)

Values for the ARIA Properties (For descriptions, roll over the items below)

Certain properties belong with certain roles. For example, autocomplete makes sense with the roles combobox and textbox. The value of the property or state is also limited to certain value types. In our autocomplete example, the value would need to be selected from a list of predetermined values, whereas a checkbox could have a state of invalid, disabled, required or checked, to name a few, with a bolean as the value.

Working with ARIA in Rich Internet Applications

ARIA and Live Regions

Live regions are sections of a web page or application that change dynamically either thru automatic updates or user interaction.
There are 5 properties specific for Live Regions:

Politeness levels: Should ARIA intrude on the user on updates?

The value of the “live” state are expressed in terms of “politeness” levels. “Polite” regions notify of updates but do not interrupt users, and updates take low priority. A level of “rude” would indicate that the assistive technology should interupt the users current action to provide update information. A good example of using a polite level would be the ticker on a financial page — the user does not need to be interupted every 10 seconds to be informed as to whether a stock value has change. An example of a time to use a “rude” level is when the user has completed a step in a checkout process and the next step is visible. Values: Off, Polite, Assertive, Rude.

Validating your XHTML when including un-speced attributes

This section is not finished
There is a tweak that you need to make in your XHTML page if you include ARIA: you need to use XHTML 1.1 and include the ARIA module in your header area. XHTML 1.0 does not support modularization. The ARIA States and Properties attributes will be understood by user agents in XHTML 1.0 by declaring and using the appropriate namespace the same as for XHTML 1.1, but such documents will not validate to the XHTML 1.0 DTD. None of the DTD snippets below enable validation, but I will update when the modules and/or specifications are updated:


xmlns:aaa=”http://www.w3.org/2005/07/aaa” lang=”en”>

Notes:

  • ARIA and HTML: HTML 4.01 is non-extensible, so you can’t use namespaces for the property and state names. Please view the specs as they become available to see the HTML 4.01 support for ARIA.

Note: This blog is still in development, but it’s come a long way, and it is likely already a bit helpful. I will be adding more example snippets and more about live regions and handling dynamic changes, so come back next week if you want to read more. The original post was 03/12/08 but I’ve reposted it since WAI-ARIA is finally being better supported by YUI, Dojo, jQuery, IE8, Safari 4, and other browsers.

 
 

Beginning AJAX using the YUI Library May 19, 2007

Filed under: AJAX, JavaScript, Web Development — Estelle Weyl @ 6:15 pm

This is a real into level tutorial. The target audience for this entry is people who find http://developer.yahoo.com/ a bit overwhelming. If you think it’s a cinch, this will be below your level. If you want a more detailed intro than what they have on the YUI site, then continue on.


Preparation Step:
Create a text file and save it at include.html. Include some basic html in this page.

<h1>Hello World</h1>
<p>This is my first AJAX call</p>

Now, let’s set up our first AJAX web page using the YUI library. Our page will simply include the content from include.html when a button is pressed. Let’s begin….

Step 1: Start a new XHTML document with a typical template:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>My First Ajax using the YUI Library</title>
</head>
<body>
</body>
</html>

Step 2: Adding script calls to include the YUI library components we will be using.

<script src="http://yui.yahooapis.com/2.2.2/build/yahoo/yahoo-min.js"
   type="text/javascript"></script>
<script src="http://yui.yahooapis.com/2.2.2/build/connection/connection-min.js"
   type="text/javascript"></script> 

Notes:

  • As we discussed in the earlier blog entry "Including Javascript in XHTML , you must include the type attribute, but do not include the language attribute.
  • While in production you should put these calls at the end of your body, for this exercise, go ahead and put these in your header (after the meta character type and the title).
  • These scripts include minimized versions of the YUI library. Minimized means that the code base was minimized, with extra characters, comments and spacing removed. This makes the file smaller so the bandwidth is less, but it makes it human un-readable. The full version can be downloaded from The YUI distribution library.

Step 3: Create a <div> with an id in the body of your page and a link that will call the AJAX function. The div will be filled with the response from our AJAX call. Include an onclick event handler in the link. There will be another tutorial soon on using the YUI event utility to dynamically include event handers (separating presentation from the content). Make sure that the link’s href leads to a real page. Web standards and accessibility guidelines state that all links should really be links!

<div id="mydiv>
</div>
<p><a href="/include.html" onclick="callAJAX(); return false;">
    My first AJAX</a></p>

Step 4: Add a script tag to your page. This is where we are going to put all the javascript AJAX functionality

<script type="text/javascript">
  //<![CDATA[  		

  //]]>
</script>

This is what we have thus far:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>My First Ajax using the YUI Library</title>
<script src="http://yui.yahooapis.com/2.2.2/build/yahoo/yahoo-min.js" type="text/javascript"></script>
<script src="http://yui.yahooapis.com/2.2.2/build/connection/connection-min.js" type="text/javascript"></script>
</head>
<body>
<div id="mydiv">
</div>
<p><a href="/include.html" onclick="">My first AJAX</a></p>

<script type="text/javascript">
//<![CDATA[

//]]>
</script>
</body>
</html>

Save your file as myfirstajax.html. The script we write will be added between the CDATA open and closing tag. For more on why we use CDATA, refer to the entry on how to Include Javascript in XHTML. If you prefer, you can make a single external javascript call and add everything to that external file. If you open it up in a browser all you should see in one link that reads "My first Ajax". The page should validate.

Step 5: Add the YUI Connection Manager utility line of code that initiates an asynchronous transaction. Put this line of code in your javascript:

var transaction = YAHOO.util.Connect.asyncRequest('GET', sUrl, callback, null);

Explanation:

  • The YAHOO.util.Connect.asyncRequest method starts an XMLHttpRequest. It returns a transaction object that has properties that you can use, including status, responseText, responseXML and tId.
  • The first argument is the HTTP method. We will cover POST and GET. The YUI connection manager also supports other HTTP methods, but POST and GET are the most common. Think of the XMLHttpRequest as a form submission: choose the HTTP method the same way you would choose a form submission method.
  • The second argument is the URL to which you are submitting the XMLHttpRequest. Think of it as a form action. It is the response page we are requesting.
  • callback, the third argument, is a series of functions that we will define to handle the server response.
  • The fourth argument is only used if the first method is 'POST'. Since we are using 'GET', we can set it to null or omit it. If we were using POST, the fourth argument would accomodate our POST message.

Step 6: Define the second parameter: the URL.  The second parameter needs to be set to the URL of the file we want to interact with asynchronously.  In this case we are simply going to include our static page — include.html — created in the preperation step before step 1.

var sUrl = "include.html";

Step 7: Define the third argument: the callback. We’ll add alerts so you can test at this point to see if it works. We’ll replace the success function after we test to see if everything is working thus far. success is the handler code that executes when the XMLHttpRequest is successful. failure is the handler code that executes if the XMLHttpRequest is unsuccessful.

  var callback = {
     success: function(o) {
        alert("AJAX Works"); //SUCCESS
        },
     failure: function(o) {
        alert("AJAX doesn't work"); //FAILURE
     }
  } 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>My First Ajax using the YUI Library</title>
<script src="http://yui.yahooapis.com/2.2.2/build/yahoo/yahoo-min.js" type="text/javascript"></script>
<script src="http://yui.yahooapis.com/2.2.2/build/event/event-min.js" type="text/javascript"></script>
<script src="http://yui.yahooapis.com/2.2.2/build/connection/connection-min.js" type="text/javascript"></script>
</head>
<body>
<div id="mydiv">
</div>
<p><a href="/include.html" onclick="callAJAX(); return false;">My first AJAX</a></p>

<script type="text/javascript">
//<![CDATA[

var sUrl = "include.html";
var callback = {
success: function(o) {
alert("AJAX Works"); //SUCCESS
},
failure: function(o) {
alert("AJAX doesn't work"); //FAILURE
}
}

var transaction = YAHOO.util.Connect.asyncRequest('GET', sUrl, callback, null);

//]]>
</script>
</body>
</html>

Step 8: Save everything and upload both include.html and myfirstajax.html into the same directory on your server. Open http://www.yourserver.com/yourfolder/myfirstajax.html in a browser. If you have an error in your code or didn’t load include.html and myfirstajax.html into the same directory, you’ll get the ""AJAX doesn’t work" alert. If you copy the code in the box above, and uploaded both files correctly into the same directory on your server, you will get the "AJAX Works" alert. If all is good, continue.

Step 9: Our goal for this project is to make the content from your external file
include.html appear on your page. We’ve created a connection to our file. We created a place holder div in step 3 with <div id="mydiv>
</div>
. We are going to target this div, and insert the content from include.html into the div with innerHTML.

Replace

 success: function(o) {
	alert("AJAX Works"); //SUCCESS 
    },

with

 success: function(o) {
    	document.getElementById(’mydiv’).innerHTML =  o.responseText;
    },

The left hand side of the above statement uses the DOM to target the content of mydiv.  The function takes the responseText value of the transaction and replaces mydiv’s innerHTML with the content retrieved by the XMLHttpRequest. Save, upload and test again!

Step 10: The power of AJAX is being able to make a XMLHttpRequest and altering the content of the page once the page is already loaded. Let’s change our code so that instead of loading include.html while we load the page, we load it dynamically when we click on our link. We included the onclick event handler in the link in step 3.  In a future tutorial we will use the YUI event library to dynamically attach an event handler to our link, thereby seperating content from presentation.

Encapsulate the javascript into a function.  Our onclick event handler in step 3 reads <a href="/include.html" onclick="callAJAX(); return false;">, so we will call our function callAJAX().

function callAJAX(){
	var sUrl = "include.html";
	var callback = {
		success: function(o) {
			document.getElementById(’mydiv’).innerHTML =  o.responseText;
			},
		failure: function(o) {
			alert("AJAX doesn’t work"); //FAILURE
			}
		} 

	var transaction = YAHOO.util.Connect.asyncRequest(’GET’, sUrl, callback, null);
} 




The return is included in the eventhandler, so we don’t need to add it to the function. You could also have written the event handler as:

<a href="/include.html" onclick="return callAJAX();">

and added the return to the callAJAX function right before the function close:

 var transaction = YAHOO.util.Connect.asyncRequest('GET', sUrl, callback, null);
	return false;
	}

Test the AJAX file