<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Romain</title>
    <description>The latest articles on DEV Community by Romain (@lawebe).</description>
    <link>https://dev.to/lawebe</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3940661%2F59263845-5148-44e0-8c86-31d1fda90fc7.png</url>
      <title>DEV Community: Romain</title>
      <link>https://dev.to/lawebe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lawebe"/>
    <language>en</language>
    <item>
      <title>The Shopify Store Accessibility Checklist (WCAG 2.2)</title>
      <dc:creator>Romain</dc:creator>
      <pubDate>Tue, 19 May 2026 18:42:52 +0000</pubDate>
      <link>https://dev.to/lawebe/the-shopify-store-accessibility-checklist-wcag-22-2bd5</link>
      <guid>https://dev.to/lawebe/the-shopify-store-accessibility-checklist-wcag-22-2bd5</guid>
      <description>&lt;p&gt;&lt;strong&gt;Shopify's Dawn theme (and most marketplace themes) ships with several WCAG 2.2 issues out of the box. Here's a checklist we use when auditing Shopify stores, in priority order.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Critical (fail an audit on their own)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Color contrast&lt;/strong&gt; on sale price tags (red on light pink), placeholder text in inputs, and the cart drawer headers. Threshold: 4.5:1 normal text, 3:1 large/bold.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buttons without accessible names&lt;/strong&gt;: the icon-only quantity steppers (+ / −) often have no &lt;code&gt;aria-label&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Form labels&lt;/strong&gt; on the checkout: most "floating label" implementations fail when the label moves outside the input's accessible name.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Serious
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Carousel autoplay with no pause control.&lt;/li&gt;
&lt;li&gt;Keyboard trap in the predictive search drawer (focus stays inside even after closing).&lt;/li&gt;
&lt;li&gt;Modal product quick-view returns focus to the top of the page instead of the trigger.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  WCAG 2.2-specific
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Target size 2.5.8&lt;/strong&gt;: social icons in the footer are typically 16×16. Bump to 24×24 minimum.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drag movements 2.5.7&lt;/strong&gt;: any custom slider or sortable wishlist needs a click/tap fallback.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessible authentication 3.3.8&lt;/strong&gt;: Shopify's default checkout is fine; custom checkouts that ban paste in the password field fail this.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick wins
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Audit your &lt;code&gt;theme.liquid&lt;/code&gt; for hardcoded colors against your background tokens.&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;aria-label&lt;/code&gt; to every `` that contains only an icon or SVG.&lt;/li&gt;
&lt;li&gt;Set focus styles globally: &lt;code&gt;:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Test the keyboard tab order through a full checkout. If you can't complete a purchase keyboard-only, the score doesn't matter.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AccessProof scans Shopify stores out of the box (we follow redirects through the storefront) and groups findings by template so your dev team can fix them theme-wide instead of page-by-page.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://access-proof.com/blog/shopify-accessibility-checklist" rel="noopener noreferrer"&gt;access-proof.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>shopify</category>
      <category>ecommerce</category>
    </item>
    <item>
      <title>axe-core vs. Lighthouse: Which Catches More Accessibility Issues?</title>
      <dc:creator>Romain</dc:creator>
      <pubDate>Tue, 19 May 2026 18:42:21 +0000</pubDate>
      <link>https://dev.to/lawebe/axe-core-vs-lighthouse-which-catches-more-accessibility-issues-3624</link>
      <guid>https://dev.to/lawebe/axe-core-vs-lighthouse-which-catches-more-accessibility-issues-3624</guid>
      <description>&lt;p&gt;&lt;strong&gt;Lighthouse and axe-core are the two automated accessibility scanners most teams reach for. They share a heritage (Lighthouse's a11y category embeds axe-core), but they catch different things in practice. We ran both against 50 production websites — here's what we found.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;50 sites, mix of e-commerce, SaaS, and content (avg 8 issues/site between the two).&lt;/li&gt;
&lt;li&gt;Lighthouse 11 (default a11y category, mobile preset).&lt;/li&gt;
&lt;li&gt;axe-core 4.9 with rules at &lt;code&gt;wcag2a, wcag2aa, wcag21a, wcag21aa, wcag22aa&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;MetricLighthouseaxe-core 4.9&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Avg issues found per site4.27.8&lt;br&gt;
Unique rules triggered2756&lt;br&gt;
WCAG 2.2 coveragepartialfull&lt;br&gt;
False positive rate (manual review)~5%~3%&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  What axe-core catches that Lighthouse misses&lt;br&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;WCAG 2.2 target-size violations (2.5.8).&lt;/li&gt;
&lt;li&gt;ARIA misuse on custom widgets (axe is much stricter on role/state mismatch).&lt;/li&gt;
&lt;li&gt;Region/landmark issues on complex layouts.&lt;/li&gt;
&lt;li&gt;Color contrast on text inside images (axe has better OCR-aware checks).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Lighthouse adds
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Performance correlation: an accessibility score next to LCP/CLS gives leadership a single dashboard.&lt;/li&gt;
&lt;li&gt;Crawl-style scoring out of 100, easier to track over time at a high level.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Verdict
&lt;/h2&gt;

&lt;p&gt;Use both. Lighthouse is great for &lt;em&gt;tracking&lt;/em&gt; a top-line score in CI dashboards. axe-core is what you want when you need to &lt;em&gt;fix&lt;/em&gt; issues — its rule set is broader, its node-level reporting is more actionable, and it's the engine behind most professional audits. AccessProof runs axe-core under the hood, mapped to WCAG 2.2 and exportable as PDF.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://access-proof.com/blog/axe-core-vs-lighthouse-accessibility" rel="noopener noreferrer"&gt;access-proof.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>testing</category>
      <category>webdev</category>
    </item>
    <item>
      <title>You Got an ADA Demand Letter. Now What?</title>
      <dc:creator>Romain</dc:creator>
      <pubDate>Tue, 19 May 2026 18:36:39 +0000</pubDate>
      <link>https://dev.to/lawebe/you-got-an-ada-demand-letter-now-what-3c5p</link>
      <guid>https://dev.to/lawebe/you-got-an-ada-demand-letter-now-what-3c5p</guid>
      <description>&lt;p&gt;&lt;strong&gt;ADA-related demand letters targeting websites have grown roughly 14% year-over-year since 2018. If you just received one, here's what to do — and what &lt;em&gt;not&lt;/em&gt; to do — in the first 72 hours.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  First 24 hours
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Don't reply directly&lt;/strong&gt;. Forward to your lawyer (or get one) before any written communication. Anything you send becomes evidence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preserve the page state&lt;/strong&gt;. Take a full HTML + screenshot snapshot of the URL(s) cited in the letter, today's date. Their claims are time-bound; you need proof of what was live when.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run a baseline scan&lt;/strong&gt;. axe-core, WAVE, AccessProof — anything that produces a date-stamped issue list. This becomes the starting point of your remediation log.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Day 2–7
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Triage findings: critical/serious first (color contrast, missing labels, keyboard traps).&lt;/li&gt;
&lt;li&gt;Document each fix with a commit / ticket / dated entry. The paper trail matters more than the speed.&lt;/li&gt;
&lt;li&gt;Add an accessibility statement page (publicly linked from the footer) describing your standard, conformance level, contact, and remediation plan.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What reduces risk long-term
&lt;/h2&gt;

&lt;p&gt;Most plaintiffs settle out of court if you can show &lt;strong&gt;continuous, dated remediation activity&lt;/strong&gt;. A single audit means nothing; quarterly automated scans + a public statement + a contact form do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Negotiating directly with the plaintiff before counsel.&lt;/li&gt;
&lt;li&gt;Removing the offending page (looks like evidence destruction).&lt;/li&gt;
&lt;li&gt;Using an "accessibility overlay" widget. Courts increasingly view them as cosmetic; they don't fix underlying issues and may add new ones.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How AccessProof helps
&lt;/h2&gt;

&lt;p&gt;Each scan produces a dated, exportable PDF report. Schedule weekly or monthly scans, archive the PDFs, and you have the contemporaneous documentation that turns "we tried" into "we proved we tried".&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://access-proof.com/blog/ada-demand-letters-what-to-do" rel="noopener noreferrer"&gt;access-proof.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>ada</category>
      <category>legal</category>
    </item>
    <item>
      <title>WCAG 2.2: Every New Success Criterion Explained</title>
      <dc:creator>Romain</dc:creator>
      <pubDate>Tue, 19 May 2026 18:36:09 +0000</pubDate>
      <link>https://dev.to/lawebe/wcag-22-every-new-success-criterion-explained-36f4</link>
      <guid>https://dev.to/lawebe/wcag-22-every-new-success-criterion-explained-36f4</guid>
      <description>&lt;p&gt;&lt;strong&gt;WCAG 2.2 (published October 2023) introduced 9 new success criteria. Most of them target real-world friction points — touch targets, focus visibility, drag operations — rather than purely conceptual rules. Here's what each one means in practice.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The 9 new criteria
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.4.11 Focus Not Obscured (Minimum) — AA
&lt;/h3&gt;

&lt;p&gt;When an element receives focus, it must not be entirely hidden by sticky headers, banners, or modals. Common offender: a sticky cookie banner that covers the focused link in the menu just below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix&lt;/strong&gt;: scroll-padding-top equal to the sticky header height, or move focus to a position that accounts for the overlay.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.4.12 Focus Not Obscured (Enhanced) — AAA
&lt;/h3&gt;

&lt;p&gt;Same as above, but the focused element must be &lt;em&gt;fully&lt;/em&gt; visible (no partial occlusion).&lt;/p&gt;

&lt;h3&gt;
  
  
  2.4.13 Focus Appearance — AAA
&lt;/h3&gt;

&lt;p&gt;The focus indicator must have a minimum area (2 CSS px around the perimeter) and a 3:1 contrast ratio against the unfocused state. Killing the default outline without replacing it fails this.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.5.7 Dragging Movements — AA
&lt;/h3&gt;

&lt;p&gt;Anything done with a drag must be doable with a single pointer (click/tap). Sliders, kanban boards, signature pads — all need a non-drag fallback.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.5.8 Target Size (Minimum) — AA
&lt;/h3&gt;

&lt;p&gt;Interactive targets must be at least 24×24 CSS px (with exceptions for inline text and spacing-based equivalents). Tiny social icons in footers are the most common failure.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2.6 Consistent Help — A
&lt;/h3&gt;

&lt;p&gt;If a help mechanism is repeated across pages (chat widget, contact link), it must appear in the same relative location. Don't hide the chat on some pages.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3.7 Redundant Entry — A
&lt;/h3&gt;

&lt;p&gt;Within the same process, don't ask for information the user has already entered. Pre-fill or offer to reuse.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3.8 Accessible Authentication (Minimum) — AA
&lt;/h3&gt;

&lt;p&gt;Cognitive function tests (memorize, transcribe a captcha, identify objects) must have an alternative. Allow paste in password fields. Offer SSO or magic links.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3.9 Accessible Authentication (Enhanced) — AAA
&lt;/h3&gt;

&lt;p&gt;No cognitive function test at all, even with alternatives. Object-recognition CAPTCHAs disqualify you.&lt;/p&gt;

&lt;h2&gt;
  
  
  How AccessProof helps
&lt;/h2&gt;

&lt;p&gt;Of these, the criteria reliably catchable by automated tooling (axe-core 4.9+) are &lt;strong&gt;2.5.8 (target size)&lt;/strong&gt; and partial coverage of &lt;strong&gt;2.4.11 (focus obscured)&lt;/strong&gt;. The rest require manual review or process audit. AccessProof flags the automatable ones automatically and prompts you for the manual checks at the end of each scan.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://access-proof.com/blog/wcag-2-2-new-criteria-explained" rel="noopener noreferrer"&gt;access-proof.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>wcag</category>
    </item>
    <item>
      <title>What is axe-core and Why It Powers Real Accessibility Audits</title>
      <dc:creator>Romain</dc:creator>
      <pubDate>Tue, 19 May 2026 18:30:27 +0000</pubDate>
      <link>https://dev.to/lawebe/what-is-axe-core-and-why-it-powers-real-accessibility-audits-5e01</link>
      <guid>https://dev.to/lawebe/what-is-axe-core-and-why-it-powers-real-accessibility-audits-5e01</guid>
      <description>&lt;p&gt;&lt;strong&gt;If you've looked at any professional accessibility tool — Deque's axe DevTools, Microsoft's Accessibility Insights, Google's Lighthouse, WAVE's engine, or AccessProof — you've already touched axe-core. It's the open-source rules engine that quietly powers most evidence-based audits today. Here's what it actually does, why it's the standard, and how it compares to the “AI accessibility” overlay claims you've probably seen.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What axe-core is
&lt;/h2&gt;

&lt;p&gt;axe-core is an MIT-licensed accessibility testing engine maintained by &lt;a href="https://www.deque.com/axe/" rel="noopener noreferrer"&gt;Deque Systems&lt;/a&gt;. It runs in any environment that has a DOM — browsers, headless Chromium, Node — and returns a structured list of accessibility violations, each tied to a specific WCAG success criterion and DOM node.&lt;/p&gt;

&lt;p&gt;The source lives at &lt;a href="https://github.com/dequelabs/axe-core" rel="noopener noreferrer"&gt;github.com/dequelabs/axe-core&lt;/a&gt;. It ships rules for WCAG 2.0, 2.1, 2.2 (Level A, AA, AAA), plus Section 508 and best-practice checks. As of axe-core 4.9 (released 2024), the engine implements approximately 90 individual rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it actually checks
&lt;/h2&gt;

&lt;p&gt;axe-core works by walking the rendered DOM and evaluating each node against its rule set. Each rule produces one of four outcomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Violations&lt;/strong&gt;: definitively fails a WCAG criterion (e.g. &lt;code&gt;color-contrast&lt;/code&gt;, &lt;code&gt;label&lt;/code&gt;, &lt;code&gt;button-name&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Needs review&lt;/strong&gt;: cannot be determined automatically; flagged for manual review.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Passes&lt;/strong&gt;: rule was checked and the node passed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inapplicable&lt;/strong&gt;: the rule doesn't apply (e.g. no images on the page → no alt-text rule fires).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples of categories axe-core reliably catches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Color contrast against computed background (including against background images via canvas sampling).&lt;/li&gt;
&lt;li&gt;Missing or incorrect ARIA attributes and roles.&lt;/li&gt;
&lt;li&gt;Form fields without programmatic labels.&lt;/li&gt;
&lt;li&gt;Buttons and links without accessible names.&lt;/li&gt;
&lt;li&gt;Heading structure and landmark misuse.&lt;/li&gt;
&lt;li&gt;Keyboard traps detectable from static DOM analysis.&lt;/li&gt;
&lt;li&gt;WCAG 2.2 target size (Success Criterion 2.5.8).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the categories it deliberately doesn't cover (these need humans):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whether alt text is &lt;em&gt;meaningful&lt;/em&gt; (it can only check presence/absence).&lt;/li&gt;
&lt;li&gt;Whether headings describe the section they precede.&lt;/li&gt;
&lt;li&gt;Reading order in complex visual layouts.&lt;/li&gt;
&lt;li&gt;Whether a control's name is appropriate to its function.&lt;/li&gt;
&lt;li&gt;Live region behavior over time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This honesty about scope is exactly why axe-core became the trust anchor of the industry. &lt;a href="https://www.deque.com/axe/" rel="noopener noreferrer"&gt;Deque publicly documents&lt;/a&gt; that fully automated testing can catch a meaningful share of issues, but the precise share depends on the site. Some sites have mostly automatable issues (forms, content); others rely heavily on custom widgets where manual review is essential. axe-core scopes the half it can handle — accurately — instead of overclaiming.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why “AI accessibility” overlays don't replace it
&lt;/h2&gt;

&lt;p&gt;Overlay widgets (accessiBe, UserWay, AudioEye) promise to “fix” accessibility by injecting JavaScript that mutates the page at runtime. The promise sounds appealing; the practical issues are well documented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Overlays operate &lt;strong&gt;downstream&lt;/strong&gt; of the underlying HTML/CSS. They can't fix a button that has no semantic role; they can only paper over it. Screen readers can still expose the broken markup beneath.&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://overlayfactsheet.com/" rel="noopener noreferrer"&gt;Overlay Fact Sheet&lt;/a&gt; — signed by 800+ accessibility professionals including the authors of axe-core — lists technical reasons overlays often introduce &lt;em&gt;new&lt;/em&gt; issues (keyboard focus stealing, ARIA conflicts, autoplay sounds).&lt;/li&gt;
&lt;li&gt;Courts have allowed lawsuits to proceed against sites that installed an overlay as their primary remediation. The widget's presence is not a defense.&lt;/li&gt;
&lt;li&gt;Most overlays don't produce an auditable, dated report of what they fixed. Plaintiff counsel asks for one. You don't have it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The alternative is to &lt;em&gt;measure&lt;/em&gt; the underlying site — axe-core's job — and fix what's actually broken in the source code. &lt;a href="https://dev.to/compare/accessibe-alternative"&gt;See our side-by-side comparison vs. overlay vendors&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How AccessProof uses axe-core
&lt;/h2&gt;

&lt;p&gt;We vendor axe-core 4.9.1 — the version is pinned, the file is shipped with our scanner image, and we don't fetch it from a CDN at scan time. This matters because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reproducibility&lt;/strong&gt;: the same scan today and 6 months from now uses the same engine version. The deltas in your reports reflect changes to &lt;em&gt;your&lt;/em&gt; site, not engine drift.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSP-friendly&lt;/strong&gt;: vendoring lets us run axe-core inside a headless Chromium even on sites with strict Content Security Policies that would block an external CDN script.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auditable&lt;/strong&gt;: anyone inspecting a PDF report can verify which axe-core version produced it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We run axe-core with the &lt;code&gt;wcag2a, wcag2aa, wcag21a, wcag21aa, wcag22aa&lt;/code&gt; rule sets enabled, then translate the violation list into a scored report (critical / serious / moderate / minor), and render it to a dated PDF. The PDF is the artifact you keep in your remediation log.&lt;/p&gt;

&lt;p&gt;Want to see a real one? &lt;a href="https://dev.to/free-wcag-scan"&gt;Run a free scan&lt;/a&gt; — no signup needed for the first one.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to interpret axe-core impact levels
&lt;/h2&gt;

&lt;p&gt;Each violation comes with an impact level: &lt;code&gt;critical&lt;/code&gt;, &lt;code&gt;serious&lt;/code&gt;, &lt;code&gt;moderate&lt;/code&gt;, or &lt;code&gt;minor&lt;/code&gt;. These are not WCAG-defined — Deque assigns them based on user impact severity. A rough mapping:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Critical&lt;/strong&gt;: blocks a user from completing core tasks (missing button label, keyboard trap, empty links).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serious&lt;/strong&gt;: degrades the experience significantly (insufficient contrast, missing form labels).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Moderate&lt;/strong&gt;: noticeable but not blocking (ARIA attribute on wrong element, redundant landmarks).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minor&lt;/strong&gt;: edge case or convention (page region missing).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For triage, fix critical and serious before anything else. AccessProof's scoring algorithm weights them &lt;code&gt;critical × 4 + serious × 2 + moderate × 1 + minor × 0.5&lt;/code&gt; on a 100-point scale — the same weighting Deque suggests in its documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The other engines, briefly
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WAVE&lt;/strong&gt; (WebAIM) is an excellent rules engine in its own right, with a strong visual UI. We've found it slightly more lenient on color contrast edge cases than axe-core but generally aligned on critical violations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lighthouse's accessibility category&lt;/strong&gt; uses axe-core under the hood but runs a curated subset. Treat the Lighthouse score as a starting indicator, not an audit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility Insights&lt;/strong&gt; (Microsoft) also uses axe-core, paired with an assisted manual test workflow. Recommended for in-team adoption.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How widely it's actually used
&lt;/h2&gt;

&lt;p&gt;axe-core sits inside the accessibility tooling of many of the largest software organizations. Some confirmed integrations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Google Lighthouse&lt;/strong&gt; uses a curated axe-core rule subset in its Accessibility category.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microsoft Accessibility Insights&lt;/strong&gt; (web and desktop) is built on axe-core with manual-assist workflows added on top.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deque axe DevTools&lt;/strong&gt;, both the free browser extension and the paid enterprise products, all run the same axe-core engine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Salesforce, IBM, GitHub, and many other major SaaS vendors&lt;/strong&gt; use it in CI per public talks and engineering posts.&lt;/li&gt;
&lt;li&gt;Web framework starter kits and accessibility linters (eslint-plugin-jsx-a11y, etc.) frequently cite axe-core's rule definitions as their reference.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open-source rules engines benefit from network effects: the more eyes on the rules, the faster false positives are caught and the faster new WCAG criteria get covered. Closed engines invariably trail.&lt;/p&gt;

&lt;h2&gt;
  
  
  How axe-core decides what is a violation
&lt;/h2&gt;

&lt;p&gt;Each axe-core rule is a function that runs against a node and returns pass/fail/needs-review. The rules are versioned in the GitHub repo and discussed openly in issues and PRs. When the W3C publishes a new WCAG version, Deque maintainers and community contributors implement supporting rules — that's how WCAG 2.2 support landed in axe-core 4.8 and 4.9.&lt;/p&gt;

&lt;p&gt;For a concrete example, here's the kind of result axe-core produces for a single contrast violation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color-contrast"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"impact"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"serious"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"cat.color"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wcag2aa"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wcag143"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nodes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"#hero p.subtitle"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Get started in 60 seconds
"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"failureSummary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Element has insufficient color contrast of 3.21 (foreground color: #9ca3af, background color: #ffffff, font size: 14.0pt, font weight: normal). Expected contrast ratio of 4.5:1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That single record gives you the rule, the WCAG mapping, the impact level, the exact CSS selector, the computed ratio, the colors involved, the font size, and the threshold it failed against. This level of specificity is what makes axe-core useful for engineers and credible in audit reports — the “evidence” is right there in the artifact.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it costs to use directly
&lt;/h2&gt;

&lt;p&gt;axe-core is MIT-licensed and free. If you're comfortable with Node and Playwright/Puppeteer, you can integrate it into your CI in an afternoon:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;axe&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;core&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;playwright&lt;/span&gt;
&lt;span class="c1"&gt;// in a Playwright test&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accessibilityScanResults&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AxeBuilder&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withTags&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wcag2a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wcag2aa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wcag21aa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wcag22aa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;analyze&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accessibilityScanResults&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What you don't get out of the box: scheduling, history, scoring, PDF export, multi-page crawl, evidence retention. That's the layer hosted services like AccessProof add on top. The engine itself is identical; the operational glue is where vendors differ.&lt;/p&gt;

&lt;h2&gt;
  
  
  Versioning and the audit-trail question
&lt;/h2&gt;

&lt;p&gt;Because axe-core evolves — new rules ship, existing rules get stricter — anyone who keeps long-term audit history should record which version produced each report. A 2024 PDF that says “axe-core 4.9.1” in the footer is reproducible: you can re-run the same version against an archived copy of your site and get the same answer.&lt;/p&gt;

&lt;p&gt;Vendors that hide their engine version (or use a custom unpublished rule set) make this kind of reproducibility impossible. Ask for the version in every PDF or HTML report your tool generates. AccessProof prints it on every page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;axe-core is the rules engine that turns “accessibility” from a vague aspiration into a measurable set of pass/fail checks. It's open source, transparent about what it can't check, and used by the people who set the standard. If your accessibility tool isn't built on it (or one of the open engines with comparable transparency), ask what it's built on — and what its false positive rate is on your stack.&lt;/p&gt;

&lt;p&gt;AccessProof uses axe-core because the alternative — running our own opaque scorer or, worse, an overlay — wouldn't produce evidence anyone could trust. &lt;a href="https://dev.to/pricing"&gt;See pricing&lt;/a&gt; if you'd like to add scheduled, dated, axe-core-backed audits to your remediation log.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://access-proof.com/blog/what-is-axe-core-evidence-based-audits" rel="noopener noreferrer"&gt;access-proof.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>testing</category>
      <category>webdev</category>
    </item>
    <item>
      <title>ADA Web Accessibility Lawsuit Checklist for 2026</title>
      <dc:creator>Romain</dc:creator>
      <pubDate>Tue, 19 May 2026 18:29:57 +0000</pubDate>
      <link>https://dev.to/lawebe/ada-web-accessibility-lawsuit-checklist-for-2026-32gh</link>
      <guid>https://dev.to/lawebe/ada-web-accessibility-lawsuit-checklist-for-2026-32gh</guid>
      <description>&lt;p&gt;&lt;strong&gt;In 2024, U.S. federal courts saw more than 4,000 ADA Title III website-accessibility lawsuits — UsableNet's annual report counted &lt;a href="https://blog.usablenet.com/2024-ada-website-lawsuit-report" rel="noopener noreferrer"&gt;4,536 filings against 2,452 unique defendants&lt;/a&gt;. Plaintiffs continue to target small and mid-size online businesses alongside enterprise. This checklist tells you what to put in place &lt;em&gt;before&lt;/em&gt; a demand letter arrives.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why 2026 looks different
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;April 2024 DOJ Title II rule&lt;/strong&gt;: the Department of Justice finalized a rule requiring state and local government web content to meet &lt;a href="https://www.ada.gov/resources/2024-03-08-web-rule/" rel="noopener noreferrer"&gt;WCAG 2.1 Level AA&lt;/a&gt;. Title II is for public entities, but it sets a public conformance bar plaintiffs cite when arguing about Title III (private businesses).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;European Accessibility Act (EAA) enforcement began 28 June 2025&lt;/strong&gt;. Many U.S. businesses with EU customers (e-commerce, SaaS, banking) are now in scope under EU law in parallel with ADA at home. See the &lt;a href="https://accessibility.blog.gov.uk/" rel="noopener noreferrer"&gt;EU Commission resources&lt;/a&gt; for sector applicability.&lt;/li&gt;
&lt;li&gt;Courts continue to look unfavorably on “accessibility overlay” widgets as a sole remediation. Several 2023–2024 decisions allowed cases to proceed despite an overlay being installed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The 2026 checklist
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Pick a target standard and write it down
&lt;/h3&gt;

&lt;p&gt;WCAG 2.1 Level AA is the de facto bar referenced by the DOJ. WCAG 2.2 (October 2023) adds 9 success criteria you should adopt; conforming to 2.2 AA implies 2.1 AA. Publish your chosen standard in your accessibility statement so plaintiffs and courts know what you're aiming at.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Publish an accessibility statement
&lt;/h3&gt;

&lt;p&gt;A statement should include: target standard (e.g. “WCAG 2.2 AA”), conformance level (full / partial), date of last audit, contact method (email + phone), and a remediation timeline. Link it from your footer on every page. Templates and guidance: &lt;a href="https://www.w3.org/WAI/planning/statements/" rel="noopener noreferrer"&gt;W3C WAI&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Run a dated baseline audit
&lt;/h3&gt;

&lt;p&gt;Use an automated scanner (axe-core, WAVE, AccessProof) plus at least one manual screen reader pass. Export the result with a timestamp and store it. Today's baseline is tomorrow's evidence that you started.&lt;/p&gt;

&lt;p&gt;If you don't have a baseline yet, &lt;a href="https://dev.to/free-wcag-scan"&gt;AccessProof's free scanner&lt;/a&gt; produces a dated PDF in under 90 seconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Fix the critical and serious issues first
&lt;/h3&gt;

&lt;p&gt;Plaintiff firms cite a relatively small set of patterns repeatedly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Missing alt text on informative images (WCAG 1.1.1).&lt;/li&gt;
&lt;li&gt;Form fields without labels (WCAG 1.3.1, 3.3.2).&lt;/li&gt;
&lt;li&gt;Color contrast failures (WCAG 1.4.3).&lt;/li&gt;
&lt;li&gt;Keyboard inaccessible controls (WCAG 2.1.1).&lt;/li&gt;
&lt;li&gt;Missing or duplicate page titles (WCAG 2.4.2).&lt;/li&gt;
&lt;li&gt;Empty or unclear link text (“click here”) (WCAG 2.4.4).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the ones automated tooling catches and plaintiffs screenshot. Address them first, regardless of WCAG level.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Document remediation with dates
&lt;/h3&gt;

&lt;p&gt;Commit messages, ticket IDs, before/after screenshots, dated PDF reports — every fix should leave a paper trail. Courts and counsel are persuaded by &lt;em&gt;continuous, dated activity&lt;/em&gt; far more than by “we did an audit once.”&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Schedule recurring scans
&lt;/h3&gt;

&lt;p&gt;Monthly minimum, weekly preferred. The 2018 Robles v. Domino's outcome and most subsequent settlements reinforce the same expectation: regressions are inevitable, and the standard is whether you detect and fix them quickly. AccessProof runs scans automatically on a schedule and archives every PDF — &lt;a href="https://dev.to/pricing"&gt;starter plans&lt;/a&gt; begin at weekly cadence.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Train at least one developer to use a screen reader
&lt;/h3&gt;

&lt;p&gt;30 minutes per release using NVDA (Windows / Firefox) or VoiceOver (Mac / Safari) catches issues no automated tool can — reading order, live region announcements, custom widget patterns. Free, no certifications required.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Have counsel on speed dial
&lt;/h3&gt;

&lt;p&gt;Pre-identify counsel familiar with ADA Title III litigation in your state. If a demand letter arrives, do not negotiate directly. Forward to counsel within 24 hours.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Avoid overlay widgets as a sole remedy
&lt;/h3&gt;

&lt;p&gt;An overlay can be one layer of defense in depth, but courts now scrutinize them. The &lt;a href="https://overlayfactsheet.com/" rel="noopener noreferrer"&gt;Overlay Fact Sheet&lt;/a&gt; (signed by 800+ accessibility professionals) catalogs the limitations. Don't rely on an overlay as your only remediation.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Review your third-party widgets
&lt;/h3&gt;

&lt;p&gt;Chat widgets, video players, payment iframes, signup forms — third-party code accounts for a significant share of failures on e-commerce and SaaS sites. Audit each integration and request accessibility statements from vendors. Cite them in your own statement (“Component X is provided by vendor Y; their conformance status: Z”).&lt;/p&gt;

&lt;h2&gt;
  
  
  What a court-ready audit trail looks like
&lt;/h2&gt;

&lt;p&gt;If you receive a demand letter and have all of these on file, you start the conversation from a defensible position:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An accessibility statement on every page, dated within the last 12 months.&lt;/li&gt;
&lt;li&gt;A series of dated PDF audit reports (monthly or weekly cadence).&lt;/li&gt;
&lt;li&gt;A public remediation log or changelog showing fixes shipped.&lt;/li&gt;
&lt;li&gt;A documented incident response process for accessibility complaints.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The difference between a $20,000 settlement and a $5,000 settlement is often the strength of this documentation alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One-time audit, no follow-up.&lt;/strong&gt; A single audit ages fast; the site changes, the standards evolve, regressions creep in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Removing the offending page.&lt;/strong&gt; Looks like evidence destruction. Fix it instead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overlay-only remediation.&lt;/strong&gt; Documented in court rulings as insufficient.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treating accessibility as a project, not a process.&lt;/strong&gt; The expectation is ongoing conformance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where AccessProof fits
&lt;/h2&gt;

&lt;p&gt;AccessProof runs axe-core 4.9+ against your site on a schedule, scores it against WCAG 2.2, and produces a dated PDF after every scan. The PDFs are designed to be exportable as part of a remediation log. Compared to overlay widgets, we don't inject JavaScript into your site — we measure it. See our &lt;a href="https://dev.to/compare/accessibe-alternative"&gt;comparison vs. accessiBe&lt;/a&gt; for the detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  A short timeline of how we got here
&lt;/h2&gt;

&lt;p&gt;Understanding the trajectory helps explain why 2026 looks different from 2018:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1990&lt;/strong&gt;: ADA signed into law. Title III applies to “places of public accommodation”; the question of whether websites count was unresolved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2018&lt;/strong&gt;: &lt;em&gt;Robles v. Domino's Pizza&lt;/em&gt; — the Ninth Circuit held that the ADA applies to Domino's website because it had a nexus to a physical place. SCOTUS declined to review.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2019–2023&lt;/strong&gt;: Federal filings of Title III website cases stabilized around 2,000–4,000 per year per &lt;a href="https://blog.usablenet.com/" rel="noopener noreferrer"&gt;UsableNet's annual reports&lt;/a&gt;. New York and California remain dominant venues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2024&lt;/strong&gt;: DOJ finalizes its Title II web rule for state and local government. Title III rulemaking remains pending, but the Title II rule defines “technical standard” as WCAG 2.1 AA, signaling DOJ's view.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;June 2025&lt;/strong&gt;: European Accessibility Act enforcement begins. U.S. businesses serving EU consumers in covered sectors are now in scope.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The macro trend is consistent: courts and regulators expect WCAG conformance, plaintiffs file at scale, and overlay-only remediation is increasingly disfavored.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sector-specific notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;E-commerce&lt;/strong&gt;: highest volume of lawsuits. The product page → cart → checkout flow is the path plaintiffs test most. Audit that flow weekly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SaaS&lt;/strong&gt;: dashboards and onboarding flows are commonly cited. Trial signup pages get tested before paying-customer flows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hospitality / travel&lt;/strong&gt;: room-selection widgets, date pickers, and PDF menus are frequent flagged elements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Healthcare&lt;/strong&gt;: patient portals are subject to both ADA and HHS Section 504/1557 standards. Multi-standard compliance is essential.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Government contractors&lt;/strong&gt;: Section 508 compliance is its own statute; the technical standard is WCAG 2.0 AA per the 2017 refresh.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cost of doing nothing vs. cost of compliance
&lt;/h2&gt;

&lt;p&gt;Typical settlement amounts for ADA web Title III cases reported in trade press range from a few thousand to mid-five-figures, plus mandatory remediation. Annual programmatic compliance — automated scans, a part-time accessibility engineer or service, periodic manual audits — generally costs less than a single contested case. The ROI argument writes itself; the question is operational discipline.&lt;/p&gt;

&lt;h2&gt;
  
  
  What plaintiffs actually look for
&lt;/h2&gt;

&lt;p&gt;Demand letters and complaints we've seen cite a remarkably consistent set of evidence:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Screenshots of the homepage and product/service pages with annotations showing missing alt text or contrast failures.&lt;/li&gt;
&lt;li&gt;Automated scanner output (often WAVE or axe DevTools) included as appendix.&lt;/li&gt;
&lt;li&gt;Specific quotes from your accessibility statement (or absence thereof) used against you.&lt;/li&gt;
&lt;li&gt;Comparison against your competitor's site if they have better conformance.&lt;/li&gt;
&lt;li&gt;Records of past complaints unanswered or unresolved.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This shapes the defense strategy: if the same scanner the plaintiff used produces a clean (or rapidly-improving) report on your dated audits, you neutralize the strongest evidence early.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vendor and procurement considerations
&lt;/h2&gt;

&lt;p&gt;If you sell to enterprise or government, your accessibility posture is a procurement input:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VPAT (Voluntary Product Accessibility Template)&lt;/strong&gt; using &lt;a href="https://www.itic.org/policy/accessibility/vpat" rel="noopener noreferrer"&gt;ITI's template&lt;/a&gt; — increasingly required by procurement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ACR (Accessibility Conformance Report)&lt;/strong&gt; — the executive summary that wraps a VPAT.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Section 508 conformance&lt;/strong&gt; for U.S. federal contracts (WCAG 2.0 AA per the 2017 refresh).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EN 301 549&lt;/strong&gt; for European procurement (incorporates WCAG 2.1 AA + non-web criteria).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you don't have a VPAT, you'll lose deals before you ever hear about a lawsuit. A current VPAT typically requires a documented audit, which is the same artifact your remediation log needs anyway.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation cadence
&lt;/h2&gt;

&lt;p&gt;The defensible operational rhythm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Weekly&lt;/strong&gt;: automated scan of critical flows (homepage, signup, checkout, account).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monthly&lt;/strong&gt;: review the scan deltas, file tickets, close the previous month's.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quarterly&lt;/strong&gt;: manual screen-reader walkthrough of the same critical flows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Annually&lt;/strong&gt;: third-party audit (paid). Refresh VPAT.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continuously&lt;/strong&gt;: open contact channel for accessibility complaints, monitored by a named owner.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cadence doesn't need to be heavy. It needs to be &lt;em&gt;documented&lt;/em&gt; and &lt;em&gt;actually executed&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The simplest first step
&lt;/h2&gt;

&lt;p&gt;If you have nothing in place today, start here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run a free baseline scan. &lt;a href="https://dev.to/free-wcag-scan"&gt;AccessProof free scanner&lt;/a&gt; gives you a dated PDF in 90 seconds.&lt;/li&gt;
&lt;li&gt;Publish an accessibility statement (W3C templates are free). Add it to your footer.&lt;/li&gt;
&lt;li&gt;Triage the top 10 critical/serious findings with your dev team.&lt;/li&gt;
&lt;li&gt;Schedule a recurring scan — weekly minimum. &lt;a href="https://dev.to/pricing"&gt;Starter plans&lt;/a&gt; at AccessProof cover this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That sequence — baseline + statement + remediation + recurring scan — is the difference between “we tried” and “we have evidence we tried.”&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article is general guidance, not legal advice. Always consult counsel for your specific situation.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://access-proof.com/blog/ada-web-accessibility-lawsuit-checklist-2026" rel="noopener noreferrer"&gt;access-proof.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>ada</category>
      <category>legal</category>
    </item>
    <item>
      <title>How to Fix Common WCAG Color Contrast Failures</title>
      <dc:creator>Romain</dc:creator>
      <pubDate>Tue, 19 May 2026 18:24:15 +0000</pubDate>
      <link>https://dev.to/lawebe/how-to-fix-common-wcag-color-contrast-failures-2jln</link>
      <guid>https://dev.to/lawebe/how-to-fix-common-wcag-color-contrast-failures-2jln</guid>
      <description>&lt;p&gt;&lt;strong&gt;Color contrast is the most frequently reported WCAG violation in automated audits. WebAIM's 2024 analysis of the top 1,000,000 home pages found that &lt;a href="https://webaim.org/projects/million/" rel="noopener noreferrer"&gt;low-contrast text was detected on 81.0% of sites&lt;/a&gt;. The good news: 90% of contrast failures fall into 6 repeatable patterns. Fix those and your scan score jumps overnight.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Placeholder text that disappears into the input
&lt;/h2&gt;

&lt;p&gt;Default browser placeholders render at roughly &lt;code&gt;#757575&lt;/code&gt; on &lt;code&gt;#ffffff&lt;/code&gt;, which clocks 4.48:1 — fails WCAG 2.1 SC 1.4.3 (AA, needs 4.5:1). Most design systems override placeholders to a lighter grey and silently break compliance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt; (fails, 3.5:1):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="nd"&gt;::placeholder&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#9ca3af&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c"&gt;/* Tailwind gray-400 on white */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt; (passes, 4.83:1):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="nd"&gt;::placeholder&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#6b7280&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c"&gt;/* Tailwind gray-500 on white */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tailwind users: &lt;code&gt;placeholder:text-gray-500&lt;/code&gt; passes on white backgrounds. &lt;code&gt;placeholder:text-gray-400&lt;/code&gt; does not.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Brand-colored buttons with white text
&lt;/h2&gt;

&lt;p&gt;Brand greens, oranges, and yellows are the usual offenders. A primary call-to-action like &lt;code&gt;#22c55e&lt;/code&gt; (Tailwind green-500) on white text returns 2.18:1 — failing both normal and large text thresholds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick fix&lt;/strong&gt;: shift the brand color down 100–200 steps in your scale for any button surface that contains text.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Fails: 2.18:1 */&lt;/span&gt;
&lt;span class="nc"&gt;.btn-primary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#22c55e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Passes: 4.54:1 */&lt;/span&gt;
&lt;span class="nc"&gt;.btn-primary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#15803d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If marketing won't let you darken the brand color, dark text on a light tint of the same hue is a frequent compromise:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.btn-primary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#dcfce7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#14532d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c"&gt;/* 9.4:1, AAA */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Sale price tags (red on pink)
&lt;/h2&gt;

&lt;p&gt;Especially common on e-commerce templates. The default red &lt;code&gt;#ef4444&lt;/code&gt; on a pink chip &lt;code&gt;#fee2e2&lt;/code&gt; returns 3.4:1 — fails for normal text. This pattern accounts for a measurable share of e-commerce contrast failures in the audits we run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix&lt;/strong&gt;: use a darker red for the text, keep the chip light:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.sale-tag&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fee2e2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#991b1b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c"&gt;/* 6.6:1, AA */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to scan your site for this pattern and 50+ other WCAG checks, &lt;a href="https://dev.to/free-wcag-scan"&gt;try AccessProof's free scanner&lt;/a&gt; — it points to the exact node, the computed ratio, and the WCAG level that fails.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Disabled states that lie about being disabled
&lt;/h2&gt;

&lt;p&gt;WCAG 1.4.3 explicitly exempts disabled UI components from the contrast rule (Understanding SC 1.4.3, “inactive” clause). But the exemption only applies if the disabled state is unambiguously communicated to assistive tech.&lt;/p&gt;

&lt;p&gt;If your “disabled” button is just visually greyed out with no &lt;code&gt;aria-disabled&lt;/code&gt; or &lt;code&gt;disabled&lt;/code&gt; attribute, screen reader users still treat it as interactive — and the contrast rule applies again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Submit

Submit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Text over hero images
&lt;/h2&gt;

&lt;p&gt;Contrast is measured pixel-by-pixel against the actual background — not the average. A white heading on a hero photo can pass on the dark left third and fail on the bright right third. Automated scanners often flag this even when it “looks fine” in design review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reliable fix&lt;/strong&gt;: a semi-transparent dark overlay on the image. &lt;code&gt;rgba(0,0,0,0.4)&lt;/code&gt; brings most photos under control without crushing the visual.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.hero&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;.45&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;.45&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="sx"&gt;url(/hero.jpg)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.hero&lt;/span&gt; &lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c"&gt;/* now reliably &amp;gt;7:1 */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For text-heavy sections, prefer a solid background block behind the text rather than relying on the image to behave.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Focus rings that vanish
&lt;/h2&gt;

&lt;p&gt;WCAG 1.4.11 (Non-text Contrast, AA) requires UI components — including focus indicators — to have at least 3:1 contrast against adjacent colors. Removing the default outline without replacing it is the single most common keyboard-accessibility failure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Catastrophic: removes focus indication entirely */&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nd"&gt;:focus&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Compliant: visible, high contrast, matches brand */&lt;/span&gt;
&lt;span class="nd"&gt;:focus-visible&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#1142ff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;outline-offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;:focus-visible&lt;/code&gt; (not &lt;code&gt;:focus&lt;/code&gt;) so mouse users don't see the ring on click while keyboard users still get it on Tab.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to verify your fixes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WebAIM Contrast Checker&lt;/strong&gt; (free, single pair) — sanity check the ratio you computed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;axe DevTools&lt;/strong&gt; browser extension — find every failing node on a page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AccessProof&lt;/strong&gt; — scan the whole site against WCAG 2.2, get a dated PDF with every node and computed ratio. Re-scan after the fix to confirm. &lt;a href="https://dev.to/pricing"&gt;See pricing&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  One pattern to adopt: a contrast-aware design token set
&lt;/h2&gt;

&lt;p&gt;Rather than chasing failures, define your palette so failures are impossible. For every accent color, ship at least one paired text color that hits 4.5:1 and one that hits 3:1 — and use only those pairings in components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* tokens.css */&lt;/span&gt;
&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--accent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1142ff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c"&gt;/* brand */&lt;/span&gt;
  &lt;span class="py"&gt;--accent-on-light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0b2fb8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* 7.0:1 on white */&lt;/span&gt;
  &lt;span class="py"&gt;--on-accent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c"&gt;/* 8.2:1 on --accent */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reviewers stop asking “is this readable?” because the system can't produce an unreadable combination.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing a fix in 30 seconds
&lt;/h2&gt;

&lt;p&gt;Before re-running a full scan, sanity-check a fix with the WebAIM Contrast Checker or your browser's DevTools color picker (Chrome and Firefox both display the computed ratio inline when you select a foreground color in the Inspector). If the ratio meets the threshold in the inspector, the change will hold at scan time.&lt;/p&gt;

&lt;p&gt;One subtlety: the inspector shows the ratio for the styled foreground/background pair. If your background is actually an inherited color or a stacked semi-transparent surface, the inspector and the scanner may compute different effective backgrounds. axe-core walks the layout to find the actual rendered background pixel; that's why a fix that “looks fine” in DevTools can still fail an audit. When that happens, simplify the stack: replace stacked transparencies with a single opaque color, or place a wrapper with an explicit background behind the text.&lt;/p&gt;

&lt;h2&gt;
  
  
  The math behind the ratios
&lt;/h2&gt;

&lt;p&gt;The WCAG contrast ratio is a relative luminance calculation defined in &lt;a href="https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio" rel="noopener noreferrer"&gt;WCAG 2.1 §1.4.3&lt;/a&gt;. The formula:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ratio = (L1 + 0.05) / (L2 + 0.05)
where L1 = luminance of the lighter color, L2 of the darker.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luminance itself is computed by linearizing each sRGB channel and weighting them &lt;code&gt;0.2126·R + 0.7152·G + 0.0722·B&lt;/code&gt;. You don't need to do this by hand — every modern tool implements it — but understanding it explains two common surprises:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Green contributes ~72% of perceived brightness. That's why brand greens often pass thresholds that brand blues fail.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;+ 0.05&lt;/code&gt; term means very dark and very light pairs plateau. Going from &lt;code&gt;#000&lt;/code&gt; to &lt;code&gt;#0a0a0a&lt;/code&gt; against white barely moves the ratio.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common Tailwind pairings that pass and fail
&lt;/h2&gt;

&lt;p&gt;For teams that live in Tailwind, here's a quick reference (background → text):&lt;/p&gt;

&lt;p&gt;BackgroundTextRatioWCAG AA normal&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;whitegray-4003.0:1fail
whitegray-5004.83:1pass
whitegray-6007.0:1pass (AAA)
whiteblue-5004.0:1fail
whiteblue-6005.2:1pass
green-500 (#22c55e)white2.18:1fail
green-700 (#15803d)white4.54:1pass
red-100red-8006.6:1pass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If your design system standardizes on these pairings, contrast violations stop appearing in your audits.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 24-pixel rule for touch targets (related but distinct)
&lt;/h2&gt;

&lt;p&gt;Strictly speaking, target size is WCAG 2.5.8 (AA), not a contrast rule — but it's the issue that hides next to contrast failures on most automated reports, so we cover it here. Interactive elements must be at least 24×24 CSS pixels.&lt;/p&gt;

&lt;p&gt;The most common offender: social media icons in the footer rendered at 16×16. Even when the contrast of the icon itself passes, the target size fails, and screen-pixel-level tools group them in the same “low-impact UI” bucket.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Fails 2.5.8 */&lt;/span&gt;
&lt;span class="nc"&gt;.social-icon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Passes — uses padding to reach 24x24 without resizing the icon */&lt;/span&gt;
&lt;span class="nc"&gt;.social-icon-wrap&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your social icons live in tight footer rows, the padding-based approach keeps the visual size intact while meeting the rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  Patterns we keep seeing in real audits
&lt;/h2&gt;

&lt;p&gt;Across hundreds of scans, six anti-patterns account for the lion's share of contrast failures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gray-on-gray secondary text&lt;/strong&gt; — designers reaching for “subtle” tones without checking the ratio.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pastel buttons with white text&lt;/strong&gt; — pastels saturate but don't darken; white text always loses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Underline-less link colors&lt;/strong&gt; matching surrounding text within 3:1 — fails WCAG 1.4.1 (color isn't the only differentiator) if you also rely on color alone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Translucent overlays&lt;/strong&gt; in modal headers that drop the effective contrast below threshold.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Toast notifications&lt;/strong&gt; with colored text on colored backgrounds — green success on light green is the canonical example.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Form helper text&lt;/strong&gt; below inputs in &lt;code&gt;#9ca3af&lt;/code&gt;. Bump to &lt;code&gt;#6b7280&lt;/code&gt; or darker.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Train one designer and one engineer on these patterns and you'll prevent ~40% of contrast issues at the design-review stage.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about dark mode?
&lt;/h2&gt;

&lt;p&gt;Most contrast bugs hide in dark mode because designers eyeball it less. Run the same six checks in your dark theme. A typical failure: bright accent colors that worked on white are now too saturated against a near-black background, especially blues and purples that lose perceived contrast on dark surfaces.&lt;/p&gt;

&lt;p&gt;If you toggle &lt;code&gt;dark:&lt;/code&gt; variants in Tailwind, make sure every &lt;code&gt;text-*&lt;/code&gt; color in a component has a corresponding dark mode pair tested against your &lt;code&gt;bg-gray-900&lt;/code&gt; or whatever your dark surface is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Color contrast is solved by patterns, not heroics. Fix placeholders, brand buttons, sale tags, disabled states, hero text, and focus rings — you'll close the majority of contrast issues a typical audit will find. Adopt a contrast-aware token set and the issue stops recurring. Re-scan, generate a dated report, and move on to the harder stuff.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://access-proof.com/blog/fix-wcag-color-contrast-failures" rel="noopener noreferrer"&gt;access-proof.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>webdev</category>
      <category>css</category>
    </item>
    <item>
      <title>How to Write a VPAT (Accessibility Conformance Report)</title>
      <dc:creator>Romain</dc:creator>
      <pubDate>Tue, 19 May 2026 18:23:44 +0000</pubDate>
      <link>https://dev.to/lawebe/how-to-write-a-vpat-accessibility-conformance-report-2pim</link>
      <guid>https://dev.to/lawebe/how-to-write-a-vpat-accessibility-conformance-report-2pim</guid>
      <description>&lt;p&gt;&lt;strong&gt;A VPAT (Voluntary Product Accessibility Template) is the procurement-standard document for declaring accessibility conformance of a software product. Government buyers, large enterprises, and increasingly mid-market customers require one. Here is how to write one that holds up.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What a VPAT is (and is not)
&lt;/h2&gt;

&lt;p&gt;A VPAT is a structured self-disclosure of how your product conforms to specific accessibility standards. It is NOT a certification — there is no certifying body. It is a vendor-issued statement, completed using the ITI/INCITS template (current version: VPAT 2.5 Rev 508, published by the Information Technology Industry Council).&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;ACR (Accessibility Conformance Report)&lt;/strong&gt; is the completed VPAT for a specific product version. The terms are often used interchangeably.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four standards a VPAT 2.5 covers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Section 508&lt;/strong&gt; — US federal procurement (mandatory for federal contracts)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WCAG 2.0 + 2.1 + 2.2&lt;/strong&gt; — Web Content Accessibility Guidelines, Level A, AA, AAA&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EN 301 549&lt;/strong&gt; — EU equivalent (EAA, public sector)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Section 504&lt;/strong&gt; — Rehabilitation Act program accessibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For each applicable criterion across these standards, you declare a conformance level.&lt;/p&gt;

&lt;h2&gt;
  
  
  The five conformance levels
&lt;/h2&gt;

&lt;p&gt;LevelMeaning&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&lt;strong&gt;Supports&lt;/strong&gt;The product fully meets the criterion.&lt;br&gt;
&lt;strong&gt;Partially Supports&lt;/strong&gt;The product has some support but with known limitations. Remarks must describe them.&lt;br&gt;
&lt;strong&gt;Does Not Support&lt;/strong&gt;The product does not meet the criterion.&lt;br&gt;
&lt;strong&gt;Not Applicable&lt;/strong&gt;The criterion does not apply (e.g. video criteria on a product with no video).&lt;br&gt;
&lt;strong&gt;Not Evaluated&lt;/strong&gt;Not assessed (acceptable only for AAA criteria; not acceptable for A or AA).&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  The five steps to write a VPAT&lt;br&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Download the current template
&lt;/h3&gt;

&lt;p&gt;From &lt;a href="https://www.itic.org/policy/accessibility/vpat" rel="noopener noreferrer"&gt;itic.org/policy/accessibility/vpat&lt;/a&gt;. Use VPAT 2.5 Rev 508 (the latest stable version as of 2026). Word format is the standard.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Run a thorough accessibility audit
&lt;/h3&gt;

&lt;p&gt;This is the substantive work. Pair automated scanning (AccessProof, axe-core, Lighthouse) with manual review (keyboard navigation, screen reader testing) for every criterion. Automated catches ~30-40%; manual catches the rest.&lt;/p&gt;

&lt;p&gt;Document evidence per criterion: WCAG 1.4.3 contrast — link to the AccessProof PDF showing contrast pass. WCAG 2.1.1 keyboard — link to a video or test report.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Fill in product details
&lt;/h3&gt;

&lt;p&gt;Product name, version, vendor info, date of evaluation, evaluator info (in-house team, external consultant, or both). Be specific about the product version — VPATs need updates per major release.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Complete each applicable table
&lt;/h3&gt;

&lt;p&gt;Three tables to fill: WCAG 2.x, Section 508 chapter 5, Section 508 chapter 6. For each criterion: conformance level + remarks (explanations, especially for "Partially Supports" or "Does Not Support").&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be honest.&lt;/strong&gt; Procurement teams and disability advocates routinely cross-check VPAT claims against the actual product. False claims of "Supports" damage credibility and legal posture more than honest "Partially Supports" with a remediation timeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Add remediation plan for known issues
&lt;/h3&gt;

&lt;p&gt;"Partially Supports" criteria deserve a remarks line with the planned fix and target date. This is what procurement teams want to see — not just current state, but trajectory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Claiming "Supports" without testing.&lt;/strong&gt; Procurement teams cross-check.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outdated VPAT.&lt;/strong&gt; Updates are needed per major release, at minimum annually.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Not Evaluated" for AA criteria.&lt;/strong&gt; Acceptable for AAA only. AA must be assessed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missing remarks for "Partially Supports".&lt;/strong&gt; Always explain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VPAT for the wrong scope.&lt;/strong&gt; Each product gets its own VPAT — not the whole company.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How AccessProof fits into the VPAT workflow
&lt;/h2&gt;

&lt;p&gt;AccessProof produces the underlying WCAG audit evidence — timestamped PDF, per-element selectors, criterion-mapped findings — that goes into the WCAG section of a VPAT. Many SaaS teams use AccessProof for the automated portion and pair with a freelance accessibility specialist for manual review on critical flows.&lt;/p&gt;

&lt;p&gt;Run a free &lt;a href="https://dev.to/free-wcag-scan"&gt;WCAG audit on your product&lt;/a&gt; to see what AccessProof captures. For scheduled scans and PDF archives for ongoing VPAT maintenance, see &lt;a href="https://dev.to/pricing"&gt;Starter and Pro plans&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://access-proof.com/blog/how-to-write-vpat-accessibility-conformance-report" rel="noopener noreferrer"&gt;access-proof.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>ada</category>
      <category>legal</category>
    </item>
    <item>
      <title>How to Test Your Website with a Screen Reader (Beginner Guide)</title>
      <dc:creator>Romain</dc:creator>
      <pubDate>Tue, 19 May 2026 18:01:41 +0000</pubDate>
      <link>https://dev.to/lawebe/how-to-test-your-website-with-a-screen-reader-beginner-guide-4fba</link>
      <guid>https://dev.to/lawebe/how-to-test-your-website-with-a-screen-reader-beginner-guide-4fba</guid>
      <description>&lt;p&gt;&lt;strong&gt;You don't need certifications to run useful screen reader tests. 30 minutes with NVDA or VoiceOver will catch issues no automated tool can. Here's how to start.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Windows&lt;/strong&gt;: install &lt;a href="https://www.nvaccess.org/" rel="noopener noreferrer"&gt;NVDA&lt;/a&gt; (free). Use Firefox — best NVDA compatibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;macOS&lt;/strong&gt;: VoiceOver is built in. Toggle with Cmd-F5. Use Safari — best VoiceOver compatibility.&lt;/li&gt;
&lt;li&gt;Headphones recommended; the synthetic voice gets fatiguing fast over speakers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The 5-minute first pass
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Load the homepage. Listen to the first announcement: it should give you the page title and a sense of structure.&lt;/li&gt;
&lt;li&gt;Tab through every interactive element on a critical page (e.g. product → cart → checkout). Note any control that announces nothing or just "button".&lt;/li&gt;
&lt;li&gt;Use the heading shortcut (NVDA: H; VoiceOver: VO + Cmd + H) to navigate by headings. The structure should make sense out of context.&lt;/li&gt;
&lt;li&gt;Open a form. Each field should announce its label, current value, and any error state.&lt;/li&gt;
&lt;li&gt;Trigger a modal. Focus should land inside the modal; closing it should return focus to the trigger.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Things automated tools miss
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reading order&lt;/strong&gt;: visually correct ≠ DOM order. A floated sidebar can be read before the main article.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live regions&lt;/strong&gt;: cart updates, form validation messages — are they announced?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom widgets&lt;/strong&gt;: tabs, accordions, comboboxes. Most fail because the ARIA pattern is incomplete.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Skip to content" links&lt;/strong&gt;: they exist in 60% of sites we audit but only work in 30%.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What to log
&lt;/h2&gt;

&lt;p&gt;For every issue: URL, element selector, what was announced, what should have been announced, WCAG criterion. Keep a running spreadsheet — patterns will emerge (e.g., "every product card swallows the price").&lt;/p&gt;

&lt;h2&gt;
  
  
  Going further
&lt;/h2&gt;

&lt;p&gt;Once you're comfortable, repeat with mobile screen readers (TalkBack on Android, VoiceOver on iOS). Mobile gestures change everything; many "accessible" sites break on touch.&lt;/p&gt;

&lt;p&gt;AccessProof handles the automated scan layer; pair it with this 30-minute manual ritual once per release and you're ahead of 90% of sites.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://access-proof.com/blog/screen-reader-testing-basics" rel="noopener noreferrer"&gt;access-proof.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>testing</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Color Contrast in Web Design: The Complete Guide</title>
      <dc:creator>Romain</dc:creator>
      <pubDate>Tue, 19 May 2026 18:01:11 +0000</pubDate>
      <link>https://dev.to/lawebe/color-contrast-in-web-design-the-complete-guide-3g50</link>
      <guid>https://dev.to/lawebe/color-contrast-in-web-design-the-complete-guide-3g50</guid>
      <description>&lt;p&gt;&lt;strong&gt;Color contrast is the single most common WCAG failure. Roughly 40% of issues we find on first scan are contrast-related. Here's how to get it right without making your site look like a hospital signage system.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The ratios
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Normal text&lt;/strong&gt;: 4.5:1 against the background (WCAG AA).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Large text&lt;/strong&gt; (≥18pt regular or ≥14pt bold): 3:1.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI components&lt;/strong&gt; (button borders, input outlines, focus rings): 3:1 against adjacent colors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AAA&lt;/strong&gt; bumps to 7:1 / 4.5:1 — required in some public-sector contracts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common traps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Light grey on white&lt;/strong&gt; for placeholder text. Almost always fails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Brand color buttons&lt;/strong&gt; with white text — many brand greens and oranges fail at 4.5:1 unless darkened.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Disabled states&lt;/strong&gt; are exempt from contrast rules, but only if the state is unambiguously communicated through other means.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text on imagery&lt;/strong&gt;: the contrast must be measured against the actual underlying pixels at the worst spot, not just the average.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tools
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WebAIM Contrast Checker&lt;/strong&gt; — fastest single-pair check.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stark&lt;/strong&gt; (Figma plugin) — runs across an entire frame.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;axe-core&lt;/strong&gt; — analyzes computed styles + image fallbacks at scan time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Design without sacrificing aesthetics
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Build a contrast-aware palette: each accent has at least one paired text color that hits 4.5:1.&lt;/li&gt;
&lt;li&gt;Use semitransparent overlays on hero images (e.g. &lt;code&gt;rgba(0,0,0,.4)&lt;/code&gt;) before placing text.&lt;/li&gt;
&lt;li&gt;For SaaS dashboards: keep secondary text at &lt;strong&gt;4.5:1 minimum&lt;/strong&gt;, not the trendy 3:1 grey.&lt;/li&gt;
&lt;li&gt;Test against your dark mode if you have one — most contrast bugs hide there.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AccessProof flags every contrast violation with the exact node, the computed ratio, and the WCAG level it fails. Fix it and re-scan to confirm.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://access-proof.com/blog/color-contrast-accessibility-guide" rel="noopener noreferrer"&gt;access-proof.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>webdev</category>
      <category>css</category>
    </item>
    <item>
      <title>Shopify Plus ADA Compliance for Enterprise Stores</title>
      <dc:creator>Romain</dc:creator>
      <pubDate>Tue, 19 May 2026 17:56:34 +0000</pubDate>
      <link>https://dev.to/lawebe/shopify-plus-ada-compliance-for-enterprise-stores-3gdp</link>
      <guid>https://dev.to/lawebe/shopify-plus-ada-compliance-for-enterprise-stores-3gdp</guid>
      <description>&lt;p&gt;&lt;strong&gt;Shopify Plus stores face the same ADA Title III exposure as regular Shopify stores — and operate at higher transaction volumes, higher visibility, and with more customization. The audit and remediation playbook tuned for Plus merchants.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What changes at the Plus tier
&lt;/h2&gt;

&lt;p&gt;Compared to standard Shopify, Plus adds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Checkout extensibility (Checkout UI Extensions) — your branding lives in checkout&lt;/li&gt;
&lt;li&gt;Custom theme freedom (no plan-tier restriction on Liquid customization)&lt;/li&gt;
&lt;li&gt;Multiple storefronts (B2B, regional, brand splits)&lt;/li&gt;
&lt;li&gt;Higher SLA, dedicated support, custom integrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For accessibility, the implication is: more surface area you control, more customization that can introduce bugs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The recurring Plus-specific issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Checkout UI extensions accessibility
&lt;/h3&gt;

&lt;p&gt;Plus merchants can inject custom UI into checkout (Cart, Information, Shipping, Payment pages) via Checkout UI Extensions. These extensions render in the Shopify checkout iframe context with Shopify's base UI components — which are themselves accessibility-baselined. But custom logic, error messages, conditional rendering can introduce accessibility bugs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-storefront accessibility drift
&lt;/h3&gt;

&lt;p&gt;A Plus merchant operating B2B, regional, and brand storefronts often has theme variations per storefront. Accessibility issues fixed in one theme do not propagate. Audit each storefront separately.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complex custom checkouts (rare, but exists)
&lt;/h3&gt;

&lt;p&gt;Plus merchants with the deprecated checkout.liquid customization face the largest accessibility surface — full checkout HTML control. Migrate to Checkout Extensibility (mandatory by 2026 for new stores) to inherit Shopify's accessibility baseline.&lt;/p&gt;

&lt;h3&gt;
  
  
  B2B portal accessibility
&lt;/h3&gt;

&lt;p&gt;Shopify B2B portals (customer accounts with B2B features) have a separate UI from the storefront and often less accessibility polish. Audit explicitly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The audit workflow for a Plus store
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;List every storefront.&lt;/strong&gt; Plus merchants often have 3-8 storefronts under one organization. Each gets its own audit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit theme + apps per storefront.&lt;/strong&gt; Most accessibility issues come from app injections (reviews, upsells, AB testing). Disable apps one at a time on a development store to identify each app's contribution.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit Checkout UI Extensions.&lt;/strong&gt; Each extension renders on the published checkout. Test with keyboard only and a screen reader.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit the customer account / B2B portal.&lt;/strong&gt; The post-login experience needs the same WCAG conformance as the public storefront.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schedule continuous scans.&lt;/strong&gt; Plus stores publish frequently (daily price/inventory updates, weekly promotions). Daily AccessProof scans (Pro plan, $79/mo for 25 sites) catch regressions early.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Procurement signal for B2B sales
&lt;/h2&gt;

&lt;p&gt;Plus merchants with B2B businesses face increasing accessibility procurement questions from enterprise buyers — especially government and education customers. An AccessProof PDF audit attached to RFP responses is a positive signal that wins deals.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changes after a demand letter
&lt;/h2&gt;

&lt;p&gt;For a Plus merchant served with an ADA demand letter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Engage ADA-defense counsel (specialists exist, often within 24 hours)&lt;/li&gt;
&lt;li&gt;Preserve site state at the date of the letter&lt;/li&gt;
&lt;li&gt;Run a baseline AccessProof scan on every storefront listed in the letter&lt;/li&gt;
&lt;li&gt;Establish a continuous scan cadence post-letter — most cases settle when ongoing remediation is documented&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Multi-channel exposure
&lt;/h2&gt;

&lt;p&gt;Plus merchants often sell through additional channels: Shop app, Google Shopping feeds, social commerce, marketplace integrations. ADA Title III primarily applies to the public web storefront, but customer-facing assistive experiences across channels should be audited periodically.&lt;/p&gt;

&lt;p&gt;Run a baseline accessibility scan on your Plus storefront — &lt;a href="https://dev.to/free-wcag-scan"&gt;free, no signup, 42 seconds&lt;/a&gt;. For multi-store and CI/CD-integrated auditing, see &lt;a href="https://dev.to/pricing"&gt;AccessProof Pro and Business plans&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://access-proof.com/blog/shopify-plus-ada-compliance" rel="noopener noreferrer"&gt;access-proof.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>shopify</category>
      <category>ecommerce</category>
    </item>
    <item>
      <title>Accessibility Testing with Playwright (and Cypress)</title>
      <dc:creator>Romain</dc:creator>
      <pubDate>Tue, 19 May 2026 17:56:04 +0000</pubDate>
      <link>https://dev.to/lawebe/accessibility-testing-with-playwright-and-cypress-142</link>
      <guid>https://dev.to/lawebe/accessibility-testing-with-playwright-and-cypress-142</guid>
      <description>&lt;p&gt;&lt;strong&gt;Playwright (and Cypress, and similar e2e tools) can run axe-core against your live app on every commit. The integration is straightforward; the value is catching accessibility regressions before they ship.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why automated e2e accessibility testing matters
&lt;/h2&gt;

&lt;p&gt;Unit tests check individual components; e2e tests check the whole rendered page in a real browser. Accessibility issues often emerge from the composition (header + main + modal all interacting) — exactly what e2e catches and unit tests miss.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up axe-core in Playwright
&lt;/h2&gt;

&lt;p&gt;Install &lt;code&gt;@axe-core/playwright&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; @axe-core/playwright
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AxeBuilder&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@axe-core/playwright&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;homepage has no critical accessibility violations&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AxeBuilder&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withTags&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wcag2a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wcag2aa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wcag22a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wcag22aa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;analyze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;critical&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;impact&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;critical&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;impact&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;serious&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;critical&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Strategies that work
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scan critical pages, not every page
&lt;/h3&gt;

&lt;p&gt;Pick 5-10 representative pages: homepage, signup, dashboard, settings, checkout. Scanning every page on every commit slows CI without finding much extra.&lt;/p&gt;

&lt;h3&gt;
  
  
  Block on critical and serious only
&lt;/h3&gt;

&lt;p&gt;Default axe categorizes by severity: critical, serious, moderate, minor. Block deploys on critical and serious. Log moderate and minor for backlog grooming.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scan key user flows mid-interaction
&lt;/h3&gt;

&lt;p&gt;The most interesting accessibility bugs appear after interaction: modal open, form errors visible, dropdown expanded. Tell Playwright to perform the action then scan.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button:has-text("Open dialog")&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitForSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[role="dialog"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AxeBuilder&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[role="dialog"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;analyze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use disableRules sparingly
&lt;/h3&gt;

&lt;p&gt;Axe has rules you may legitimately disable (e.g. &lt;code&gt;color-contrast&lt;/code&gt; on a page intentionally low-contrast for a design demo). Document each disabled rule with a TODO.&lt;/p&gt;

&lt;h2&gt;
  
  
  What axe-in-Playwright catches
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Missing alt text, missing labels, missing accessible names&lt;/li&gt;
&lt;li&gt;ARIA validity (invalid roles, required attributes missing)&lt;/li&gt;
&lt;li&gt;Color contrast (computed in headless Chromium)&lt;/li&gt;
&lt;li&gt;Skipped headings, missing landmarks&lt;/li&gt;
&lt;li&gt;Empty buttons / links&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What it does NOT catch (use AccessProof for these)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Behavior over time.&lt;/strong&gt; A scheduled scan that runs daily catches the regression introduced after the e2e suite passes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-page consistency.&lt;/strong&gt; CSS or JS changes that affect every page silently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real network conditions.&lt;/strong&gt; Tests run in fixed environments; AccessProof scans production exactly as users see it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Court-ready evidence.&lt;/strong&gt; CI logs are not great evidence. A timestamped PDF report is.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pair Playwright + axe (catch on every commit) with AccessProof (scheduled scans of production + PDF reports). Different layers of the same coverage strategy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cypress is the same idea
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;cypress-axe&lt;/code&gt; with the same patterns. The API differs slightly but the strategy is identical.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://access-proof.com/blog/accessibility-testing-playwright-cypress" rel="noopener noreferrer"&gt;access-proof.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>testing</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
