Web accessibility means designing and developing websites and technologies so that people with disabilities an other limitations can use them.
Keep in mind: no site will ever be 100% accessible, but we aim for that goal.
# Web Content Accessibility Guidelines
The WCAG exists to help create a shared a standard when it comes to web accessibility.
### Four WCAG principles
- Perceivable: Information and UI must be able to be perceived.
- Operable: UI and navigation must be fully operable.
- Understandable: Users must be able to understand any UI or information presented.
- Robust: Content must be accessible by a variety of user agents, including assistive tech.
### WCAG conformance levels
- A: essential support.
- AA: ideal support.
- AAA: specialized support. Isn't recommended for entire sites.
# Semantic HTML
Use HTML elements for their intended purposes (e.g. `<button>` for buttons, `<header>` for headers). This helps assistive tech understand the structure of content.
As useful as `<div>` and `<span>` elements are as generic containers, they're not the most a11y friendly.
If a user is meant to click something, whether it's an actual button or not, you will usually want to use a `<button>` element.
If you want to provide some sort of tabular data, use a `<table>` element, along with related elements.
When you use an input element, you should always create a relationship between it and a `<label>` element. It provides context thats announced along with the input. It also increases the clickable area of the input itself. There are two ways to create this relationship:
```html
<!-- Useful when you need the input itself to have an ID -->
<label for='name'>Name</label>
<input type='text' id='name' />
<!-- Look, Ma, no ID! -->
<label>
Name
<input type='text' />
</label>
```
Additionally, inputs should always use the `type` that makes the most sense.
When you want to present a list to a user, you should use the appropriate element (`<ol>`, `<ul>`, `<dl>`) and their related list item elements.
### Headings and landmarks
`<h1>` to `<h6>` elements indicate headings. Landmarks acts as regions on the page.
By properly using landmarks and headings, you provider assistive tech a more operable and understandable page.
There are seven landmark elements: `<aside>`, `<footer>`, `<form>`, `<header>`, `<main>`, `<nav>`, `<section>`.
![[html-landmark-elements.png]]
# Accessible colors
Ensure enough contrast ratio, the difference in brightness between two colors. Use tools like the WebAIM Contrast Checker to validate.
Level AA requires a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text.
Level AAA requires a contrast ratio of at least 7:1 for normal text and 4.5:1 for large text.
Do not use color alone to convey information. Some people have total color blindness, or achromatopsia.
# Keyboard navigation
Some users rely solely on a keyboard or another assistive tech to operate their computer.
Proper `<button>` elements are focusable and have event handling for keyboards by default: pressing space or enter while a button is focused will trigger the "click" event.
You should never completely remove focus styles. Focus styles give keyboard users a visual indication of which element is focused.
```css
/* Never completely remove focus styles, like below. */
*:focus {
outline: none; /* No! */
border: none; /* Bad! */
}
```
### Tab order
The tab order is the order in which elements on the page will receive focus when pressing the tab key. By default, it's in the same order as the order of elements listed in the HTML file.
Use `tabindex` to manage focus order.
Make sure the visual order match the tab order. The best way to do this is to just have the elements in your HTML file match the order in which they receive focus.
### Hidden content
When you visually hide content, such as a menu or modal, make sure the content is hidden from assistive tech as well.
One way to do this is give the hidden content a `tabindex` value of -1. However, this might still be accessible to some assistive tech.
A better solution is giving the container for the hidden content either `display: none` or `visibility: hidden` CSS property.
# Meaningful text
### Links
Follow these rules when adding links to a page:
- Make sure the text content of the `<a>` element indicate where the link redirects to and that it's brief— avoid using phrases like "click here."
- If a link would open or download a file, include text that tells the user what kind of file as well as the file size.
- If a link would automatically open in a new tab or window, indicate that to the user.
### Forms
Provide meaningful errors to users when filling out or submitting a form. Include as much information as possible to help them rectify the issue. For example, include an example of a valid input or the validation rules that were not met.
### Alternative text
Use the `alt` attribute for images. If the image is purely for decoration or unimportant, you generally don't want assistive tech made aware of it and should use an empty string: `alt=''`.
# ARIA (Accessible Rich Internet Applications specification)
The purpose of ARIA is to define a way to make web content more accessible when native HTML is unable to do so
ARIA can be extremely powerful, but it can be equally dangerous when used incorrectly. Therefore, **no ARIA is better than bad ARIA.**
### The five rules of ARIA
- Always use native HTML elements and attributes over ARIA when possible.
- Never change native semantics, unless you have no other choice.
- All interactive ARIA controls must be usable with a keyboard.
- Never use `role='presentation'` or `aria-hidden='true'` on focusable elements.
- All interactive elements must have an accessible name.
### The accessibility tree
The accessibility tree is based on the DOM. While the DOM represents nodes and objects that make up a web page, the accessibility tree contains only the accessibility related information that will be used by assistive tech. ARIA works by modifying properties of the objects of the accessibility tree.
- Name: The "accessible name" is what assistive tech announce to a user and what separates elements of the same type from one another. The name may be set by one or more native labels, including the text contents of an element, the `<label>` element, or the `alt` attribute, to name a few.
- Description: This is what assistive tech announce in addition to its accessible name.
### ARIA labels
ARIA labels help users of assistive tech better understand the context on a web page by overriding native labels or providing additional descriptive text.
###### aria-label
The `aria-label` attribute overrides any native label of an element and modifies its name property in the accessibility tree. It is best used when an element doesn't already have a native label.
A common use for `aria-label` can be found in the "close" button of modals. Instead of a screen reading announcing, "X, button", it would announce, "Close menu, button".
```html
<button type='button' aria-label='Close menu'>X</button>
```
Another use case is on landmark elements. Once a screen reader reaches the below HTML, it would announce "Main navigation, navigation landmark".
```html
<nav aria-label='main navigation'>...</nav>
```
Do not use `aria-label` to change how a word is phonetically announced. That "fix" could make no sense to other assistive tech, like a braille reader.
###### aria-labelledby
The `aria-labelledby` references another element that labels the current element. It overrides both the native label and the `aria-label` attribute.
The below example would announce the button as "Shirts, Buy, button"
```html
<!-- Here's the labelling element -->
<h2 id='label'>Shirts</h2>
<!-- And here's the labelled element. Note the order of the ID references -->
<button type='button' id='buy-btn' aria-labelledby='label buy-btn'>Buy</button>
```
###### aria-describedby
`aria-describedby` references another element that provides a description for the current element.
The below example would announce the input element as, "Password, edit protected, password must be at least ten characters long."
```html
<label>Password:
<input type='password' aria-describedby='password-requirements'/>
</label>
<!-- Meaningful text + ARIA! -->
<span id='password-requirements'>Pw must be at least 10 characters long.</span>
```
### Hiding content from the accessibility tree
Use `aria-hidden` to hide elements, such as decorative images, from the accessibility tree. Note: the element will remain visible to sighted users.
```html
<!-- Announces: "Add add book, button" -->
<button type='button'>
<span class='material-icons'>add</span>
Add Book
</button>
<!-- Announces: "Add book, button" -->
<button type='button'>
<span class='material-icons' aria-hidden='true'>add</span>
Add Book
</button>
```