Remediation workflow
WCAG Remediation Checklist for Existing Websites
You have scan results — a ShipSafe report, an Axe audit, or an ADA demand letter citing specific failures. Now what? This guide gives you a prioritized fix order: from the one-line template changes that resolve the most common lawsuit triggers, to the complex keyboard navigation work that takes longer but closes the remaining gaps.
- Baseline scan first
- Priority 1: Template fixes
- Priority 2: Alt text
- Priority 3: Form labels
- Priority 4: Color contrast
- Priority 5: Keyboard nav
- Document the work
- Verify with ShipSafe
- FAQ
Step 0: Run a baseline scan before touching anything
Before making any changes, document the site as it exists now. This creates a timestamped “before” record. If a demand letter is involved, this evidence matters.
- Run ShipSafe on your homepage and each cited URL. Screenshot the results with the date visible in the browser.
- Install the Axe DevTools browser extension (free, by Deque) and run it on the same pages. Export the full violations list — this becomes your work queue.
- Save both sets of results. A screenshot with the current date and the failing item count is sufficient documentation at this stage.
Axe DevTools is the right tool for building your fix queue: it lists every failure with a specific element selector, the WCAG criterion it violates, and a “More info” link explaining the exact fix. Work through the Axe results list in the priority order below.
Priority 1: Template-level fixes — 30 minutes, no design decisions
These fixes live in your layout template (or base HTML file), which means each fix propagates automatically to every page on the site at once. They address the most commonly cited WCAG failures in ADA demand letters and require no visual design changes.
Add lang="en" to your <html> tag
Open your base template or index.html and add the lang attribute with the correct BCP 47 code for your site’s primary language. For English: <html lang="en">. Screen readers use this attribute to select the correct voice and pronunciation engine; without it, your text may be read in an unintelligible accent. This is WCAG 3.1.1 Level A — one of the most frequently cited single-attribute failures in automated demand letters.
<!-- Before -->
<html>
<!-- After -->
<html lang="en">
Add a skip navigation link
Add the following as the very first element inside <body>, before the <header>. Without it, keyboard and screen reader users must Tab through every navigation item on every page load — WCAG 2.4.1 Level A requires a mechanism to bypass repeated blocks of content.
<a href="#main" class="skip-link">Skip to main content</a>
<!-- Add id="main" to your main content wrapper -->
<main id="main">…</main>
Style the link to be off-screen by default, visible on keyboard focus:
.skip-link {
position: absolute;
left: -9999px;
top: 8px;
background: #14181f;
color: #fff;
padding: 10px 16px;
border-radius: 8px;
font-weight: 600;
z-index: 9999;
}
.skip-link:focus { left: 12px; }
Priority 2: Alt text — 30 to 90 minutes
Every <img> element must have an alt attribute. Axe lists every image missing one. Work through the list:
- Informational images — hero images, product screenshots, team photos, charts: write alt text that describes what the image communicates, not just what it depicts. “Screenshot of the dashboard showing a risk score of 78 with three WCAG failures listed” is useful. “Image” is not.
- Decorative images — dividers, background textures, icons paired with visible text: use
alt=""(empty string, not missing). This tells screen readers to skip the element entirely. - Linked images — an image wrapped in an
<a>tag: the alt text should describe the link destination, not the image. If the link goes to your pricing page,alt="View pricing", notalt="arrow icon". - CMS-managed images — if images come from a CMS (WordPress, Contentful, Sanity): add alt text in the media library. It propagates to all uses of that asset automatically, and filling in the alt field becomes the sustainable long-term process for editors.
Priority 3: Form labels — 30 to 60 minutes
Unlabeled form inputs are among the most common ADA demand letter citations. Axe flags every <input>, <select>, and <textarea> that lacks a programmatically associated label.
The standard fix — visible label:
<label for="email">Email address</label>
<input id="email" type="email" placeholder="you@example.com">
For single-input forms where a visible label would disrupt the layout:
<input type="email" aria-label="Email address" placeholder="you@example.com">
Placeholder text alone does not satisfy the label requirement — it disappears when the user starts typing and is not reliably announced by screen readers. Don’t overlook search bars, newsletter signup fields in footers, and subscribe inputs embedded in blog posts or sidebars. Those are just as exposed as the main contact form.
Priority 4: Color contrast — 1 to 2 hours, design sign-off usually needed
ShipSafe and Axe both flag text elements failing the 4.5:1 contrast ratio (or 3:1 for large text ≥ 18pt). This fix often requires a design decision — you’re changing a color that was chosen intentionally.
Systematic approach using CSS variables
If your site uses CSS custom properties for color — --color-text-muted, --text-secondary, etc. — changing the variable value fixes every instance at once:
:root {
/* Was #999999 (2.85:1 on white — fails) */
--text-muted: #767676; /* 4.54:1 on white — passes */
}
Use the WebAIM Contrast Checker to find the exact value that passes. The lightest grey that passes 4.5:1 on white is #767676. Anything lighter fails. If your codebase uses hardcoded hex values throughout, do a global find-and-replace for each failing color. Check placeholder text separately — it is subject to the same contrast ratio and is frequently overlooked.
Priority 5: Keyboard navigation — 2 to 4 hours
Keyboard navigation failures are not detectable by automated scanners — they require manual testing. Unplug your mouse and Tab through your entire site.
- Replace
<div onclick>with<button>— any interactive element built as a<div>or<span>with a click handler is invisible to keyboard users and screen readers. Native<button>elements come with keyboard accessibility and focus management built in. - Remove positive tabindex values —
tabindex="1",tabindex="2", etc. override the natural DOM order and almost always create a broken, unpredictable focus sequence. Search your codebase fortabindexwith values above 0 and remove them. Use DOM order to control focus, not tabindex. - Fix modal focus management — modals must: (a) move focus into the modal on open, (b) trap focus inside while the modal is open, (c) close on the Escape key, and (d) return focus to the triggering element on close. Each missing step is a WCAG 2.1.2 keyboard trap violation.
- Verify visible focus indicators — Tab through the page and confirm every focused element shows a visible ring. If you have
:focus { outline: none }globally (a common CSS reset), replace it with:focus-visible { outline: 2px solid #005fcc; outline-offset: 2px; }— this shows the ring for keyboard users but not mouse clicks.
Document every fix
Documentation is the evidence that you remediated in good faith. Courts weigh documented remediation significantly more favorably than an undocumented claim.
- Write descriptive git commit messages — “Fix unlabeled form inputs on contact and newsletter forms (WCAG 1.3.1 A)” is verifiable, timestamped evidence. “Fix accessibility stuff” is not.
- Save before-and-after scan screenshots — run ShipSafe before and after each priority block and save both results with the date visible. A documented before/after showing the issue count drop from 7 to 0 is concrete evidence of remediation.
- Add an accessibility statement — a publicly accessible page stating your commitment to WCAG 2.1 AA, a contact email for reporting accessibility issues, and the date of your last review. Add a link in your site footer. Courts and regulators view this as evidence of ongoing good faith.
Verify with ShipSafe after each priority block
Re-run ShipSafe after completing Priority 1–3 to confirm those items are resolved before investing time in Priority 4–5. ShipSafe catches the four failures most commonly cited in ADA demand letters — missing language attribute, unlabeled inputs, missing alt text, color contrast — and shows you an updated risk score. A clean result on those items before you begin the harder work confirms you’ve closed the highest-exposure gaps first.
Re-scan my site with ShipSafe →
Related ShipSafe guides:
- ADA compliance checklist — 30 testable WCAG 2.1 AA items to audit your site
- WCAG compliance for AI-generated sites — the 5 most-flagged gaps
- Received an ADA demand letter? Step-by-step response guide
- Do accessibility overlays prevent ADA lawsuits?
- How to fix missing alt text on images — WCAG 1.1.1 fix guide
Frequently asked questions
What WCAG failures should I fix first?
Fix the four failures that appear most often in ADA demand letters first: (1) missing lang attribute on the <html> element, (2) images without alt text, (3) unlabeled form inputs, and (4) missing skip navigation link. These can be addressed in under two hours and substantially reduce your litigation exposure. Color contrast and keyboard navigation are important but take longer and should follow once the critical items are resolved.
What tools do I need to find all accessibility failures?
Start with ShipSafe (paste your URL for a fast automated scan) and the Axe DevTools browser extension (free from Deque — available for Chrome, Firefox, and Edge). Together they catch approximately 30–40% of WCAG 2.1 AA criteria, including the failures most likely to appear in demand letters. After fixing those, do a keyboard-only walkthrough to find navigation failures automated tools can’t detect. For ARIA and dynamic content, test with VoiceOver on macOS or NVDA on Windows.
How do I fix missing alt text across an entire site efficiently?
Run Axe DevTools on your key pages — it lists every image missing an alt attribute with its element selector, so you can find it directly in the source. For informational images (photos, screenshots, charts), describe what the image communicates. For decorative images (dividers, background textures, icons that duplicate adjacent text), use alt="" so screen readers skip them. If images come from a CMS, adding alt text in the media library is the sustainable long-term fix — it propagates to all uses of the asset automatically.
How do I fix color contrast across an entire site efficiently?
If your site uses CSS custom properties for colors (e.g., --text-muted, --color-secondary), changing one variable value fixes every instance at once. Use the WebAIM Contrast Checker to find the hex value that passes 4.5:1, update the variable in your root CSS, then re-scan. The lightest grey that passes 4.5:1 on white is #767676. If your codebase uses hardcoded values, do a global find-and-replace. Don’t forget placeholder text — it’s subject to the same ratio and is frequently missed.
What’s the fastest single fix that reduces lawsuit risk the most?
Adding lang="en" to the <html> element is the fastest fix — 30 seconds, one attribute — and it resolves WCAG 3.1.1 Level A, one of the most commonly cited failures in ADA demand letters. Skip navigation is next: about 10 minutes of HTML and CSS that resolves WCAG 2.4.1 Level A. Neither requires a design decision or any visible change to the page, which makes them the ideal starting point regardless of what else needs fixing.
Do I need to fix accessibility on every page, or just the homepage?
Every publicly accessible page should meet WCAG 2.1 AA. In practice, ADA demand letters from automated-scan firms almost always cite only the homepage, since that’s what their scanner tested. Fix the homepage first — that’s the highest priority. However, the structural failures (missing lang, no skip nav, CSS contrast values) exist across all pages and are typically fixed in the site template, which propagates the fix to every page at once. Fix the template and you fix the whole site simultaneously.
How do I document my accessibility fixes for legal protection?
The most useful documentation is a timestamped git commit history with descriptive messages that name the specific criterion fixed — e.g., “Add lang attribute to html element (WCAG 3.1.1 A)”. Pair that with before-and-after ShipSafe scan screenshots saved with dates. An accessibility statement on your site — stating your WCAG 2.1 AA commitment, a contact email for reporting issues, and the date of your last review — completes the documented posture that courts weigh favorably. This combination of git history, scan evidence, and a public statement is the most defensible paper trail for a small business.
Also in the Copper Bay Labs suite
Accessibility is one layer of pre-launch risk. These free tools cover the rest:
Generate a privacy policy, terms of service, and cookie notice for your site — free, in your browser, no account.
Security headers HardenCheckScan your live site’s HTTP headers for missing CSP, HSTS, and other security hardening flags.
Secret scanning LeakCheckPaste code or a config file and see exposed API keys and secrets flagged before they reach the repo.
Post-deploy ExposureCheckScan your live URL for exposed .env files, .git directories, source maps, and bundled secrets.