Skip to main content

Web Accessibility Quick Guide

Welcome to my Quick Guide!

This is a guide focused on "old-style" websites, like those commonly found here on Neocities. There are a ton of guides on web accessibility out there (and I've linked to several of them on my Resources page!), but most of them are written with "modern and conventional" websites in mind. This guide is a work-in-progress, and I plan to add more sections over time!

This is not a comprehensive guide. My goal is to give you simple accessibility tips that you can use without wrecking your vision for your webpage. Fully following the Web Content Accessibility Guidelines (WCAG) would probably require bigger, more visible, and more complicated changes. I plan on making some tutorials later that go into more detail.

Broadly speaking, the guide is divided into two sections: tips that can be applied without changing the visual design at all, and tips that may require changing the design slightly. Of course, these tips will not cover every scenario. I recommend reading the glossary if any words or acronyms I use are unfamiliar.

Now, without further ado...

Glossary (click to expand)
ARIA
Stands for Accessible Rich Internet Applications . It's a set of tools for making webpages more accessible, mostly for people who use screen readers. The most commonly used tools for simple websites are labels and roles.
ARIA label
ARIA labels are attributes (defined below) that you can use to provide extra information to screen readers. Things like images and buttons can be given a label to describe their purpose.
ARIA role
Like labels, ARIA roles are also attributes that you can add to your HTML elements. You can give any HTML element an ARIA role. They help screen readers know what kind of content they are "looking" at. For example, using <div role="navigation"> will tell a screen reader that the <div> is a navigation menu.
Attribute
Used to add information or functions to an HTML element. For example, in a line like <img src="example_image.jpg">, src is an attribute that modifies the <img> element.
Element
The technical term for the HTML "building blocks" that you use to code a webpage. Things like <p>, <img>, and <div> are elements.
Interactive element
Elements that can be, well, interacted with. Things like links, buttons, and checkboxes. If you can click on it and it does something, it's interactive.
Keyboard focus ∕ focusable
You can move between interactive elements on a page using the tab key. Use tab to move forward and shift+tab to move backward. Most elements can be interacted with using either enter or space. Usually, an outline will appear around whatever element you're "standing" on. That element is called your current keyboard focus. "Focusable" means that focus can be moved to an element by tabbing to it.
Screen reader
A program that "reads" the contents of a webpage out loud. They're commonly used by blind people and by people who can't see very well.
Semantic elements ∕ semantic markup
HTML elements that clearly describe their function, not just how they look. Elements like <div> and <span> are not semantic; you can't tell what they're "for" just by the HTML tag. <nav> is a semantic element: you immediately know that anything inside that tag is part of a navigation section.
WCAG
Short for Web Content Accessibility Guidelines . It's a set of standards for web accessibility.

Part One: Invisible Fixes

Page Language

This one's super easy! The <html> element at the top of your page should have a valid lang attribute.

If your page is in English, a simple <html lang="en"> will suffice. If you change languages in the middle of a page for whatever reason (say, to use an idiom in another language), you should also wrap that in another element (such as a <span>) and give that its own lang attribute as well.

Why does my page need a lang attribute? (click to expand)

Screen readers use the lang attribute to decide which language's pronunciation rules to apply. If no lang is specified, the screen reader will use the default language its user set, which may or may not be English. If a screen reader tries to read text in one language using the pronunciation rules of another, the result is garbled nonsense! Imagine trying to read English, but pronouncing every letter as you would in Spanish. It would be almost impossible to understand.


Landmarks

Landmarks are used by screen reader users to figure out what section of a webpage they are in. People who use screen readers will often pull up a list of landmarks on the page and jump between them. Modern HTML has several types of landmarks built in, including <header>, <nav>, <main>, and <footer>, among others.

If you already have a layout that doesn't use those landmarks, you can also "retrofit" elements of your page using ARIA. For example, using <div role="navigation"> will add a navigation landmark. You can put your navigation links inside of that <div> and it will be the same as putting them in a <nav> element. Note, though, that using built-in (or "native") HTML landmarks is preferable to using ARIA.

Here's a table with a few common HTML landmarks and their corresponding ARIA roles. There are more landmarks than I've listed here; these are just the most common ones:

HTML5 ARIA Role
<header> role="banner"
<nav> role="navigation"
<main> role="main"
<footer> role="contentinfo"

Semantic Markup

People with sight can identify the purpose of elements on a page just by looking at them. If something looks like a heading, we can easily tell that it's a heading. If something looks like a list, we can easily tell that it's a list, et cetera.

People who use screen readers can't identify elements of a page by looking at them. That's why semantic markup is important: it tells screen readers what an element is and what it's for. Non-semantic elements like <div> and <span> convey no information. That doesn't mean you should never use these elements! It's just good practice to avoid them when appropriate semantic alternatives are available.

Anything that functions as a heading should be marked as a heading (<h1>, <h2>, <h3>, etc). Anything that functions as a list should be marked as a list using <ul> or <ol> and <li> elements. Landmarks (described above) are also semantic. There are a lot of other semantic elements, but headings, lists, and landmarks are probably the most important.

It's also important to not use semantic elements purely for styling. If you just want big bold text, you shouldn't use a heading tag. Screen reader users will often pull up a list of headings on a page and use them to navigate quickly. Text that's semantically marked as a heading but isn't actually a heading can be very confusing! In this case, using CSS is better.


Keyboard Focus

Every interactive element on your webpage needs to be focusable using a keyboard. Most interactive HTML elements are focusable "out of the box". If you're using custom JavaScript, you may have to do a bit more work. Note: Elements that aren't interactive (headings, paragraphs, etc) should not be focusable.

By default, using tab will focus elements in the order they're written in the HTML. You want to make sure that page elements get tabbed to in an order that makes sense. That usually means left-to-right, top-to-bottom. Make sure to avoid cases where the focus gets "stuck" on an element. That's called a keyboard trap. If someone is stuck in a keyboard trap, they won't be able to tab to any other element on the page!

Most browsers will default to showing a blue or dotted outline around the currently-focused element. Depending on your color scheme, that can be pretty hard to see. It's recommended (but not required) to create an extremely obvious style for keyboard focus using CSS.

At a minimum, please never remove the default focus styling (e.g. by setting a:focus {outline: none;}) without replacing it. If you do that, keyboard users won't have any way to tell what element they're currently focused on. That can make your website nearly impossible to use.

What about tabindex? (click to expand)

The tabindex attribute lets you manually change the tab order. Giving an element a tabindex of 0 makes sure that it is keyboard focusable. Using a tabindex of -1 will make it not focusable, which is sometimes useful.

You can also give things a positive tabindex (greater than 0). The tab order will follow the numbering: first 1, then 2, etc. Any element with a positive tabindex will come first in the tab order, before anything that doesn't have a positive tabindex. This means that if ANY interactive element on your page has a positive tabindex, ALL of them have to.

In 99.999% of circumstances, you shouldn't use a positive tabindex. Screen readers typically read things in the order they're written in the HTML. If you manually change the tab order of elements on the page, it can make the tab order not match the order they're read by a screen reader. That can make webpages very confusing and hard to use. Tabindexes are also really hard to maintain because you'll have to change them all every time you add something new to your website.


Tables

Tables that are used to display data or information should have proper semantic markup. This can get complicated, and there are plenty of guides on it, so I won't go into detail here. The most important thing is to use an actual <table> element instead of "faking it" using <div>s. Use <th> for table headers and <td> for regular table cells.

Important: If you use <table> elements just for arranging things on a page (not for displaying data), they should not use data table markup. That means you need to avoid <caption>, <summary>, <th>, scope, and headers. They should also be given an ARIA role atrribute: <table role="presentation">. The "presentation" role makes screen readers ignore the table and treat it as regular text instead.


Image Alt Text

Still working on this section!


Part Two: Somewhat Visible Changes

Page Title

This one won't change the design of your page, but it will affect how its title is displayed in a browser tab. Every page should have a meaningful <title>. This should be placed inside the page's <head>. If the URL changes, the title should change, too. Try to make your titles unique and short. If you use a title style (like I do) that includes both the title of the page and the title of your website, you should place the title of the page first. That makes moving between browser tabs much simpler.


Navigation menus should be put in a <nav> element or a <div role="navigation">. It's a good idea to use a list (<ul> or <ol>) inside the <nav> for your navigation links. That will make them easier to use with a screen reader. WCAG also says that you have to keep the list of links the same on every page, but if doing that would break the design of your site, I won't be mad if you don't. <3

If you have a navigation bar at the top of the page (or a navigation sidebar that comes before the page content in the HTML), it's a good idea to include a keyboard-functional "skip navigation" link at the very top. You can make it completely invisible unless focused with a keyboard. This website has one, and you would never know it unless you use a keyboard! Just refresh the page and then press tab to see mine. Making a hidden link can be a bit complicated, so I recommend following a tutorial online. (I might make one later.)

Why add a "skip navigation" link? (click to expand)

The point of a "skip navigation" link is to let keyboard users jump straight to the main content of your page. It's basically there to make your website less annoying to use, especially if you have a long list of navigation links. You wouldn't want to have to tab through the entire navigation list every time you refresh or go to another page.


Links that have visible text should have meaningful text. Screen reader users can pull up a list of links on a webpage and use them to find their way around. Links with text like "Click Here" or "Learn More" make no sense out of context.

There are other ways to provide meaningful labels for links if needed. Link tags (<a>) that contain only an image element will read the alt text of the image to someone using a screen reader. If you absolutely have to use non-descriptive link text, you can provide alternate link text with ARIA. Using the aria‑label attribute will leave the visual text untouched and give alternative text to screen readers.

Bad Example: <a href="https://example.com">Click Here</a>
Good Example: <a href="https://example.com">Example Website</a>
Decent Alternative: <a href="https://example.com" aria‑label="Example Website">Click Here</a>


Flashing Images

Still working on this section!


Animation

Still working on this section too. Come back soon!