../courses.php
HTML
HTML101
90
Accessibility Basics
Build pages that work for screen readers, keyboards, and every ability — from the start.
What is the first rule of ARIA, and what does it tell you about when to use it?
The first rule of ARIA is: if you can use a native HTML element with the right semantics already built in, use that instead of adding ARIA. A
<button>
is already keyboard-focusable, already announced as a button by screen readers, and already responds to Enter and Space — no ARIA needed. ARIA exists for situations that native HTML cannot handle, not as a substitute for writing correct HTML in the first place.
Accessibility is not a feature you add at the end of a project — it is a result of writing correct HTML throughout. Every lecture in this course so far has taught accessibility: semantic structure from Lecture 1, labelled forms from Lecture 2, scoped table headers from Lecture 3, alt text from Lecture 4. This lecture brings those threads together and fills in what is still missing.
Screen readers are software that convert on-screen content into speech or braille. They are used by people who are blind or have low vision, but also by people with reading difficulties, motor disabilities that prevent mouse use, and people driving or doing other tasks that prevent them from looking at a screen. They navigate by headings, landmarks, links, form fields, and list items — all of which are announced correctly only when the underlying HTML is semantic and correct.
Keyboard navigation is equally important. Many users cannot use a mouse — because of motor disability, injury, or preference. Tab moves focus forward through interactive elements (links, buttons, inputs). Shift+Tab moves backward. Enter activates links and buttons. Space toggles checkboxes and activates buttons. These keyboard behaviours are free when you use the correct HTML elements. They must be manually programmed — and are frequently missed — when you build interactions with
<div>
and JavaScript instead.
ARIA (Accessible Rich Internet Applications) is a set of HTML attributes — roles, states, and properties — that provide accessibility information when native HTML cannot. The most common use case is describing a custom interactive widget (a tab panel, a modal dialog, an autocomplete dropdown) that has no native HTML equivalent. Used correctly, ARIA dramatically improves accessibility. Used incorrectly — or used instead of correct HTML — it actively makes things worse. The golden rule: no ARIA is better than bad ARIA.
Accessibility patterns applied throughout one page section
<!-- 1. Skip link — always first in <body> -->
<a href="#main-content" class="skip-link">
Skip to main content
</a>
<header>
<nav aria-label="Primary">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about"
aria-current="page">About</a></li>
</ul>
</nav>
</header>
<main id="main-content">
<!-- 2. Correct heading hierarchy -->
<h1>About Our Team</h1>
<section aria-labelledby="team-heading">
<h2 id="team-heading">Meet the staff</h2>
<p>We are a team of five...</p>
</section>
<!-- 3. Form with full labels -->
<section aria-labelledby="contact-heading">
<h2 id="contact-heading">Contact us</h2>
<form action="/contact" method="post">
<label for="name">Your name</label>
<input type="text" id="name" name="name" required>
<!-- 4. Error message linked to input -->
<label for="email">Email address</label>
<input type="email"
id="email"
name="email"
aria-describedby="email-hint"
required>
<span id="email-hint">
We will never share your email.
</span>
<button type="submit">Send</button>
</form>
</section>
</main>
The skip link — The very first interactive element on every page should be
<a href="#main-content">Skip to main content</a>.
It is hidden visually (with CSS — not with
display:none,
which would also hide it from screen readers) and becomes visible only when focused. Keyboard users must Tab through every navigation link on every page load before reaching the content — unless this link exists. It is one line of HTML that eliminates a major frustration for keyboard users.
Heading hierarchy — Think of headings as a table of contents. There is one
<h1>
per page — the page title. Major sections get
<h2>.
Sub-sections within those get
<h3>.
Never skip a level to get a visual size — use CSS for sizing. Screen reader users navigate pages by jumping between headings: if the hierarchy is broken, the mental map of the page breaks with it. A screen reader that announces "heading level 1: About, heading level 4: Meet the team" leaves the user confused about what happened to levels 2 and 3.
aria-label
and
aria-labelledby — When a page has more than one
<nav>,
more than one
<section>,
or any landmark that could be ambiguous, you must give it a name.
aria-label="Primary"
gives the element a direct text label (used when there is no visible heading).
aria-labelledby="team-heading"
points to an existing visible heading element by its
id
— preferred when a heading already names the section, because the visible text and the accessible name stay in sync automatically.
aria-current="page" — Add this to the navigation link that points to the current page. Screen readers announce it as "current page" or "selected", letting users know exactly where they are in the site without having to read the page title. It is a small addition that significantly improves orientation in multi-page sites.
aria-describedby — Where a label names an input, aria-describedby adds supplementary information. In the example, the email field is labelled "Email address" but also linked to a hint: "We will never share your email." A screen reader reads the label first, then the description when the user pauses. Use this for hints, format instructions, or error messages — never as a replacement for a proper
<label>.
Legal requirement
In many countries — including Canada, the US, the EU, and the UK — websites serving the public are legally required to meet WCAG 2.1 AA accessibility standards. Government sites, healthcare, education, and financial services face the highest requirements. Building accessibility in from the start is far cheaper than retrofitting it later under legal pressure.
Larger audience
Approximately 1 in 6 people worldwide have some form of disability. Accessibility features help users with visual, hearing, motor, and cognitive differences — but also situational users: someone in bright sunlight, using a phone one-handed, or in a noisy environment without headphones.
Better for everyone
Keyboard navigation, clear headings, descriptive link text, and sufficient colour contrast make pages easier to use for all visitors — not just those with disabilities. The same structure that helps screen readers also helps search engines, improves page speed, and reduces cognitive load.
Semantic HTML does most of the work
You do not need to become an accessibility expert to cover 80% of what matters. Using the correct HTML elements —
<button>
not
<div>,
<label>
on every input,
alt
on every image, headings in order — handles the most common failures automatically.
Broken heading order, missing labels, div buttons — avoid
<h1>Welcome</h1>
<h4>Our Services</h4> <!-- skipped h2, h3 -->
<input type="text" placeholder="Your name">
<!-- no label -->
<div onclick="submitForm()">
Submit
</div>
<!-- not a button, not keyboard accessible -->
Ordered headings, linked labels, real buttons — use this
<h1>Welcome</h1>
<h2>Our Services</h2> <!-- correct hierarchy -->
<label for="name">Your name</label>
<input type="text" id="name" name="name">
<button type="submit">Submit</button>
<!-- keyboard-focusable, announced correctly -->
Paste your page HTML into ChatGPT and ask: "Check the heading hierarchy, confirm every interactive element is keyboard-accessible, and flag any inputs without labels." It is good at finding heading-level gaps and missing labels. Be careful if it suggests adding ARIA roles to elements that are already semantic — for example
role="button"
on a
<button>
element. That is redundant. Accept ARIA suggestions only for genuinely custom widgets.
Add a skip link as the very first element inside
<body>:
<a href="#main-content">Skip to main content</a>.
Give your
<main>
the attribute
id="main-content".
Press Tab immediately on page load and confirm the skip link receives focus first.
Audit the heading structure of a page you have built. Open Chrome DevTools → Accessibility → Full page accessibility tree. Confirm there is exactly one
<h1>,
that no heading levels are skipped, and that the heading text describes each section meaningfully.
If your page has more than one
<nav>
or more than one
<section>,
add
aria-label
or
aria-labelledby
to distinguish each one. Check the Accessibility panel and confirm each landmark has a unique name.
In your navigation, add
aria-current="page"
to the link that matches the current page. Open a screen reader (VoiceOver on Mac with Cmd+F5, or NVDA on Windows) and navigate to that link — confirm it is announced as "current" or "selected."
Run a Lighthouse Accessibility audit in Chrome DevTools on a page you have built. Aim for a score above 90. For every flagged issue, read the "Learn more" link Lighthouse provides — each one explains the exact HTML fix required.
Skipping heading levels — jumping from
<h1>
straight to
<h4>
because it looks smaller. Screen reader users navigate by heading level. A gap means they search for an
<h2>
that does not exist. Use CSS to control size — never use heading level for visual sizing.
Building buttons and links with
<div>
or
<span>
elements. These are not keyboard-focusable, not announced as interactive by screen readers, and do not respond to Enter or Space. Every user who cannot use a mouse is blocked. Use
<button>
for actions and
<a href>
for navigation — always.
Adding ARIA to fix problems caused by not writing semantic HTML. Writing
role="button"
on a
<div>
still does not give it keyboard behaviour — you must also add
tabindex="0"
and JavaScript for Enter/Space. The
<button>
element gives you all of that for free. ARIA role first, proper element never, is the wrong order.
Using
display:none
or
visibility:hidden
to hide the skip link at all times. These CSS rules remove the element from the accessibility tree — screen readers cannot find it either. Hide it with a technique that moves it off-screen visually (
position:absolute; left:-9999px)
but keeps it in the DOM and tab order.
Using placeholder text as a label substitute. Placeholder text disappears the moment the user starts typing — users forget what they were supposed to enter. Placeholder text also has lower colour contrast than regular text and is not read reliably by all screen readers. Always use a visible, persistent
<label>.
Add a skip link, maintain a correct heading hierarchy, label every interactive element, apply
aria-label
or
aria-labelledby
to ambiguous landmarks, and use
aria-current
and
aria-describedby
where they add real value — without using ARIA as a substitute for correct HTML.
Login - Jit4All
Login
Welcome back to Jit4All