Overview
As your audience grows, it is important to ensure that your website or application can be used by everyone - specifically people with permanent or temporary disabilities. This is often referred to as accessibility (or A11y as an abbreviation), and is a requirement for all modern websites or applications.
In this post I wanted to give some of the specific A11y tips that you can add to your Ruby on Rails project to make it suitable for a large and diverse audience.
Images
No tutorial on A11y can ever be complete without mentioning images!
Images are great. However, if your users have a vision impairment and use a screen reader to read aloud the page, their user experience will vary greatly depending on how you have set up images.
First off, there are two types of images: functional and decorative:
1. Functional
This is any image on your site that is needed to use the site or contains important text. These should have a useful alt tag or similar so that information isn’t missed by someone using a screen reader. For example a company logo.
erb
<%= image_tag "company-logo", alt: "Company Name" %>
This also means that if your image doesn’t load for some reason (such as in a HTML email), the alt text will show instead:
Note: This is seperate to the title, which appears on hover.
erb
<%= image_tag "company-logo",
alt: "Company Name",
title: "Company Name" %>
2. Decorative
Any image on your site that is there only for appearance and is not needed to use your website is classed as decorative. In this case we don’t want the screen reader to read them out as it will clutter up the page and slow down the user. For these images the options are:
a) Displaying them as a background image in the CSS.
erb
body-background {
background-image: image-url("background-image");
}
b) Referencing them in the HTML with a blank alt tag (otherwise the screen reader may read the file name out instead)
erb
<%= image_tag "background-image", alt: "" %>
Aria Attributes
If you’ve improved the accessibility of a website, or copy and pasted in bootstrap components, chances are you’ve encountered aria tags.
These are custom tags you add to your HTML elements if they are doing something a bit out of the ordinary. They then notify the screen reader of the difference so the user can figure out what’s going on.
For example if you have a button on your website that when clicked it opens up a modal you can add the aria-haspopup
 to the button to let them know what is going to happen.
The gotcha here, though, is that embedded Ruby attributes don’t like hyphens, so if you add it in like this:
erb
<%= button_tag "Apply Now!",
type: "button",
aria-haspopup: true,
%>
You’ll get a big scary error with syntax errors like this:
syntax error, unexpected ‘:’
Similarly to adding data attributes with embedded Ruby, you need to get rid of the hyphen. You can do this either by putting it in quotes like this:
```erb <%= button_tag “Apply Now!”, type: “button”, “aria-haspopup”: true,
%> ```
Or by putting it into a hash, which is particularly useful if you adding more than one:
erb
<%= button_tag "Apply Now!",
type: "button",
aria: { haspopup": true },
%>
Unique titles
Page titles are extremely important as they are the first thing a user hears through a screen reader. If it is the same throughout the site, it will lead to a poor user experience as they will have to scan through the page manually (past all the top header and navigation again) to try and get a feel for what is on the page. It is also good practice for any robot users such as Google in order to improve your Search Engine (SEO) ratings.
This is the way I set it up with embedded Ruby tags in Rails, which allows it to be updated as you update the page.
In the application.html.erb
page set up the title like this:
```erb
```
Then in the individual pages you set it like this at the top:
erb
<% content_for :title, "Home page" %>
More can be added here for the SEO ratings. However, if it is too long, it will make it harder to get through with the screen reader. At that point it might be better to move extra keywords into other meta elements in the head.
Forms
Forms are the basis of any Ruby on Rails project. Luckily screen readers are expert at figuring out forms as they are fairly predictable when set up correctly with valid HTML5. The main tips are:
- Make sure everything is wrapped in a
form
- For every
input
, have a correspondinglabel
- Wrap related elements, such as a list of radio buttons, in a
fieldset
with a legend - Add in some form validation to help the user, such as adding in
required
attributes
Here is a basic Rails form that follows these tips:
erb
<%= form_tag do |form| %>
<%= form.label :name, "Full Name" %>
<%= form.text_field :name, placeholder: "Your full name", required: true %>
<%= form.field_set "Which are better cats or corgis?" do %>
<%= form.radio_button :pets, "cats" %>
<%= form.label :pets_cats, "Cats of course!" %>
<%= form.radio_button :pets, "corgis" %>
<%= form.label :pets_corgis, "Corgi's obviously!" %>
<%= form.radio_button :pets, "fence sitter" %>
<%= form.label :pets_both, "All animals are great" %>
<% end %>
<% end %>
If you want to have some inputs without labels, the best practice here is to keep it in the HTML so it is still read out with the screen reader, and then hide them from view with CSS.
Note: Do not use display: none;
to hide elements as that removes them from the page and the screen reader won’t pick it up at all.
erb
<%= form.label :name, "Full Name", class: "sr-only" %>
.sr-only { position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;}
Ruby gems?
So by now you’re probably thinking ‘surely there’s a gem to fix all of this?’ Unfortunately, not that I have found. There are a few out there doing bits and pieces but most are fairly small and not currently maintained. Even trying to find a gem to validate HTML output was tricky as they seem to like either pure HTML or ERB tags, but not both. For example gem w3c_validators
doesn’t work unless you escape all <%= %>
.
Conclusion
I hope that has given you an idea of some ways to include a11y into your Ruby on Rails project. If you want to test out how your site sounds with a screen reader, check out out Voice Over if you are on a Mac and NVDA if you are on Windows. Both are free with great documentation to get you up to speed quickly.