011: Accessibility Basics
Learning outcomes
By the end of this lesson, you should be able to explain accessibility as support for different ways of perceiving and operating content. You will audit semantics, labels, alternatives, grouping, and keyboard focus; choose links and buttons for the right jobs; and apply the “native HTML first” rule before reaching for ARIA.
Prerequisites and retrieval
Open the validated form and portfolio from the earlier work. Find five accessibility decisions already present there: the page language, heading hierarchy, meaningful link text, context-sensitive alt, and the association between each label and its control. Accessibility is not a feature we bolt on at the end. This lesson turns those earlier decisions into a repeatable way of working.
Terminology
- Accessibility: Making websites usable by as many people as possible, including people with disabilities. — Source: MDN: Accessibility overview
- Assistive technology (AT): Hardware/software people use to interact with content — screen readers, magnifiers, switch devices. — Source: W3C WAI: Easy Checks
- Keyboard operable: All functionality available without a pointer (WCAG principle: operable). — Source: WCAG 2.2
- Focus: The currently targeted element receiving keyboard interaction. — Source: WCAG 2.2
- Focus order: The sequence in which focus moves among interactive elements, normally following source order. — Source: WCAG 2.2
- Accessible name: The programmatic name derived from label, alt, or aria-label that AT announces. — Source: ARIA APG: Read Me First
- Role: The kind of interface object an element represents (button, navigation, heading). — Source: WHATWG: WAI-ARIA
- State/value: Current conditions communicated alongside role, such as checked, expanded, disabled. — Source: WHATWG: WAI-ARIA
- ARIA: A W3C vocabulary of roles, states, and properties supplementing native accessibility semantics. — Source: WHATWG: WAI-ARIA
- WCAG: The Web Content Accessibility Guidelines — testable success criteria organized under POUR principles. — Source: W3C WCAG 2.2
- Semantics: "The meaning of a piece of content, for example the meaning of a heading or a paragraph." — Source: MDN: Semantics
- Label: "A text label associated with a form control by using the label element with for/id or by wrapping." — Source: WHATWG: Label element
- Landmark: "A region of a page intended for navigation, such as banner, navigation, main, complementary, contentinfo." — Source: W3C WAI: Page Structure — Landmarks
- Focus visible: "The focus indicator is visible." — Source: WCAG 2.2: Focus Appearance
Mental model: one interface, many ways to use it
There is no single “average user” to design for. One person might read visually, another might listen through a screen reader, and another might zoom text, move through headings, use only a keyboard, issue voice commands based on visible labels, or combine several of these approaches. Semantic HTML gives the browser a shared structure that it can expose through those different interaction modes.
Accessibility is not limited to screen readers, and a single automated score cannot establish that a page works for everyone. WCAG 2.2 AA can provide a useful project baseline, but conformance still requires both automated checks and human evaluation, and it cannot represent every individual need.
Native semantics first
Start with the behavior you need, then choose the HTML element that already provides it. Compare these two examples:
<div onclick="submitForm()">Send message</div>
and:
<button type="submit">Send message</button>
The div is not a button. It has no button role, normal keyboard focus, Enter/Space activation, disabled behavior, form-submission behavior, or dependable accessible-name semantics as a control. Adding role="button" makes a promise, but JavaScript still has to reproduce the expected interaction. The native button already carries that behavior and meaning.
The same choice applies elsewhere:
- use
<a href="project.html">View project</a>to navigate; - use
<button type="button">Show filters</button>for an in-page action; - use
<h2>for a section heading, not<div class="heading">; - use
label,fieldset, andlegendfor forms; - use
table,th, andscopefor tabular relationships.
ARIA can fill genuine semantic gaps, but it does not supply behavior or visual styling. Duplicate roles and labels are best avoided, and incorrect ARIA can hide or misrepresent semantics that were otherwise correct. The first ARIA rule is therefore practical: when a native element already provides the required semantics and behavior, use it.
Accessible names, focus order, and skip navigation
Every interactive element needs an accessible name: the text assistive technology uses to identify it. Native HTML usually gives you the clearest path:
- a button's text names the button;
- a
labelnames its associated form control; - an image's
alttext names the image when the image conveys content; - link text names the destination or purpose.
Do not use a placeholder as a replacement for a visible label. A placeholder disappears while a person types and is not a dependable labeling mechanism.
Keyboard focus should normally move in source order. Positive tabindex values such as tabindex="5" create a second focus order that becomes fragile as soon as the page changes. Native links, buttons, and form controls are already focusable.
When a page puts repeated navigation before its main content, a skip link gives keyboard users a direct way past it:
<a href="#main-content">Skip to main content</a>
...
<main id="main-content">
...
</main>
You can style the link later so it becomes prominent when focused. The HTML still has two jobs: the target must exist, and the source order must describe a sensible route through the page.
Hidden content needs the same care. In typical use, the hidden attribute removes content from normal rendering and from the accessibility tree. Do not use it on information a person still needs to complete the task.
Guided example: keyboard audit the course form
Use the 010 contact form and a checklist. Set the mouse aside and audit what a keyboard user can actually do.
- Reload, then press Tab. Focus should reach interactive controls in a logical source order.
- Confirm that focus is visibly apparent using the browser defaults. HTML alone should not remove it; later CSS must preserve a strong indicator.
- Use the pointer for this one label check: clicking each label should focus or toggle the intended control.
- Use arrow keys within a radio group and Space on checkboxes.
- Open and change the select using the keyboard conventions for the platform.
- Enter invalid values and submit with Enter or the button. Check that focus and feedback identify the problem.
- Zoom to 200%. Content and controls must remain understandable. Final reflow testing belongs with CSS, but meaningful HTML source order should already be in place.
- Inspect the accessibility tree. Each control should expose an appropriate name, role, and state.
Here is a repaired excerpt to use during the audit:
<form action="/contact" method="post">
<p>
<label for="email">Email address (required)</label>
<input type="email" id="email" name="email" autocomplete="email" required>
</p>
<fieldset>
<legend>Reply preference</legend>
<input type="radio" id="reply-email" name="reply" value="email" required>
<label for="reply-email">Email reply</label>
<input type="radio" id="reply-none" name="reply" value="none">
<label for="reply-none">No reply needed</label>
</fieldset>
<button type="submit">Send message</button>
</form>
This form needs no ARIA. The visible labels and native grouping expose the names and relationships, while required exposes both state and behavior. Adding ARIA just to make markup appear “more accessible” would add noise rather than capability.
Images, headings, and links audit
Decide what each image means in its surrounding context. An informative image needs a concise equivalent; a decorative or redundant image should use alt=""; a functional image should name its destination or action; and a complex image needs equivalent data or an explanation. “Every image needs descriptive alt text” is a useful-sounding myth. Every img generally needs an alt decision, and the correct decision can be empty alt text.
Read the headings by themselves. Their hierarchy should summarize the page, not jump levels merely to get a preferred visual size. Then navigate by landmarks: the page header, navigation, main content, and footer should make sense without redundant roles.
Read the links by themselves as well. “Read weather project details” communicates a purpose; a page full of “Learn more” links does not. Adjacent links to one destination can also create repetition. When the content model allows it, combine the image and title into one link, or keep one clear text link.
Intermediate example: repair an inaccessible project card
Before:
<div class="card">
<div class="big">Weather app</div>
<img src="images/weather.webp">
<div tabindex="0" role="button">Learn more</div>
</div>
After:
<article>
<h2>Weather summary project</h2>
<img
src="images/weather.webp"
alt="Forecast summary for Chennai showing cloudy conditions and 31 degrees Celsius"
width="1440"
height="900">
<p>A semantic page explaining a local forecast.</p>
<p><a href="projects/weather.html">Read the weather project details</a></p>
</article>
The operation here is navigation, so the correct element is a link, not a pretend button. tabindex="0" would add focus to the div, but it would not give that element link behavior or a useful link role. The real heading supports heading navigation. The image dimensions reduce layout movement, and the alt text communicates the meaningful result shown in the screenshot.
If the surrounding text already communicates all of the screenshot's information, empty alt text may avoid repeating it. The right accessibility choice comes from context, not from applying one universal rule about description length.
Advanced optional extension: restrained ARIA
Some additions genuinely supplement native HTML. For example, aria-current="page" can identify the active navigation link, and aria-describedby="password-help" can associate persistent instructions with a control. Both retain the native role and the visible text.
Do not add an aria-label that contradicts the visible label. Voice-control users may speak the words they can see, so the accessible name should contain that visible label, as required by Label in Name guidance. Never hide focusable content with aria-hidden="true". Advanced ARIA patterns need testing in the browser and assistive-technology combinations that matter for your users before they ship.
Common mistakes and debugging
- Accessibility equals alt text: audit perceivability, operation, understanding, and robustness.
- Every image gets a detailed description: decorative/redundant images need empty alt.
tabindex="0"makes a div a button: it adds focus only.- Positive tabindex to fix order: repair source order instead.
- Link styled as button confusion: semantics follow action, not appearance.
- Focus removed because it looks ugly: preserve/replace it with a clearly visible indicator.
- Placeholder as label: use persistent associated labels.
- ARIA added to native elements: remove redundant or conflicting attributes.
- Automated checker treated as proof: combine tools with keyboard, zoom, structure, content, and user testing.
When an accessible name looks wrong, inspect the control in this order: native semantics, associated visible label, computed accessible name, and then keyboard behavior. A control may receive focus while still having no useful name. The reverse problem also occurs: an aria-label can conceal a visible naming mistake from a sighted reviewer. In DevTools' accessibility tree, verify the name and role, then activate the control using only the keyboard. Repair the HTML relationship before adding ARIA.
Accessibility, security, and performance
Accessibility is the main concern in this lesson. Where appropriate, use WCAG 2.2 AA as a target, but do not claim conformance from this basic audit. Test keyboard access and the absence of traps, logical focus, page title and language, headings, names, labels, alternatives, errors, zoom, reflow, contrast after CSS, and captions.
Accessible authentication has security implications. Allow password managers and paste, do not make cognitive-function tests the only route, and provide alternatives. Timeouts and CAPTCHAs may be legitimate security controls, but they can also create barriers and need inclusive design. Native HTML often reduces custom code, attack surface, and performance overhead compared with custom widgets; that is not a reason to skip a security review.
Tiered exercises
Level 1: classify
Choose link or button for: About page, submit form, show more text, download résumé, and delete a draft. Explain the purpose behind each choice.
Level 2: audit
Keyboard-audit the course form and record its focus order, label behavior, group operation, submit behavior, and errors. Repair every HTML issue you find.
Level 3: portfolio review
Inspect the landmarks, headings, links, images, and accessibility tree in the portfolio. Remove unnecessary ARIA and write a short statement describing the residual risk.
Level 1: About page: link; submit: submit button; show text: button (with later scripted state); résumé URL: link, optionally with download expectations stated; delete: button because it changes state and needs confirmation design.
Level 2: A correct native form follows source order; every visible label targets one unique ID; arrow keys operate same-named radios; Space toggles checkboxes; the submit button activates by keyboard; required/type errors block ordinary submission. Fix generic div controls, missing labels, mismatched IDs, and positive tabindex.
Level 3: The expected portfolio has one visible main, logical headings, named navigation when there is more than one navigation region, descriptive link purposes, context-based alt decisions, native controls, and only justified aria-current or aria-describedby. Residual risk: no automated or single-person audit proves WCAG conformance; CSS contrast and reflow, plus production browser/AT/user testing, remain.
Recap and exit questions
Accessible HTML supports many interaction modes through semantics, names, relationships, and native behavior. Begin with native elements, preserve focus and source order, and use ARIA only when a real semantic gap remains.
- Why does
role="button"not create button behavior? - What should determine link versus button?
- When is empty alt correct?
- Why avoid positive tabindex?
- What evidence proves that a control has both a useful accessible name and usable behavior?
- Why can automated results not prove accessibility?
Try it with your own example
Put the mouse down for five minutes and audit Rina's cake-order form as a keyboard-only customer would experience it. You built the form, so you already know its assumptions and shortcuts; that makes it a useful first page to audit honestly.
- Reload the page and press Tab once. Does focus land on “Your name,” before the radio group, in that order? If you rearranged fields casually while testing lesson 010, check whether the visual order and source order have drifted apart.
- Tab into the size
fieldset. Use the arrow keys, not Tab, to move between “6-inch” and “8-inch.” This is native radio-group behavior, but it works only when both inputs genuinely sharename="size". If a copied radio lost the shared name, the step silently fails even though the screen may look correct. - Submit with the name field empty and confirm that focus visibly lands there, rather than merely noticing a browser validation bubble somewhere off-screen.
Now try the most revealing test in this lesson. Picture Rina's real order form with a “Learn more about allergens” link beside a “Learn more about pickup” link. If both links are labeled only “Learn more,” a screen-reader user who opens a list of page links hears “Learn more, Learn more” and cannot distinguish them. Rewrite both links so each makes sense on its own, out of context. That builds directly on the link-writing skill from lesson 004 and is a habit worth carrying into every site you ship.
Further reading: W3C WAI — Easy Checks is a ten-minute manual checklist you can run on Rina's finished site using the same approach.
