A beginner's guide to building an accessible website
Tags: inclusion, frontend, a11y, beginners
Published: 2023-10-10 13:23:16

## Why a11y is important to me as a developer

As someone who suffers from chronic migraines, I am particularly sensitive to bright colors, which can trigger migraines. Navigating applications without a dark mode option can **sometimes** pose a bit of a challenge for me, especially when I need to use them for extended periods. 
As I progressed in my development career, I became acquainted with web accessibility, It dawned on me that there are individuals who face persistent challenges accessing applications not just sometimes, but **every time** because their unique needs have been overlooked.

This realization led me to educate myself about disabilities and it became clear to me that every day is not always straightforward for people with disabilities. As a developer, I believe it is my responsibility to make sure that I create applications that are convenient for everyone, including people living with disabilities.

## Tips for building an accessible Platform

Using the appropriate semantic elements in HTML can act as a guide for visually impaired users to navigate a website. HTML provides a lot of semantic elements, and it is crucial to use them properly. Some types of semantic elements include:

**[List items](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/li):** When used correctly, HTML lists group-related elements and helps users with screen readers better understand the information presented. Examples are:
 `<ul>, <ol>, <dl>, <li>, <menu>`

**[Body structure](https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/Document_and_website_structure):** Instead of using `divs` to separate every section of your website, use the semantic element to give structure to your website or web application. Examples of the body structure include `<header>, <footer>, <main>. <nav>, <section>`.


Accessible attributes: HTML attributes are very important when building accessible web platforms. They can give more information about an element, especially for people using screen readers to access your platform. Some web-accessible attributes are: [aria](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA), [rel](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel), alt, role, title, and so on. 

**alt**: The `alt` attribute is an important tag in HTML that provides more information about the images used on a webpage. It is used by screen readers to describe the image to users. It is recommended to keep the alt text brief and to the point. If the image is purely decorative, then the alt tag should be left blank. Avoid using phrases like "image of" or "photo of" in the alt text, as these are already interpreted by screen readers.

An example of a descriptive image: `<img scr="cat.png" alt="a smiling cat" />`
An example of a decorative image: `<img scr="arrow.svg" alt="" />`.


> I created an image component in my React app using typescript to ensure that I always provide an alt text. I made it mandatory to pass the alt as a prop, so if I ever forget to add the alt attribute to my image, typescript throws an error and reminds me to add it.

```
interface ImageInterface extends HTMLAttributes<HTMLImageElement> {
  src: string;
  alt: string;
}

export const Image: React.FC<ImageInterface> = ({ src, alt, ...rest }) => (
  <img
    src={src}
    alt={alt}
    {...rest}
  />
);

export default Image;
```

**role**: The 'role' attribute does exactly what it says—it tells browsers and screen readers what an element does. It's like giving an element a specific job title. Always use the most fitting role possible, and avoid using generic roles like 'group' unless it's really necessary. Also, don't double up on roles; if something already has a clear description, let it be. e.g 

```
// Here is a wrong use of role: 
`<button role="button">Click me</button>`. 
// You're already using a button you do not need to add a role.


//This is a valid example of using the role: 
`<div role="button">
This div is now acting as a button
</div>`

```

### Keyboard Navigation.

When creating a web page or component, I prioritize smooth keyboard navigation to ensure a seamless user experience. If I encounter any challenges in navigating with a keyboard, I revisit my code and make the required adjustments. It's important to remember that some users rely solely on their keyboards to interact with your applications. Neglecting to test and optimize for keyboard navigation can create barriers for these users, hindering their experience with your platform. Therefore, it is crucial to ensure that keyboard navigation is seamless and user-friendly for all users. 


### Accessible Colors

I have visited some websites where it was quite difficult for me to navigate due to the color scheme. If you are not someone with a permanent color vision issue it is still important to understand how people perceive color and contrast. This will help you understand how to best support their visual needs.

For a comprehensive understanding of the color system and accessibility, refer to [this article by material.io.](https://m3.material.io/styles/color/the-color-system/accessibility). 

When working with colors it is important to understand the CSS media [@prefers-color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme) and  [@prefers-contrast](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-contrast). The linked MDN articles offer detailed insights on how to effectively utilize these features.


## Animations

Web accessibility goes beyond using correct HTML codes; it also involves considering the impact of animations on users. Personally, as someone prone to migraines, certain animations can trigger dizziness for me. If you've experienced motion sickness, be it in a car or on a boat, you can relate.

To address this concern, the @prefers-reduced-motion CSS media query comes into play. It checks whether users have enabled a setting on their device to minimize the amount of motion they experience.

```
.animated-element {
  animation: swing 1s linear infinite alternate;
}

@media (prefers-reduced-motion) {
  .animated-element {
    animation: none;
  }
}
```

It is also important to avoid flashing content which can be particularly frustrating for users with photosensitivity, frequent flashes also have the potential to trigger seizures.

In cases where flashing content is unavoidable, it's imperative to include a Flash Warning alert on your platform. This proactive approach ensures users are informed and can take necessary precautions while engaging with the content.

### Forms

When you're working with form elements and attributes, the default elements have very good accessibility support. But sometimes the styles are not very pretty and uniform across different browsers and we might need to create custom form styles. when building custom forms, it's essential to prioritize accessibility.

Ensuring that custom styles maintain accessibility standards is crucial. This guarantees that, despite the visual enhancements, users of all abilities can seamlessly interact with and navigate through the form.

Always add a focus style for your form so a keyboard user knows which field they're currently on, the HTML input element already has a focus style using an outline, I personally don't like that style so using [tailwind](https://tailwindcss.com/docs/hover-focus-and-other-states#focus) I would usually replace it with something like:

```
<input class="focus:outline-none focus:ring-1 focus:ring-slate-400" />
```

**Labels:** They are used to inform a user about the purpose of an input field. Do not replace the labels with placeholders as they serve different purposes. If a field is required a good practice is to add that to the label.

```
<label>Email address: 
<span>(required)</span>
<input id="email" type="email" autocomplete="email" required />
</label>
```

**Error handling:** When a user encounters a form error, we need to make the error known to the user in the simplest way possible, and offer suggestions on how to fix the error. 

## More accessibility tips:

- Use the appropriate semantic elements (e.g: don't replace your button with a div)
- Use appropriate attributes where required (e.g alt, [tabindex](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex))
- Use common fontface whenever possible.
- Use relative values for your base font sizes (e.g. %, rem) to allow easy resizing.
- Avoid using justified paragraph alignment `text-align: justify;`, It can create uneven spacing between texts.
- Add captions or transcripts to videos 

In my next article, we'll look at how to test your website for accessibility. 

If you found this article helpful, please like and consider sharing it with others who may also benefit.