On a small website, accessibility is easy to postpone. The design starts to take shape, the responsive work is done, and it feels like only the finishing touches are left.
Some choices get expensive once the rest is in place, though. Navigation built with div elements, headings picked by font size, forms without labels and invisible focus all require structural changes, not just a CSS pass.
I have been paying more attention to this since I started organising projects with multiple pages and a lot of content. In my portfolio, structure helps search engines find pages, but it also helps someone reach an article, understand where they are and move around without using a mouse.
I am not an accessibility specialist. I see it as a part of frontend work I need to keep learning, alongside security and performance. This is the baseline I want to have in place before calling a website finished.
Leaving it late means rebuilding
Accessibility shows up in basic decisions: the HTML you choose, content order, keyboard navigation, form messages and the job each image does.
You do not need to wait for an audit to look at those things. While building a page, you can already check whether it makes sense without the visual styling, whether the HTML order is logical and whether controls behave as expected.
There are cases beyond screen reader use, too: someone on a phone in bright sunlight, someone who has increased the text size, someone using a keyboard because of a temporary injury, or someone seeing an interface for the first time.
HTML does more work than it gets credit for
Early on, it is easy to pick elements based on how they look. A div for everything, a styled span for a button, and headings chosen by font size.
Browsers and assistive technology do not read that the way a person does. The code needs to state what each part is.
Use a <button> for an action. Use an <a> when it takes someone somewhere else. Put navigation in <nav>, main content in <main>, and use headings to express the real hierarchy of the page.
<button type="button">Open filters</button>
<a href="/projects/">View projects</a>Those elements bring useful behaviour with them: they can receive focus, work with a keyboard and tell assistive technologies what they are.
ARIA can add meaning when an interface needs it. Before adding attributes, it is worth checking whether HTML already has an element that expresses the intent.
Keyboard testing changes what you notice
One simple test I try not to skip is moving through a page with Tab, Shift + Tab, Enter and Space.
It quickly reveals issues that do not show up when you use a mouse:
- Focus is invisible because it was removed in CSS.
- The tab order makes no sense.
- A menu opens but cannot be closed properly.
- A dropdown leaves focus somewhere unexpected.
- Interactive elements are empty or cannot be reached.
- A modal opens while the keyboard can still move through the page behind it.
Removing focus for a cleaner design is usually a bad trade. It is the reference point for keyboard users. If the default style does not fit the website, design another one that is still clear.
On content-heavy sites, a skip link to the main content also saves people from working through the whole menu every time they open a new page with a keyboard.
Page structure is navigation too
Headings do more than set the visual rhythm of a page. They help people understand its hierarchy and move between content sections.
In an article, the main title should be an h1, followed by sections that use h2, h3 and so on in an order that matches what you are explaining.
That fits the way I want to approach this blog: one clear idea per article, sections that answer a specific question and links that say where they lead. A link that only says “here” or “read more” is much harder to understand outside its paragraph.
The same applies to the broader layout. Header, navigation, main content, complementary content and footer are different parts of a page, and HTML can make that clear.
A form does not explain itself
Forms are where the gap between an interface that looks fine and one people can actually complete becomes obvious.
A placeholder is not a replacement for a label. It disappears as soon as someone starts typing and does not provide a stable reference for the person or their screen reader.
<label for="email">Your email</label>
<input id="email" name="email" type="email" autocomplete="email" />What happens after an error matters too. “Invalid field” is not very helpful. It is better to say which value has a problem, why, and how to fix it when possible. Red can support the message, but it should not be the only signal.
In my article on common security mistakes in web forms, I wrote about validating on both the frontend and backend. There is another reason to get the frontend right: a well-designed validation flow gives people quick, understandable feedback instead of making them blindly resubmit a form.
Alternative text depends on context
Not every image needs a long description, and writing “image of” in every alt does not help anyone.
The useful question is: if this image disappeared, what information would someone lose?
If a screenshot shows an important part of a project, the alternative text should explain what it shows or why it matters. If an image is purely decorative and the content already works without it, it can use alt="" so it does not add noise.
<img
src="/ico-notes-project.webp"
alt="Search screen in the ICO Notes app showing results grouped by module"
/>alt is not a place to repeat keywords. It is content for someone who cannot see the image, and that makes you think about the image’s actual role on the page.
Comfortable reading is part of the interface
Contrast, text size, spacing and reading width directly affect the experience.
Very light grey text on a white background can look good in a screenshot and still be tiring to read for several minutes. A small button might work with a mouse but be difficult to tap on a phone. A rigid layout can break down when someone increases text size.
Looking at an interface only on a large screen and in ideal conditions leaves out too many cases. Zooming the page to 200%, checking that the content still makes sense and trying it on a phone uncovers issues quickly. If a site uses animation, reduced-motion preferences are worth respecting where possible.
A score does not close the subject
Lighthouse, axe and similar tools are useful for finding repeated issues: missing image alternatives, insufficient contrast, unnamed controls or invalid attributes.
They are a prompt to investigate, not the final grade for a project. A tool cannot tell whether an alternative text describes an image well, whether a form order makes sense, whether an error message is understandable or whether a menu feels easy to use.
Before shipping, I would start here:
- Move through the key pages using only a keyboard.
- Review headings and main page regions in the HTML.
- Check that forms have labels, instructions and clear errors.
- Look at images and decide what information they should convey without being seen.
- Zoom text and test on a phone before the deploy.
That does not let you claim a website is accessible in every case. It does stop you from shipping without looking at the basics.
The kind of detail I want to look after
When I started turning course notes into a reference app and organising content across multi-page projects, the problem was not only writing code. The information had to be findable and understandable without already knowing where to click.
That is why accessibility matters to me. It makes you look at the parts of a website that do not show up in a screenshot: content order, focus, messages and how the interface responds when it is not used the way the developer expected.