<?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: Giriprasad patil</title>
    <description>The latest articles on DEV Community by Giriprasad patil (@giriprasad_patil_c2719c67).</description>
    <link>https://dev.to/giriprasad_patil_c2719c67</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3700990%2Fa99b1745-5a21-4402-a701-1dc73edc8753.jpg</url>
      <title>DEV Community: Giriprasad patil</title>
      <link>https://dev.to/giriprasad_patil_c2719c67</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/giriprasad_patil_c2719c67"/>
    <language>en</language>
    <item>
      <title>A Perfect Automated Accessibility Score Doesn't Test These 4 Things</title>
      <dc:creator>Giriprasad patil</dc:creator>
      <pubDate>Tue, 20 Oct 2026 05:52:07 +0000</pubDate>
      <link>https://dev.to/giriprasad_patil_c2719c67/a-perfect-automated-accessibility-score-doesnt-test-these-4-things-k1p</link>
      <guid>https://dev.to/giriprasad_patil_c2719c67/a-perfect-automated-accessibility-score-doesnt-test-these-4-things-k1p</guid>
      <description>&lt;p&gt;A green 100 on an automated accessibility audit is a good sign. It means the page has no failures that a rule engine can find in the page as it first loads: images without alt text, inputs without labels, low-contrast text, invalid ARIA.&lt;/p&gt;

&lt;p&gt;It doesn't mean a keyboard or screen reader user can get through the page. Automated rules run against one snapshot — one theme, one viewport, before anyone clicks anything — and many WCAG failures only exist after an interaction. Here are four that a perfect score routinely misses, with the criterion each one fails and the fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Focus that goes nowhere when a dialog closes (WCAG 2.4.3)
&lt;/h2&gt;

&lt;p&gt;A dialog that opens and closes correctly for a mouse user can strand a keyboard user. When the dialog unmounts, the element that had focus is gone, and the browser drops focus back to the top of the document. A screen reader user who pressed "Add to cart" now hears the page from the beginning.&lt;/p&gt;

&lt;p&gt;A rule engine looking at the page as loaded never opens the dialog, so it never sees this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Remember what opened the dialog, and return focus there when it closes.&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useReturnFocus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&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;opener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;opener&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;opener&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;opener&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;opener&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;open&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;While the dialog is open, keep focus inside it — the native &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; element opened with &lt;code&gt;showModal()&lt;/code&gt; does that for you, and closes on Escape. More patterns: &lt;a href="https://dev.to/focus-management-modal-close"&gt;managing focus after a modal closes&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Status messages nobody hears (WCAG 4.1.3)
&lt;/h2&gt;

&lt;p&gt;"Added to cart", "3 results", "Email already in use" — messages that appear after an action are visible to sighted users instantly. A screen reader announces them only if they're rendered into a live region that was already in the page before the text changed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- In the page from the start, empty --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"status"&lt;/span&gt; &lt;span class="na"&gt;aria-live=&lt;/span&gt;&lt;span class="s"&gt;"polite"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"cart-status"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Later: change only its text&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cart-status&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Added to cart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A live region created at the same moment as its message is often not announced. Rendering the container on load and updating its text is the reliable pattern. Full walkthrough: &lt;a href="https://dev.to/dynamic-content-updates-screen-readers-aria-live"&gt;announcing dynamic content to screen readers&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Menus that only open on hover (WCAG 2.1.1)
&lt;/h2&gt;

&lt;p&gt;A navigation submenu revealed with &lt;code&gt;:hover&lt;/code&gt; works for a mouse and does nothing for a keyboard. The links inside exist in the HTML, so a check of the loaded page finds nothing wrong — but a keyboard user can never reach them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;aria-expanded=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt; &lt;span class="na"&gt;aria-controls=&lt;/span&gt;&lt;span class="s"&gt;"menu-products"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Products&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"menu-products"&lt;/span&gt; &lt;span class="na"&gt;hidden&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/shirts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Shirts&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Toggle &lt;code&gt;aria-expanded&lt;/code&gt; and &lt;code&gt;hidden&lt;/code&gt; from the button's click handler, close the menu on Escape and return focus to the button. A button gets Enter and Space handling for free. Full pattern: &lt;a href="https://dev.to/multi-level-navigation-accessibility"&gt;accessible multi-level navigation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Contrast in the theme the scan didn't load (WCAG 1.4.3)
&lt;/h2&gt;

&lt;p&gt;An automated scan sees whichever theme the page renders by default. If that's the light theme, the dark theme is never measured — and colours that pass on white often fail on a dark surface.&lt;/p&gt;

&lt;p&gt;Measured with the WCAG contrast formula:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Text&lt;/th&gt;
&lt;th&gt;Background&lt;/th&gt;
&lt;th&gt;Ratio&lt;/th&gt;
&lt;th&gt;4.5:1 for body text&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;#475569&lt;/code&gt; (slate 600)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#FFFFFF&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7.58:1&lt;/td&gt;
&lt;td&gt;Passes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#475569&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#0B0F19&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2.53:1&lt;/td&gt;
&lt;td&gt;Fails&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;#2563EB&lt;/code&gt; (blue 600)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#FFFFFF&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;5.17:1&lt;/td&gt;
&lt;td&gt;Passes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#2563EB&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#0F172A&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3.45:1&lt;/td&gt;
&lt;td&gt;Fails&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The same tokens, a different background, a different result. Check every theme's pairs on purpose — the &lt;a href="https://dev.to/tools/color-contrast-checker"&gt;color contrast checker&lt;/a&gt; takes any two colours — and see &lt;a href="https://dev.to/dark-mode-accessibility-wcag-contrast"&gt;dark mode and WCAG contrast&lt;/a&gt; for a palette that works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing what a score can't see
&lt;/h2&gt;

&lt;p&gt;None of this makes automated checks less useful: they catch the most common failures on every page, quickly, every time you deploy. Pair them with the checks that need interaction:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A keyboard pass.&lt;/strong&gt; Unplug the mouse. Tab through every flow, open and close every dialog and menu, and watch where focus goes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A screen reader pass&lt;/strong&gt; on the flows that matter most — sign-up, checkout, search — with VoiceOver, NVDA or Narrator, all free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Each theme and breakpoint&lt;/strong&gt; you ship, not only the default.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ADAGuard runs some interaction checks in a real browser — it presses Tab to find keyboard traps, and measures whether a focused element is hidden behind a sticky header — but no automated tool covers everything above. &lt;a href="https://dev.to/free-accessibility-scanner"&gt;Scan a page free&lt;/a&gt; to see what it finds, and &lt;a href="https://dev.to/wcag-coverage"&gt;what it tests automatically&lt;/a&gt; is listed criterion by criterion.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>a11y</category>
    </item>
    <item>
      <title>Dark Mode Accessibility: Why a Theme Toggle Doesn''t Satisfy WCAG Contrast</title>
      <dc:creator>Giriprasad patil</dc:creator>
      <pubDate>Mon, 19 Oct 2026 19:11:31 +0000</pubDate>
      <link>https://dev.to/giriprasad_patil_c2719c67/dark-mode-accessibility-why-a-theme-toggle-doesnt-satisfy-wcag-contrast-21ni</link>
      <guid>https://dev.to/giriprasad_patil_c2719c67/dark-mode-accessibility-why-a-theme-toggle-doesnt-satisfy-wcag-contrast-21ni</guid>
      <description>&lt;p&gt;Color contrast is the number one accessibility failure on the web. According to WebAIM's Million analysis, 83.6% of all websites fail WCAG contrast requirements on at least one element. Adding a dark mode toggle to your site doesn't fix that statistic — for most teams, it creates an entirely new set of contrast failures that no one checked because the light mode tested fine.&lt;/p&gt;

&lt;p&gt;Test individual color pairs with the &lt;a href="https://dev.to/tools/color-contrast-checker"&gt;color contrast checker&lt;/a&gt;; for code-level fixes in React apps, see the &lt;a href="https://dev.to/accessibility-checker/react"&gt;React accessibility checker&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The ada compliance color checker problem in 2026 is this: most teams test contrast for one theme. They pick colors for light mode, run them through a contrast ratio tool, confirm they pass 4.5:1, and ship. Then they add a dark mode using CSS custom properties, invert a few background variables, and assume the same colors will work in reverse. They rarely do.&lt;/p&gt;

&lt;h2&gt;
  
  
  What WCAG Actually Requires for Contrast
&lt;/h2&gt;

&lt;p&gt;WCAG 2.1 Level AA sets two minimum contrast ratios that apply to every color combination on your site — in every theme:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.4.3 Contrast (Minimum):&lt;/strong&gt; At least 4.5:1 for normal text (under 18pt regular or 14pt bold). At least 3:1 for large text (18pt+ regular or 14pt+ bold). This ratio applies to text against its immediate background.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.4.11 Non-text Contrast:&lt;/strong&gt; At least 3:1 for user interface components (buttons, form inputs, focus indicators, icons that convey meaning) against adjacent colors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Both thresholds apply independently to every theme.&lt;/strong&gt; A color pair that achieves 5.2:1 in light mode and 2.8:1 in dark mode is non-compliant. The dark mode version fails 1.4.3 regardless of the light mode result. If you offer a dark mode, you must run an ada compliance color checker against your dark theme separately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Dark Mode Creates New Contrast Failures
&lt;/h2&gt;

&lt;p&gt;The instinct when building dark mode is to invert: swap your white background for a dark background, keep your brand colors, change your text from dark to light. This works visually for most colors. It fails accessibility for many.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pure black is too harsh, saturated colors "vibrate."&lt;/strong&gt; Accessibility specialists consistently recommend against using pure black (#000000) as a dark mode background. The extreme contrast between pure black and white text (21:1) can cause eye fatigue and halation effects for users with certain visual impairments. Industry standard dark backgrounds use very dark grays (#121212, #1e1e1e) rather than true black.&lt;/p&gt;

&lt;p&gt;More importantly, fully saturated brand colors — the bright reds, oranges, and yellows that pop on a white background — often fail contrast requirements on dark backgrounds. A bright orange (#FF6B00) achieves 4.8:1 on white (#FFFFFF), passing AA. The same orange achieves only 3.1:1 on dark gray (#121212), failing AA for normal text. Same hex value, opposite compliance outcome depending on theme.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Semantic states lose meaning in dark mode.&lt;/strong&gt; Error states (red borders, red text), success states (green badges), warning indicators (yellow icons) — these are color-coded signals that may pass contrast in light mode and fail in dark mode. Because they appear infrequently (only on form errors or validation), they're often the last thing tested. They're also the most legally significant: a form that cannot communicate an error state to a low-vision user is a direct barrier to completing a task.&lt;/p&gt;

&lt;h2&gt;
  
  
  The &lt;code&gt;prefers-color-scheme&lt;/code&gt; Problem
&lt;/h2&gt;

&lt;p&gt;Developers who implement dark mode via CSS &lt;code&gt;prefers-color-scheme&lt;/code&gt; — the media query that automatically switches the theme based on the user's OS setting — often never see the dark version in their browser during development. Their browser is in light mode. They build, test, and ship in light mode. The dark mode exists in the CSS and is served to users who prefer it, but no one on the team ran an ada compliance color checker against it.&lt;/p&gt;

&lt;p&gt;A minimal but meaningful test workflow:&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;/* In your browser DevTools — Forces dark mode for testing */&lt;/span&gt;
&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* Your dark mode tokens go here */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Chrome DevTools → Rendering tab → Emulate CSS media feature &lt;code&gt;prefers-color-scheme&lt;/code&gt; → set to &lt;code&gt;dark&lt;/code&gt;. This lets you view the dark theme without changing your OS setting, enabling contrast testing in the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Test and Where the Failures Hide
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;UI Element&lt;/th&gt;
&lt;th&gt;Light Mode Risk&lt;/th&gt;
&lt;th&gt;Dark Mode Risk&lt;/th&gt;
&lt;th&gt;WCAG Criterion&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Body text&lt;/td&gt;
&lt;td&gt;Low (if initially tested)&lt;/td&gt;
&lt;td&gt;Medium — inverted palette may drop ratio&lt;/td&gt;
&lt;td&gt;1.4.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Placeholder text&lt;/td&gt;
&lt;td&gt;High — often set to gray at 3:1 or less&lt;/td&gt;
&lt;td&gt;Higher — same gray looks different on dark bg&lt;/td&gt;
&lt;td&gt;1.4.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disabled button text&lt;/td&gt;
&lt;td&gt;Medium — often intentionally low contrast&lt;/td&gt;
&lt;td&gt;High — dark mode inversion makes it worse&lt;/td&gt;
&lt;td&gt;1.4.3 (Note 1 exception applies but check)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Form input borders&lt;/td&gt;
&lt;td&gt;Medium — light gray borders on white fail 1.4.11&lt;/td&gt;
&lt;td&gt;High — dark mode border colors frequently fail&lt;/td&gt;
&lt;td&gt;1.4.11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Focus indicator (outline)&lt;/td&gt;
&lt;td&gt;High — default browser outline removed by CSS&lt;/td&gt;
&lt;td&gt;Very High — dark mode often has no visible focus&lt;/td&gt;
&lt;td&gt;2.4.7 / 2.4.11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error state text&lt;/td&gt;
&lt;td&gt;Low if checked&lt;/td&gt;
&lt;td&gt;High — red on dark bg often fails&lt;/td&gt;
&lt;td&gt;1.4.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Icon color&lt;/td&gt;
&lt;td&gt;Medium — icon-only elements need 3:1&lt;/td&gt;
&lt;td&gt;High — icon color may be inverted incorrectly&lt;/td&gt;
&lt;td&gt;1.4.11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Link text color&lt;/td&gt;
&lt;td&gt;Low if initially blue&lt;/td&gt;
&lt;td&gt;Medium — dark mode link color often under-contrasted&lt;/td&gt;
&lt;td&gt;1.4.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CTA button&lt;/td&gt;
&lt;td&gt;Low if checked&lt;/td&gt;
&lt;td&gt;Medium — brand-color button on dark bg often fails&lt;/td&gt;
&lt;td&gt;1.4.3 + 1.4.11&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Testing Both Themes Systematically
&lt;/h2&gt;

&lt;p&gt;The correct approach is to run your ada compliance contrast checker against both themes separately. For web surfaces, use the same tool you'd use for light mode — but capture the dark mode state.&lt;/p&gt;

&lt;p&gt;For automated scanning, ADAGuard at &lt;a href="https://www.adaguard.io" rel="noopener noreferrer"&gt;adaguard.io&lt;/a&gt; scans your site's live-rendered DOM including JavaScript-applied styles. If your dark mode is applied via a class toggle (e.g., &lt;code&gt;class="dark"&lt;/code&gt; on ``), you can share the dark-mode URL or state with a scanner that supports URL parameters. ADAGuard's ada compliance color checker functionality is part of its full 23-category scan, covering contrast ratios across the rendered page alongside form labels, alt text, ARIA, and focus indicators.&lt;/p&gt;

&lt;p&gt;For manual review, use the browser DevTools color picker or tools like the Colour Contrast Analyser desktop app to spot-check your most common text/background combinations in both themes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Contrast Compliance Into Your Design System
&lt;/h2&gt;

&lt;p&gt;The highest-leverage fix is upstream: define accessible dark mode color tokens at the design system level, not per-component.&lt;/p&gt;

&lt;p&gt;Rather than allowing any designer to use any color on any dark background, pre-define an approved palette for dark mode that has been verified against 4.5:1 for text and 3:1 for UI components. Document which combinations are approved, which are prohibited, and which require special consideration (large-text only, icon-only with text label). Build this into your Figma variable library or design tokens spec so that the contrast requirements are enforced at the design stage, not discovered in a post-launch ada compliance color checker audit.&lt;/p&gt;

&lt;p&gt;The EAA has been in enforcement since June 28, 2025, and color contrast is one of the most easily detected violations — regulators and plaintiff attorneys can run automated checks against your dark theme just as easily as your light theme.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 30-Second Fix
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.adaguard.io" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;Run an ADAGuard scan right now to get a full WCAG 2.2 AA report including color contrast analysis in under 30 seconds!&lt;/a&gt;
 ADAGuard checks both contrast thresholds (1.4.3 and 1.4.11) across your live-rendered page, plus 20 other check categories covering ARIA, form labels, alt text, and focus indicators. See exactly which contrast failures exist on your current theme — then run the same scan on your dark mode state before a regulator or plaintiff attorney does it for you.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>design</category>
      <category>a11y</category>
    </item>
  </channel>
</rss>
