[The WebAIM Million](https://webaim.org/projects/million/) report presents a sad state of where the top one million websites on the web from an accessibility perspective. Even if you're not working on a top one million website, the lessons we can learn from the report are worth it.
In the table below, we see the most common accessibility issues and what percentage of the top one million websites exhibit the issue.
| WCAG Failure Type | % of home pages in 2022 | % of home pages in 2021 | % of home pages in 2020 | % of home pages in 2019 |
| --- | --- | --- | --- | --- |
| Low contrast text | 83.9% | 86.4% | 86.3% | 85.3% |
| Missing alternative text for images | 55.4% | 60.6% | 66.0% | 68.0% |
| Empty links | 50.1% | 51.3% | 59.9% | 58.1% |
| Missing form input labels | 46.1% | 54.4% | 53.8% | 52.8% |
| Empty buttons | 27.2% | 26.9% | 28.7% | 25.0% |
| Missing document language | 22.3% | 28.9% | 28.0% | 33.1% |
To me this is appalling. These are not complicated things to fix or automate a solution for.
This post will look at some of the problems and how to fix them manually. In a future post, we'll look at tooling to automate a11y testing.
## Manual fixes
The manual fixes require working with CSS and HTML. It also requires external tools and built-in browser developer tools.
### Low contrast text
The problem is that the lower contrast the harder it is to read. This is mostly a design decision... developers have less influence in the design of a page or app than designers do.
That said we can manually check the contrast of foreground over background text using tools like the [Contrast Checker](https://webaim.org/resources/contrastchecker/) or Deque's [Deque Color Contrast Analyzer](https://dequeuniversity.com/color-contrast).
The goal is to reach the following levels under the following conditions:
| Specification | Level | Normal Text | Large Text |
| --- | --- | --- | --- |
| WCAG 2.0 | AA | 4.5:1 | 3:1 |
| WCAG 2.0 | AAA | 7:1 | 3:1 |
| WCAG 2.1 | AA | 4.5:1 | 3:1 |
| WCAG 2.1 | AAA | 7:1 | 4.5:1 |
WCAG 2.1 AAA requires a contrast level of 3:1 for graphics and user interface components such as form input borders.
Large text is defined as 14 point (typically 18.66px) and bold or larger, or 18 point (typically 24px) or larger.
You can extract colors from the page you're viewing using extensions like [Colorzilla](https://www.colorzilla.com/chrome/) (available for Chrome and Firefox).
Since version 89, Chrome has a different algorithm for calculating contrast. In [New color contrast calculation - Advanced Perceptual Contrast Algorithm (APCA)](https://developer.chrome.com/blog/new-in-devtools-89/#apca) (part of what's new in DevTools for Chrome 89), the DevTools team explains what APCA is and how it works.
Since this is an experimental feature, I would hold off on using it until it's available in other browsers or becomes part of WCAG 3.0 or later.
### Missing alternative text for images
This one is another low-hanging fruit that can easily be fixed manually just by being careful.
When writing the code for an image, whether it's a standalone figure or a responsive image with multiple srcsets, add the `alt` attribute to the image, whether it's the default image for a responsive set or a standalone image.
```html
```
The following responsive image shows the inclusion of the `alt` attribute as a normal image would:
```html
```
This is as easy as it gets. There is no excuse why we can't add this when adding the tags, if we're writing HTML or templates for our CMS content, or when entering data into a CMS.
TO check that the alt attribute is present, you can do a global search for the images on the page and check that the `alt` attribute is present and has a meaningful value.
If you use `figure` elements with the optional `figcaption` child, you should still use the `alt` attribute in the `img` child. [Figure and figcaption – extended alternate text for screen readers?](https://www.hassellinclusion.com/blog/figure-figcaption-extended-alternate-text-screen-readers/) shows how different screen readers handle the figcaption attribute. the TL;DR is that the `figcaption` attribute is not a substitute for the `alt` attribute.
### Empty links
A lot of times when I see a link with no text, either because the author forgot it or because it includes an icon or an image like a social media icon.
```html
```
or
```html
```
The problem with this is that screen readers and assistive technologies don't have a way to derive context from the link alone. They use the content of the alt attribute as the content that they'll show the user.
According to Hidde de Vries:
> If you were to replace your image with a square, what would you write in the square for it to still be useful? Source: [Common accessibility issues that you can fix today](https://hidde.blog/common-a11y-issues/)
Leaving it empty is an option if that’s the most useful alternative for the image.
### Missing form input labels
39% of the 4.4 million form inputs identified were not properly labeled either via