Thinking about accessibility—a few tips to make a difference
June 19, 2021• ☕️☕️ 9 min read
While conducting an interview session, I asked a candidate about what web accessibility is, the answer was, “Isn’t it about aria-label?“. It made me smile. It wasn’t an unexpected answer. I have experienced the same replies many times while bringing this topic up casually over a cup of coffee chat.
I know where the root problem lies. I believe it’s the lack of awareness and knowledge about accessibility in general. It’s a mindset that we consider accessibility as an optional thing. Web accessibility is rarely seen as a part of acceptance criteria when writing Jira tickets.
Well, being a web developer, we can change this mindset. We can educate ourselves, spread awareness, share the guidelines. Together we can make the web more inclusive and accessible.
With the motivation aside, It’s time to look into a few tips that can quickly get you up and running with accessibility in mind. After all, it’s not that scary as you might have thought. Time to make a difference.
Table of Contents
- Use Semantic elements
- Don’t use divs for creating a button
- Use ‘skip to main content’ link
- Don’t forget the focus state
- Never miss the ‘alt’ tag on your image
- Link text should describe the purpose of the link
- No ARIA is better than Bad ARIA
- Implementing your custom UI widgets
- Use ‘lang’ attribute to define the language of the page, and element
- Use jest-axe to automate your a11y tests
- Use CSS to highlight the accessibility issues
- Using Icon only as button
- VisuallyHidden React component
- Color contrast
- Accessibility checklist
- Learn to operate VoiceOver on your Mac
- Use a11y eslint plugin as your dev dependency
- Use ARIA live regions to announce dynamic changes in the page
- Zoom up the page to 200% and see if you can still use the website
- Chrome/FireFox extensions
- Read articles on accessibility, follow blogs/newsletters
- It’s not only about the UI
Use semantic elements where possible
- Semantic elements are the ones that convey meaning to both the browser and the developer.
- They have some intrinsic role associated with them.
- Screen readers would announce their role to help visually impaired users navigate a page.
- The VoiceOver rotor in mac can list available
landmarks
,links
,headings
if the semantics elements are used. - Improves the page search ranking SEO.
- References:
Don’t use divs for creating a button
div
is not a semantic element, it doesn’t convey anything to the browser. It’s also non-interactive.- Adding a
role="button"
is not enough; it won’t make it keyboard accessible. - You need to add
tabindex="0"
to make it focusable. - The button element gets you all the aforementioned features for free.
- References: Use button instead of divs
Use ‘skip to main content’ link
- For users with some motor disabilities, it can be hard to navigate every link item before reaching the
main
content block. - Using the
skip to main content
link allows the users to skip the long navigation links, and land straight to the main content. - Put the
skip to main content
link at the top of the page, so that it can receive focus when theTab
key is hit. - References:
Don’t forget the focus state
- Focus indicator helps users figure out where they are on the page.
- It also benefits the users with short-term memory to discover where the focus is located.
- If you’re setting
outline: none
for the focus state, make sure to style this state to make focus clear and visible. - Aid in keyboard navigation as you can see a focus ring around interactive elements when tabbing.
- You can style the focus ring to improve aesthetics; it doesn’t have to be ugly.
- Can use :focus-visible
- References:
Never miss the ‘alt’ tag on your image
- Every image that has a semantic meaning should have a non-empty alt attribute value.
- If the image is used for presentational purposes only (Background gradient), you need to pass
alt=""
value. - Skipping the
alt
tag is not an option at all. - References:
Link text should describe the purpose of the link
- It’s like your promise to the users. Screen reader users rely on some shortcuts to bring up the links available on your page.
- Link text shouldn’t be ambiguous. For example,
click here
as link text conveys no meaning. Use meaningful description text. - Shouldn’t be too long. Long text can be hard to comprehend/remember and might miss conveying the actual purpose of a link.
- References: link text purpose (WCAG)
No ARIA is better than Bad ARIA
- Assistive technologies rely on the aria roles of the elements to convey semantics. It’s kind of a promise.
- Using a bad
aria
role can cause more harm than good. So choose it wisely. - Moreover, you don’t need to use a
role
while using semantic elements. Mostly all semantic elements have implicit roles. - References:
Implementing your custom UI widgets (e.g Modal/Tabs)
- If you’re implementing your own custom UI widget (e.g Modal/Tabs), I’ll highly recommend reading WAI-ARIA Authoring Practices and WCAG Techniques.
- This will help you to make informed decisions and avoid basic a11y issues.
- Take inspiration from open source libraries that take pride in keeping accessibility as their core feature. Reach UI, Chakra UI, Mentine, Reakit are some of the examples.
- References
Use ‘lang’ attribute to define the language of the page, and element
- Make sure to use
<html lang='prefered-language-of-your-users'>
. For example,<html lang="en">
would set the language toEnglish
. - Allow assistive technologies such as screen readers to invoke the correct pronunciation.
- References:
Use jest-axe to automate your a11y tests
- If you’re using jest, it’s easy to automate the findings of basic a11y issues via jest-axe.
- For example, in React, you can create a test utility function like the following:
import { axe } from 'jest-axe';
/*
* @param {object} ui element
* @param {object} axeOptions jest-axe options
*/
const testA11y = async (element, axeOptions = {}) => {
const container = React.isValidElement(element)
? render(element).container
: element;
const results = await axe(container, axeOptions);
expect(results).toHaveNoViolations();
};
// And now can use it to test your component in jest like:
it('should have no basic a11y issues', async () => {
await testA11y(<YourReactComponent />);
});
- References: jest-axe.
Use CSS to highlight the accessibility issues
- For example, you can create a CSS selector to draw attention towards the issues. For example, draw a red outline if an image is missing an alt tag.
- And if a developer misses a rule, it would be clearly visible. Check the following examples:
/* All img tag must have alt attribute. For decorative images, provide empty value (alt="") */
img:not([alt]) {
outline: 2px dotted red;
error: All img elements should have alt attribute;
}
/* For tabpanl UI, the <ul> element should have the role of "tablist" */
.tab ul:not([role="tablist"]) { outline: 0.5em solid red; }
/* A elements that don't have a class get default styles */
a:not([class]) {
text-decoration-skip-ink: auto;
}
Using Icon only as button
- As Icon button has no visible text associated; it’s important to make sure the assistive technologies has a way to announce its name.
- There are multiple ways to do so. let’s one example as suggested by Sara Soudein
<!-- Using visually hidden text, accessible to screen reader -->
<button>
<svg aria-hidden="true" focusable="false" ...>
<!-- svg content -->
</svg>
<span class="sr-only">Menu</span>
</button>
and the ‘sr-only’ would be:
.sr-only:not(:focus):not(:active) {
clip: rect(0 0 0 0);
clip-path: inset(100%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
You can explore other techniques in this great article referenced below:
- References: Accessible Icon Buttons
VisuallyHidden React component
- You can easily create a reusable react component using the aforementioned sr-only css. It can also be a part of your component library.
/*
* This component will visually hide the content in the DOM, keeping it accessible
* for the screen reader user.
*/
const VisuallyHidden = ({ as: Component = "span", children }) => (
<Component className="sr-only">{children}</Component>
);
// And then you can use it like:
<VisuallyHidden as="h1">I am visually hidden h1 tag</VisuallyHidden>;
Color contrast
- It’s important to make sure that your UI has a minimum contrast ratio as described in WCAG guidelines.
- Not meeting the color contrast ratio can cause users to perceive your text incorrectly.
- If you are a developer, you can collaborate in the design process, and enforce this constraint before working on implementing the actual UI.
- References:
Accessibility checklist
- The following checklists can come in handy when you visually want to keep track of accessibility standards in your app:
- accessibility checklist from a11yproject team can be handy when it comes to keeping things in check.
- accessibility checklist from a11yEngineer
Learn to operate VoiceOver on your Mac
- Learning Mac’s VoiceOver tool is super easy. A few shortcuts and you shall be able to operate it in no time.
- Try using VoiceOver along with a keyboard to browse your website. You will be amazed to see how good or bad your accessibility ranking it.
Use a11y eslint plugin as your dev dependency
- Nothing is better than having a development tool that could warn you when your UI has some basic a11y issues.
- If your project uses React, eslint-plugin-jsx-a11y is a must-have dev dependency to help you along.
Use ARIA live regions to announce dynamic changes in the page
- Use aria-live to let the screen reader knows about the new content that would appear as of some user actions.
- Assistive technologies will announce dynamic changes in the content of a live region.
- Example would be an alert/notification that would appear when an action is completed.
- This is important to remember when you’re creating a SPA (single page application) where content changes without a full page reload.
- References:
Zoom up the page to 200% and see if you can still use the website
- Many users would zoom up your page to 200% or more, and your app should still be functional.
- Content shouldn’t overlap and your page should still be usable.
- Make sure interactive elements are still functional.
- References:
- WCAG Resize Text — Level AA success criteria requirement.
Chrome/FireFox extensions
- The following web extensions can help you identify a few of your web accessibility issues right from your browser:
Read articles on accessibility, follow blogs/newsletters
- The main issue behind so many inaccessible web apps is the lack of knowledge and awareness about the accessibility guidelines.
- You can invest some time learning about these standards and then sharing these with your teammates. You need to take the first step.
- I would recommend the following resources if you want to level your accessibility knowledge:
It’s not only about the UI
It’s not just the UI elements or usage of assistive technologies that correspond to accessibility, it’s also about your other web core vitals:
- Run lighthouse check and see how well your app is performing overall.
- Use code-splitting and lazy loading where possible to avoid sending unnecessary JavaScript.
- Don’t make too many requests on your first page load.
- Think about progressive enhancement and server-side rendering.
Conclusion
Starting a web developer career has become more of knowing about React, VueJS, and AngularJS. The advent of these frameworks has made creating a complex UI so easy that we’ve forgotten about accessibility guidelines. No doubt our developer experience has improved, but we have paid the cost of forgetting about vanilla JavaScript fundamentals, HTML native elements, and accessibility.
It’s the time we resurrect these existing standards and lay down our app using the principles that would make it inclusive and accessible. Accessibility is not optional, and as a developer, it’s our sole responsibility to make sure it won’t go unattended.
Written by Amandeep Singh. Developer @ Avarni Sydney. Tech enthusiast and a pragmatic programmer.