A Developer’s Nightmare: Web Accessibility

Mía Salazar
8 min readJul 7, 2020

It goes without saying that web accessibility is one of the biggest nightmares of developers. Indeed, it’s a very difficult and complex subject, especially if we are trying to build a website with a Level AAA accessibility conformance to Web Content Accessibility Guidelines 2.0.

Level AAA logo

For those wondering, a Level AAA conformance is the highest level of web accessibility conformance and it isn’t easy to achieve. For that purpose, here we expose some tips to have into consideration in order to build a AAA web without dying of boredom in the process.

Tab is important

Our website must be navigable with just the Tab key. What does that mean? A user should be able to navigate between focusable elements in the page pressing the Tab to go to the next element and Shift + Tab to the previous one. This allows users to surf our web without mouse or trackpad and improves the experience for blind users or users with motor disabilities, among others.

A navigable button with Tab key from Taylor Swift’s homepage, and its focused appearance

Nevertheless, does that mean that every piece of our code should be accessible with the tab? Not really, that would be very confusing. Only important components for navigation such as forms, inputs, menus, buttons or links need to be accessible with the tab key.

On the other hand, some HTML tags like <a>, <form>, <input>… “are implicitly focusable. That is to say, they are in the tab order automatically. However, for those who aren’t naturally added in the tab order, and are useful for the navigation, we can use tabindex.

Tabindex is a global HTML5 attribute. If the value is 0, the element that contains this attribute will be focusable and will be added to the tab order following the logical navigation order of the document. If the value is negative, the element will not be included in the tab order. However, you could still make it focusable with Javascript.

A focused input from Steam, inputs are implicitly focusable

Lastly, if the value is positive, it will define an explicit tab order. The bigger the number, the later it will be focused. However, changing the tab order using positive values is not recommended as it can be confusing and it forces you to give a value to every element that can be focused on a tabindex. Instead, it’s a better practice to reorder your layout.

One (bad) example:

<p>Not focusable element</p><div tabindex=”4">Not focusable element but forth on the tab order</div><label>Second in tab order:<input type=”number”></label><a href=”www.miasalazar.com” tabindex=”-1">Focusable element not included in the tab order</a><input type=”text” tabindex=”0"/>Tabbable element third on tab order<div tabindex=”1">Not focusable element but first on the tab order</div>

A better practice would be:

<p>Not focusable element</p><div tabindex="0">Not focusable element but first on the tab order</div><label>Second in tab order:<input type="number"></label><input type=”text” />Tabbable element third on tab order<div tabindex="0">Not focusable element but forth on the tab order</div><a href=”www.miasalazar.com” tabindex="-1">Focusable element not included in the tab order</a>

Additionally, the focus style should be key in the design process. If the organization doesn’t plan accessibility from the start, the website might end up with issues such as elements that are focused and don’t show any visual clue that are focused, among other bugs.

A focused element from Delish Vegan Donuts that is not displaying it’s focused

Semantic HTML

Writing HTML knowledgeably is pretty important because each tag gives information about what it contains. A <figure> will precede an image, a <main> specifies the main content of a page, a <nav> will introduce a list of navigation links… It might sound obvious, but if we use a <span> or a <p> for a link instead of an <a>, the browser or the screen reader would not identify that piece of code as a link.

Besides, creating a correct structure would help the browser (or screen reader) organizing the information. A meaningful structure with the most appropriate tag for each content can be pretty helpful.

Adalab has a nice structure using semantic HTML

Furthermore, wise use of heading tags (h1,h2,h3…) according to the importance of each text in the page not only shows a consistent text structure and helps the user to find information, but also helps search engines and improves SEO on a website.

Role, name, value, state

Elements should give information about what they are, what is their value, their name, and their status.

  • Role: The property role gives us an idea of what is the purpose of an element. For example, using the role ‘banner’ to introduce general information. However, semantic HTML can erase the need to use some roles, as tags such as form has its role intrinsic.
  • Name: Elements should have a name(or a label tag) when clarification is needed. For example, in a form with multiple inputs, each input should have a name indicating what is its purpose.
  • Value: Value is useful when we have a checkbox or a select. It gives a hint about the value of each one and helps the user select between all the options.
  • State: State gives information about which is the status of every element e.g. if it is checked, collapsed…
Freedom Cakes contact form doesn’t provide labels for its inputs, but it does indicates its names


Color contrast is a very important and easy issue. Text, images, inputs… They all should have a contrast ratio of 4.5:1 or more.

On the other hand, text that is larger than 18px or 14px with bold font-weight, should have a contrast ratio of at least 3:1.

Homer’s web page has a perfect contrast ratio

Descriptive Links

Most screen reader users use links to navigate websites, therefore, providing descriptive links gives information about where the link will lead them. A good link text will notify its purpose and won’t use generic terms such as ‘click here’ or ‘see more’, instead, it will tell you relevant information about the linked-to page. Some examples could be:

Besides, descriptive links also improve SEO performance.

Bethesda’s web page is not giving description to some of its links

Alt text

Alt texts’ primary purpose is to put into words the content of the image for screen readers or to sight-impaired users. If the picture doesn’t have an alt tag, it will read the file name. By default, all pictures should have an alt, at least one that is empty. The decision tree on how to use alt tags can be summed up in three cases:

  • If the <img> has only decorative purposes, the alt tag can be left empty (alt=””)
  • If the picture contains relevant information, it will need a descriptive alt
  • If the image is a link, it should describe its purpose and destination.

Besides, alt text is also important to SEO purposes

Star Wars’ website has good alt text


“Aria helps developers create more accessible websites, and it provides a lot of solutions for a wide range of issues. To sum up, ARIA mechanisms can add new semantics, modify the existing semantics, and express patterns or relationships.

Aria-label, aria-labelledby y aria-describedby

Aria-label is an attribute that is used to define a tag when text is not visible, for example, in a button that is employed to close a modal, and its texts is just an ‘X’.

<button aria-label=”Close”>X</button>

Aria-labellledby allows us to link elements and create a list. It might sound like aria-labelledby is the same as label, but it’s the opposite: a label tells us which is his children, and an aria-labelledby point who is its father. Besides, aria-labelledby doesn’t work as a label, for example, it doesn’t allow you to click on it and change the status of the checkbox, radio input, etc.

A clear example is this radio input

<p id=”movies”>Favourite movie</p><div role=”radiogroup” aria-labelledby=”movies”>  <label for=”starwars”>    <input type=”radio” name=”movie option” id=”starwars”>Star Wars  </label>  <label for=”zombie”>    <input type=”radio” name=”movie option” id=”zombie”>Zombieland  </label>  <label for=”basterds”>    <input type=”radio” name=”movie option” id=”basterds”>Inglourious Basterds  </label></div>

Aria-describedby tells us that an element is going to have a description, or additional information and where it’s providing this new data. For example.

<label for=”password”>Password:</label><input name=”password” id=”password” type=”password” aria-describedby=”passwordDescription” aria-required=”true” /><p id=”passwordDescription”>Password must 8 characters at least</p>

Aria relationships

As we said earlier, aria also allows us to show the relationship between elements.

Aria-owns is one of the most used aria technologies and it tells us that elements that may seem unrelated to others are actually children of them or are its secondary elements. Therefore, aria-owns is very useful when you want to indicate a hierarchy. For example, if you have a menu that opens another menu that is not inside the first one, you can use aria owns.

<div aria-owns=”second-menu”>First menu</div><div id=”second-menu”>Second menu</div>

Aria-posinset and aria-setsize work together to give an explanation about the relationship between elements, creating a list. Aria-setsize establishes the size of the set and aria-posinset specifies the position of one element inside a set.

<ul role=”listbox”>  <li role=”option” aria-posinset=”1” aria-setsize=”2”></li>  <li role=”option” aria-posinset=”2” aria-setsize=”2”></li></ul>


In some cases, elements that are displayed in the browser are not useful for other users, for example, those who use assistive technologies to surf the web. For these special circumstances, we can use aria-hidden. If it is set to true, the content will be displayed for the browsers but not for the assistive technology users.

Final Fantasy VII remake page uses aria-hidden in its shopping cart icon

Wrapping up

Creating accessible websites can be tricky, and teams have to take into consideration a lot of things, however, our responsibility as developers is to remove barriers from the web and help people to participate in the web equally.



Mía Salazar

I’m a Front-End developer that loves pizza, cookies, write and code