Dark mode can feel comfortable and polished while still making text or controls hard to see. Check each foreground/background pair in the theme people will use, then review the rendered interface at normal size. A contrast score is useful evidence for one pair; it is not a complete accessibility review of a page or product.
Start with the actual color pairs
A contrast ratio describes the relative luminance of two colors: a foreground and its background. It does not belong to one color by itself. A muted gray may be readable on a near-black surface but fail on a lighter card; a saturated accent may work as a large icon and fail as small text.
Make a list of the pairs that appear in the interface:
- Body text on the page background
- Card text on raised surfaces
- Muted text, helper copy, and placeholders
- Links and inline actions
- Button labels on button backgrounds
- Input text and selected values
- Error, warning, and success messages
- Focus indicators and control boundaries
Include hover, active, disabled, selected, and error states. A palette can pass for its default state yet become difficult to read when a button darkens on hover or a disabled control reduces opacity.
If a component has a gradient, image, transparency, or layered surface behind text, test the resulting rendered contrast at the lightest and darkest locations. A pairwise checker needs the effective colors, not just the nominal CSS values. A semi-transparent foreground or overlay can produce a different color once composited over its background.
Use the right WCAG criterion
For WCAG 2.2, Success Criterion 1.4.3 specifies minimum contrast for normal text and large text, with defined exceptions. The general thresholds are 4.5:1 for normal text and 3:1 for large text. “Large” has a specific size and weight definition in the criterion; do not apply the lower threshold to ordinary body copy simply because a heading looks prominent.
WCAG 2.2 Success Criterion 1.4.11 addresses contrast for visual information needed to identify user interface components and states, and for parts of graphical objects. It uses a 3:1 threshold against adjacent colors for applicable content, with exceptions. This is separate from text contrast: a button label may pass while its boundary, selected indicator, or icon remains difficult to distinguish.
Read the criterion and its guidance when determining whether a particular element is in scope. Some types of text or interface details have exceptions, and legal or procurement requirements may specify a conformance level or standard version. Follow the current applicable requirements for your product rather than treating these figures as a universal legal rule.
The W3C Understanding Contrast Minimum document explains the text criterion, and Understanding Non-text Contrast covers applicable controls and graphical information. These help clarify what a numeric test does and does not establish.
Why dark themes need separate checks
A dark theme reverses the usual brightness relationship: light text sits on a dark surface. That does not guarantee stronger contrast. Two dark grays can be close in luminance, and a low-opacity gray can become almost indistinguishable on the final surface. Bright text can also create glare or visual crowding, especially when every label is pure white against pure black.
Dark interfaces commonly layer several surfaces: the page, a card, a menu, a modal, and an input. If those surfaces are too similar, users may not see where one component ends. If they are too different, the page can feel fragmented. Contrast testing should account for both readability and the component boundaries that communicate structure.
A muted text token deserves particular attention. Designers often reduce opacity to create hierarchy, but opacity is applied against the background and can create a lower effective contrast than expected. Measure the final rendered color on each relevant surface rather than assessing the token value alone.
Test text at its rendered size
A contrast checker can calculate a ratio from two opaque color values. Use the exact foreground and background values for the specific text. For text with opacity, a background image, a gradient, or a translucent overlay, determine the effective colors in the rendered location before using a checker.
If the component uses a token such as color-mix(), an alpha channel, or a CSS filter, inspect the computed appearance in the browser. A token that looks like a solid color in a design file may be blended with the surface in the final page. Record the resolved pair that you tested so another reviewer can reproduce the check after the theme changes.
Check text at its actual size and weight. Normal body text, captions, small labels, and placeholder text are easy to overlook because they are not the primary design focus. Large headings may use different thresholds under the applicable criterion, but size and weight definitions matter; do not infer the status from a visual impression.
Also check text states separately. A link may have enough contrast in its default state but lose it after hover. A keyboard focus outline may not alter the text color at all, yet must remain visible as a state indicator. A disabled control may be exempt from some criteria, but the disabled state still needs to be understandable and should not be confused with ordinary content.
The Toolsnix Contrast Checker can help test a selected foreground and background pair. Use it during review, then inspect the actual component because the tool cannot automatically know whether your image, transparency, gradients, font size, or state behavior matches the test inputs.
Check non-text information too
Text is only part of the interface. A thin outline around an input, a chart line, a selected tab marker, or a custom checkbox can carry information. If that visual detail is needed to identify the control or state, check it against adjacent colors under the relevant non-text contrast guidance.
Not every decorative border must be treated as meaningful, and not every icon has the same role. Ask whether removing or failing to see the mark would make the component's function or state harder to identify. Then evaluate the element according to the relevant criterion and the product's accessibility requirements.
Do not rely on color alone for errors, selection, or data categories. Pair a color with a label, icon, shape, line style, or other cue. This matters in both light and dark themes, and it helps when colors are viewed on low-quality displays or under unusual lighting.
Focus rings deserve their own check. A bright outline may be visible against the page but disappear when it overlaps a button with a similar accent color. Test keyboard focus on the actual component edge and across each surface it can touch. If the outline crosses both a dark card and a bright button, choose a treatment that stays visible on both, such as a two-color ring or enough separation from the control. Then confirm that hover styling does not erase the focus cue.
A practical review workflow
- List component states. Include default, hover, focus, active, selected, disabled, error, and success where they exist.
- Record foreground and background pairs. Include page, card, modal, and control surfaces rather than assuming one background.
- Use a checker with the final values. Test text and applicable non-text information using the appropriate criterion.
- Fix the role, not only the screenshot. Adjust the token or component mapping so the change applies consistently across similar screens.
- Inspect at normal zoom and typical display sizes. Look at text hierarchy, focus, control boundaries, charts, and icons in context.
- Repeat the review after changes. A foreground adjustment may improve text and reduce distinction between selected and unselected states.
- Document exceptions and scope. Record which standard and version you used, and which content or states still need a separate review.
Example: a dark settings panel
Consider a settings card with a charcoal surface, light body text, gray helper text, a violet save button, and a thin gray input border. Checking only the body text misses several risks. The helper text may be too dim; the button label may not contrast enough with violet; the input boundary may blend into the card; and a focus outline may disappear on the button's hover color.
Test each pair independently. If the helper text fails, choose a lighter muted token or a stronger surface contrast. If the save label fails, adjust the button shade or label color. If the input boundary is difficult to see, strengthen the border or add another meaningful visual cue. Then review focus and hover states because they use different colors. There is no one adjustment that fixes all the pairs.
Common mistakes to avoid
- Testing only the default page background: Components often sit on cards, modals, or colored panels.
- Treating hex values as the final rendered colors: Opacity and compositing can change the visible result.
- Checking only body text: Placeholders, captions, button labels, and icons also need attention.
- Using the text threshold for every element: Text and applicable non-text information have different criteria.
- Assuming a contrast pass means WCAG conformance: Keyboard access, semantics, reflow, and many other requirements are outside a color-pair calculation.
- Removing hierarchy by making everything bright: Contrast should preserve distinctions without turning every element into a competing highlight.
- Changing only a local component: A shared token may be the real source of repeated low-contrast text.
Frequently asked questions
What contrast ratio should dark mode text meet?
Under WCAG 2.2 Success Criterion 1.4.3, the general minimum is 4.5:1 for normal text and 3:1 for large text, subject to the criterion's definitions and exceptions. Confirm the standard and conformance requirements that apply to your product.
Is pure white text on black the best dark mode choice?
Not automatically. It can create a very strong brightness difference and may feel harsh, while slightly softened colors can still meet the relevant contrast requirement. Test readability and visual comfort in the actual interface.
Do icons and input borders need contrast checks?
Some non-text elements fall under WCAG 2.2 Success Criterion 1.4.11 when their appearance is needed to identify a control, state, or meaningful graphic. Review the criterion's scope and exceptions for each use.
Can a contrast checker certify my site as accessible?
No. It checks the values you provide for a particular pair. It does not assess the whole page, every state, keyboard operation, content semantics, or other accessibility requirements.
Should disabled controls pass the same contrast threshold?
WCAG criteria include exceptions for inactive user interface components, but the disabled state should still be recognizable and not mistaken for ordinary text. Follow your product's accessibility target and use clear semantics and styling.
Next step
Review one representative dark screen and test its actual text, control, and focus pairs. Fix shared tokens where possible, then revisit the same components in light mode and interactive states. Keep the standard, version, and exceptions in the review note so the result is explainable later.
