Accessible Rails Apps – Images and Alternative Text

Posted by Brian in Accessibility, Rails, Usability (July 3rd, 2009)

Many types of users make use of alternative text for images. Users who use screen reading software rely on those tags to describe the images they can’t see. Mobile users with slow connections or ‘pay by the minute’ plans often times turn off images to speed up the process.

Rails does something a little crazy with the image_tag helper… it automatically generates the ALT tag, which is just a horrible horrible idea.

  <%= image_tag "rails.png" %>

generates

  <img src="/images/rails/png" alt="rails" />

This is an absolutely awful idea, and I presume this was done just to shut up the XHTML Transitional validator which will complain if you leave ALT text off of your image elements.

You shouldn’t be adding ALT text to images to satisfy a validator. You should be doing it because it’s The Right Thing To Do.

ALT text is designed to describe the image, to be an alternative to the image. So, when placing the image on the page, take a few seconds to describe what it is.

  <%=image_tag "rails.png", :alt => "The Ruby on Rails Logo"
  <%=image_tag "banner.jpg", :alt => "Awesome Consulting Services - We Make Websites" %>

And for goodness sakes, please don’t prefix your description with “An image of…”. Screenreaders and other devices will make it completely clear to us that the content is supposed to be an image.

Some images convey more information than the ALT may allow, and so we’ll talk about that next.

Accessible Rails Apps – Rails Links, REST and JavaScript Hidden Forms

Posted by Brian in Accessibility, Rails, Usability (July 1st, 2009)

This is the first in a series of articles on developing accessible Rails applications. Accessibility is really important to me as I spend a lot of time working on web sites and applications that need to adhere to Section 508 guidelines. Making web sites accessible is also the Right Thing To Do.

JavaScript and Accessibility

When developing Rails applications, I try really hard to develop the entire application without using JavaScript, since a lot of users who rely on screen reading software can experience problems with AJAX, so these people tend to disable scripting. Using a screen reader is a lot like looking at a web page through a paper towel tube. You can’t see the whole thing at once, and it’s not likely that you are going to see something changing on the screen, and I’ve never come across screen reading software that can really let you know when a section of the page has been replaced. It might tell me that the content has changed, but I have to make it read the whole page back to me again and figure out what happened. Popup advertisements add to the problem, so people tend to just turn of the JavaScript completely.

Accessibility doesn’t just mean the users with disabilities, though. It can also mean those BlackBerry users who have horrible JavaScript support. So, what we’re really talking about is the age-old idea of “progressive enhancement.” Make a low-tech version work first, then spice it up.

Rails and REST

When you develop Rails applications and you’re working to keep your applications adhering to a RESTful design, certain URLS can only be accessed by certain methods. For example, to delete a record, you’re supposed to send a DELETE request to the destroy action of the controller.

Web browsers can only do GET and POST requests. GET requests are only supposed to read data, and POST requests are intended to change data. You POST to create something. Rails uses hidden form fields to emulate the DELETE and PUT methods.

However, Rails allows you to build links that can do other types of requests, like the DELETE request that’s planted in the default scaffolding. Honestly this is one of the single biggest mistakes the Rails core team has ever made. Here’s why:

This code:

  <%=link_to "Delete", project_path(@project), :method => :delete %>

actually produces a hidden HTML form. When you click this link, it actually submits the hidden form. This requires JavaScript to run and also mixes behavior with HTML markup. It’s a truly ugly situation that really should never be used.

A simple solution

The simple solution is to use the button_to helper instead. It generates the same form, but requires no JavaScript to activate it.

  <%=button_to "Delete", project_path(@project), :method => :delete %>

But I don’t want a button!

You don’t have to have one. As Tore Darell points out on his blog, the appropriate way to handle this is to do the opposite of what Rails was doing. You build the form yourself using button_to, but use unobtrusive JavaScript to replace the form with a link, by simply hiding the form, adding an observer to the newly created link which submits the form.

Add this to your application.js file to replace all of your button_to instances.

document.observe('dom:loaded', function(){
  $$('form.button-to').each(function(form){
      var link = new Element('a', {href:'#', 'class':'button-to'});
      link.update(form.down('input[type=submit]').value);
      link.observe('click', function(e){
        e.stop();
        form.submit();
      });
      form.insert({after:link});
      form.hide();
  });
});

Tore got it right, and the Rails team got it wrong. This solution is great because

  • It’s accessible. With JS disabled, the buttons will work and perform the appropriate actions.
  • It’s clean. The JS is unobtrusive. It’s not intermixed with your code, and it doesn’t use DOM Level 0 “onclick” which, in some instances, is considered deprecated or invalid markup.
  • It makes it look like a link without the need to resort to crazy CSS antics.
  • A single fix replaces all occurrances. You’re not generating duplicate JavaScript code all over your views like you would with link_to :method => :delete.

Replacing a single instance

You can replace button_to instances that contain a specific class if you simply wrap the JavaScript code in a simple if... block:

   <%=button_to "Dismiss", user_message_dismissals(:message_url => message.id), :class=>"dismissible" %>

    if(form.descendants().any(function(element){ return element.hasClassName("dismissible")})){
         var link = new Element('a', {href:'#', 'class':'button-to'});
         ...
    }

And I’m sure there are better ways to do that, too.

That’s it for now. I welcome your comments and suggestions on this topic and others.

IE Web Developer Toolbar?

Posted by Brian in Accessibility, Browsers, web (April 24th, 2007)

There’s a toolbar for Internet Explorer that has many of the same features as Firebug for Firefox.
Visit http://www.microsoft.com/downloads/details.aspx?familyid=e59c3964-672d-4511-bb3e-2d5e1db91038&displaylang=en to get a copy of the current beta.

To launch it, start IE7 and go to Tools -> Toolbars -> Explorer Bar -> IE DOM explorer.

You can inspect the DOM, the HTML elements, the CSS, and much more. It’s great to have this available!

Is XHTML bad for you?

Posted by Brian in Accessibility, Browsers, News, web (April 17th, 2007)

What do you do when you are confronted with the possibility that everything you know is wrong, or that you’re doing things not because they’re good, but because everyone else is doing it?

It seems that there are issues with using XHTML instead of HTML, and I think this is something that any web developer needs to investigate further.

From the article:

If you’re a web developer, you’ve probably heard about XHTML, the markup language developed in 1999 to implement HTML as an XML format. Most people who use and promote XHTML do so because they think it’s the newest and hottest thing, and they may have heard of some (usually false) benefits here and there. But there is a lot more to it than you may realize, and if you’re using it on your website, even if it validates, you are probably using it incorrectly.

This website uses XHTML 1.0 Transitional, apparently incorrectly.

All links open in a new window.

Other links: