Many front-end bugs I'm asked to fix aren't broken code. They're code that works in the browser the developer tested in, and quietly fails elsewhere: with a screen reader, a crawler, a slow connection, or a browser the developer didn't test. "It follows standards" can sound like a box-ticking exercise until you've seen a page that is a stack of <div>s with click handlers, which is hard for both assistive technology and search engines to interpret. Accessibility and SEO overlap far more than they differ. Both depend on the HTML describing what's actually on the page.
Here's how I structure a new front-end build so it holds up under the W3C validator, a screen reader, and a Lighthouse audit, and where I've seen that discipline slip under deadline pressure.
Start from the document outline, not the design file
A design file gives you boxes and colours. It doesn't give you a document structure, and the structure is what assistive technology and search engines read. Before I write CSS, I sketch the semantic skeleton:
<body>
<header>
<nav aria-label="Main">…</nav>
</header>
<main>
<h1>One per page, describes the page's purpose</h1>
<section aria-labelledby="services-heading">
<h2 id="services-heading">Services</h2>
</section>
</main>
<footer>…</footer>
</body>
Most developers already know <header>, <nav> and <main> exist. The mistake I see more often is heading order. Heading sizes get chosen for visual weight, so you end up with an <h4> styled to look prominent sitting above the page's only <h2>. A sighted user won't notice. A screen reader user navigating by the heading list gets an outline with a missing level, and that's exactly what the W3C's guidance on using h1–h6 to identify headings is meant to prevent.
I check heading order on every new page before it ships, because this mistake is invisible on screen and only shows up when something reads the document structure.
Where this goes wrong in production
Heading order breaks the first time a content editor touches the CMS. You ship a clean outline, and months later someone adds an <h2> inside a sidebar widget because it "looked more important." To make this harder to get wrong, drive heading levels from a prop (level={2}) rather than hardcoding tags, so a nested component can adjust its own rank instead of silently duplicating an <h2>.
Alt text becomes "image123.jpg" under deadline pressure. Every informative image needs an alt. A decorative image needs an empty alt="", which tells assistive technology to skip it. That's better than reading out a meaningless filename. The more common mistake is writing descriptions for every image, including the sixth identical icon in a row of social links, which just adds noise. See the W3C's guidance on information and relationships for the principles.
Semantic HTML gets replaced with a <div onclick>. A <div> or <span> with a click handler isn't a button. It isn't keyboard-focusable, doesn't respond to Enter or Space, and doesn't announce its role. Using <button type="button"> is a quick fix, but it often gets skipped because the design has no visible button styling. Resetting a native button with CSS is a small job:
/* reset a real button, don't fake one */
.link-style-button {
all: unset;
cursor: pointer;
display: inline;
}
/* all: unset also removes the focus outline, so restore a visible one */
.link-style-button:focus-visible {
outline: 2px solid currentColor;
outline-offset: 3px;
}
Keyboard focus must stay visible. WCAG's focus visible criterion is the reason for that second rule.
SEO follows from clear structure
Clean HTML doesn't replace good SEO work, but a lot of what search engines need is already present when the markup is honest about the page:
- One
<h1>that states the page's purpose in plain language. "Residential Electrician in Austin, TX" tells both visitors and search engines what the page is about. A clever slogan usually doesn't. - A
<title>and meta description written for each page. Copy-pasted metadata with one word swapped gives search engines little to work with, and it's a common problem on existing sites. - A
<link rel="canonical">on every page, especially on sites with tracking or filter parameters that create duplicate URLs for the same content. - Semantic landmarks (
<nav>,<main>,<article>) that help crawlers and assistive technology find the main content. Search engines don't publish how they weigh landmarks, so treat this as a clarity benefit rather than a ranking lever. - Structured data (JSON-LD) for content with a matching schema.org type, such as
Article,LocalBusinessorProduct. Structured data makes a page eligible for certain rich results. Google's structured data introduction is explicit that you must include the required properties for a page to be eligible, and that eligibility is not a guarantee of display. Rich result types also have their own content rules, and Google has restricted some of them over time, so check the current guidelines for each type before you build around one.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "Example Plumbing Co.",
"telephone": "+1-512-555-0100",
"address": { "@type": "PostalAddress", "addressLocality": "Austin", "addressRegion": "TX" }
}
</script>
None of this requires a plugin or an "SEO package." It requires the HTML to describe honestly what's on the page, which is the same requirement accessibility has.
Trade-offs and when NOT to do this
Strict standards compliance has a real cost, and it's better to name it than pretend it doesn't exist.
Full WCAG AA compliance on a tight budget is a scoping conversation. A lot of the practical benefit comes from keyboard navigation, correct semantics, sensible contrast and working alt text, and those can be prioritised ahead of a full audit against every success criterion. If a budget forces a choice, I'd fix the things that affect whether someone can use the site before the things that only affect whether an automated scanner reports green. Those aren't the same thing.
Not every HTML validation error matters equally. A missing alt attribute matters. A vendor-specific attribute on an <svg> that the validator doesn't recognise often doesn't. Chasing a zero-error report on a page built around third-party embeds, such as payment widgets or map embeds, can mean chasing noise. Learn which errors affect users.
Semantic HTML doesn't remove the need for ARIA. <nav>, <main> and friends cover common cases, but custom components such as tab panels, comboboxes and toast notifications have no native HTML equivalent. They still need role, aria-expanded and focus management where applicable. The WAI-ARIA Authoring Practices describe the expected patterns. The rule is to use native HTML first and reach for ARIA where native elements don't cover the behaviour.
Why it matters for the business behind the site
Clients don't hire a developer to pass a validator. They hire one because the site needs to convert visitors and be found in search. Standards compliance supports both goals. A page that search engines can parse cleanly is usually also a page that assistive technology can parse cleanly, and pages that load quickly on slower phones and connections tend to keep mobile visitors. Getting the fundamentals right in the HTML means you don't have to pay for them again on every new feature.
If your current site was built quickly and needs someone to review its semantics, accessibility, structured data and technical SEO, that's the kind of audit-and-fix work I do. Tell me what you're seeing in your analytics or accessibility feedback, and I'll tell you what's worth fixing first.