Accessibility

Web accessibility (often shortened to "a11y") is the practice of building pages that everyone can use, including people who rely on keyboards, screen readers, or magnification, by using semantic HTML, descriptive text alternatives, and sufficient colour contrast.

Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.

Part of the free HTML & CSS course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

By the end of this lesson you'll be able to build pages that work for keyboard users, screen-reader users, and people with low vision — and you'll be able to spot and fix inaccessible markup on sight.

Accessibility is like a building with ramps, lifts, and braille signs. A staircase works fine if you can walk — but a ramp lets everyone in, including the person in a wheelchair, the parent with a pushchair, and the courier with a heavy trolley.

Your webpage is the building. A screen reader is a blind visitor who can only "see" the page through the labels and structure you provide. If your "button" is really a styled div , it's like a door with no handle — some visitors simply can't open it. Over 1 billion people worldwide live with a disability, so these ramps are not an edge case.

Accessibility (often shortened to a11y — "a", then 11 letters, then "y") means building pages that work for people who use assistive technology: screen readers, keyboard-only navigation, screen magnifiers, and more. It is not a nice-to-have bolted on at the end; it is part of writing correct HTML.

The single most important thing for accessibility is to use the right HTML element for the job . A screen reader knows that button is clickable, that nav is navigation, and that main is the main content — but a div is meaningless furniture it has to skip past. "Semantic" just means the tag describes what the thing is , not how it looks.

Run the worked example below. The same visual layout is built twice — once from div s and once from real elements. They look identical, but only the second one tells a screen reader what each part is .

Screen-reader users often jump heading to heading to scan a page, the way a sighted reader skims bold titles. That only works if your headings form a logical outline: one h1 per page, then h2 for each section, then h3 under those. Never skip a level just to get a smaller font — that's a job for CSS, not for picking the wrong tag.

For images, the alt attribute is the text a screen reader speaks in place of the picture. Get it right by image type:

Many people never touch a mouse. They move through a page with Tab (next control), Shift+Tab (previous), Enter / Space (activate), and Escape (close). For this to work, every interactive element must be reachable and must show a visible focus indicator — the ring that tells you where you are. Native elements ( a , button , input ) are focusable for free; that's another reason to use them.

The demo below is a full accessible page: a skip link, semantic landmarks, a labelled form, and a bright focus ring. Open it and press Tab repeatedly — watch the skip link appear first, then the focus ring jump from control to control.

Low-contrast text — pale grey on white, light blue on teal — is hard to read for everyone and impossible for many people with low vision. WCAG sets a measurable target called a contrast ratio , from 1:1 (invisible) to 21:1 (black on white). To pass AA , the level most laws require, hit these numbers:

💡 Pro tip: Don't guess. Open browser DevTools, inspect a text element, and the colour picker shows the live contrast ratio with a pass/fail tick against AA and AAA.

And never rely on colour alone to convey meaning — a red/green status dot is invisible to colour-blind users. Add an icon, a word, or a shape as well.

This "card" uses a div as a button and an image with no alt text. Replace the blanks so it becomes accessible, then run it and check the expected screen-reader behaviour written in the comments.

These inputs only have placeholder text — which vanishes when you type and is not a label. Connect each input to a label using matching for / id values, then verify the expected screen-reader behaviour in the comments.

Support is faded now — only an outline is given. Build a small page from scratch that ties the whole lesson together. Use the worked page in section 4 as your reference if you get stuck.

You can now build pages that work for everyone. The essentials:

Next up: HTML5 Semantic Architecture , where you'll structure whole pages with these landmark elements.

Practice quiz

What is the single most important thing you can do for accessibility?

  • Add ARIA roles to every element
  • Set a high z-index on focusable elements
  • Use semantic HTML — the right element for the job
  • Use only inline styles

Answer: Use semantic HTML — the right element for the job. Semantic elements like button, nav and h1–h6 give screen readers, keyboards and search engines built-in meaning for free.

What contrast ratio does WCAG AA require for normal-size text?

  • 4.5:1
  • 3:1
  • 7:1
  • 1:1

Answer: 4.5:1. AA requires at least 4.5:1 for normal text and 3:1 for large text (18pt/24px, or 14pt/18.66px bold).

When is it appropriate to give an image an empty alt attribute (alt="")?

  • When the image is informative
  • Whenever you forget what the image shows
  • Never — alt must always have text
  • When the image is purely decorative and adds no information

Answer: When the image is purely decorative and adds no information. alt="" tells the screen reader to skip a purely decorative image. Leaving alt off entirely makes it read the file name instead.

How do you correctly connect a label to a form input?

  • Use placeholder text as the label
  • Match the label's for attribute to the input's id
  • Wrap the input in a div
  • Add a title attribute to the input

Answer: Match the label's for attribute to the input's id. A label's for must match the input's id. The screen reader then announces the label, and clicking the label focuses the input.

Why should you never write outline: none on :focus without a replacement?

  • Keyboard users can no longer see where they are on the page
  • It slows down the page
  • It disables hover styles
  • It removes the element from the DOM

Answer: Keyboard users can no longer see where they are on the page. Removing the focus ring with nothing in its place makes the page unusable by keyboard. Style :focus-visible with a high-contrast outline instead.

What is a skip link?

  • A link that skips loading images
  • A link that opens in a new tab
  • The first focusable link that jumps past the header/nav straight to main content
  • A link with aria-hidden set

Answer: The first focusable link that jumps past the header/nav straight to main content. A skip link ('Skip to main content') lets keyboard and screen-reader users bypass repeated navigation. It is usually hidden until focused.

What is the correct heading structure for a page?

  • Multiple h1 elements per page
  • One h1, then h2 for sections, then h3 under those — never skipping levels
  • Pick heading levels by the font size you want
  • Only use h3 and h4

Answer: One h1, then h2 for sections, then h3 under those — never skipping levels. Use one h1, then a logical outline of h2, h3 and so on. Font size is a job for CSS, not for choosing the wrong heading level.

Which native elements are keyboard-focusable for free?

  • div and span
  • p and section
  • header and footer
  • a, button and input

Answer: a, button and input. Native interactive elements like a, button and input are focusable and keyboard-operable automatically — another reason to use them.

Why is using a div with onclick instead of a button an accessibility problem?

  • A div cannot have a background colour
  • A div onclick can't be reached by Tab, ignores Enter/Space, and isn't announced as a button
  • A div onclick is slower to render
  • A div onclick breaks the box model

Answer: A div onclick can't be reached by Tab, ignores Enter/Space, and isn't announced as a button. A div is not focusable or announced as a control. A real button is reachable by Tab, responds to Enter/Space, and is announced as a button.

Besides colour, what should convey status like success or error?

  • Nothing else is needed
  • A louder colour
  • An icon, a word, or a shape as well — never colour alone
  • Only animation

Answer: An icon, a word, or a shape as well — never colour alone. Colour alone is invisible to colour-blind users. Add an icon, text label, or shape so the meaning does not depend on colour.