Overview
Choose foreground and background colors that remain readable.
Color Contrast (WCAG Ratios) makes the interface usable for more people and more devices. The goal is not only passing an automated score, but making names, focus, state, errors, and reading order understandable.
Core Ideas
- For Color Contrast (WCAG Ratios), start with the keyboard and visible labels.
- Expose the right name, role, value, and state for interactive controls.
- Use clear error messages and do not rely on color alone.
- Validate with tools, then confirm manually with real interaction.
Step by Step
- Build the Color Contrast (WCAG Ratios) pattern with semantic HTML first.
- Tab through the interface and confirm focus order.
- Check labels, descriptions, live messages, and error states.
- Use an automated tool after manual checks to catch missed details.
Beginner Explanation
Color Contrast (WCAG Ratios) is about making text and important UI states readable against their background.
Contrast is not only a design detail. Low contrast can make buttons, links, form errors, disabled states, and instructions unusable.
Check normal text, large text, icons, focus rings, borders, charts, and placeholder-like helper text separately.
Before You Start
- Before practicing Color Contrast (WCAG Ratios), identify the task a user is trying to complete.
- List the interactive elements and confirm each one has a visible label or clear text.
- Tab through the UI once before changing code so you know the current focus order.
- Check whether information is conveyed only by color, position, motion, or icon shape.
- Keep a notes list for issues found by keyboard testing, screen reader testing, and automated tools separately.
Key Accessibility Concepts
- Check body text, headings, links, buttons, icons, borders, and focus indicators.
- Do not rely on color alone to identify success, warning, error, or selected state.
- Test text over images, gradients, disabled-looking controls, and hover/focus states.
- Use design tokens so accessible color pairs can be reused across the site.
Plain-English Glossary
- Accessible name: the label announced for a control, link, image, or region.
- Role: the type of element or widget exposed to assistive technology.
- State: current information such as expanded, selected, pressed, invalid, checked, or disabled.
- Focus order: the sequence keyboard users follow when pressing Tab and Shift+Tab.
- Landmark: a page region such as nav, main, header, footer, aside, or form.
- Live region: an area that announces important dynamic updates.
- Alt text: text alternative for an image when the image communicates information.
- Assistive technology: tools such as screen readers, magnifiers, switch devices, voice control, and captions.
What You Will Learn
- Explain the accessibility risk that Color Contrast (WCAG Ratios) solves.
- Identify names, roles, states, labels, focus order, and errors in a real interface.
- Update the code editor example without breaking keyboard or screen reader behavior.
- Separate automated-tool findings from manual usability findings.
Where You Use This in Real Projects
You use Color Contrast (WCAG Ratios) in login pages, checkout flows, dashboards, menus, dialogs, search forms, media pages, image galleries, article pages, admin panels, and design systems.
Accessibility work is easiest when it is built into components from the start: buttons, links, inputs, alerts, dialogs, tabs, accordions, cards, navigation, and tables.
A beginner should practice small pieces first, then test the full task flow from page load to success or error recovery.
Browser and Assistive Technology Notes
- Different browsers and assistive technologies may announce the same pattern slightly differently, so test the behavior, not only the exact wording.
- Native HTML controls usually provide stronger cross-browser behavior than custom div-based controls.
- Do not hide important text with display: none if assistive technology needs to read it.
- Use visually hidden helper text only when the text is useful for non-visual users and not a substitute for visible instructions.
- Retest after CSS and JavaScript changes because visual updates can accidentally hide labels, focus rings, and error messages.
Code Example
.button {
color: #ffffff;
background: #4a148c; /* strong contrast */
}
.muted {
color: #667085; /* readable on white */
}
Another Example
.notice {
color: #111827;
background: #fef3c7;
border: 2px solid #92400e;
}
.notice a {
color: #1d4ed8;
text-decoration: underline;
text-underline-offset: .18em;
}
More Practice Examples
Example 1: Button with live status
<button id="saveButton" type="button">Save profile</button>
<p id="saveStatus" role="status"></p>
<script>
const button = document.querySelector('#saveButton');
const status = document.querySelector('#saveStatus');
button.addEventListener('click', () => {
status.textContent = 'Profile saved successfully.';
});
</script>
- The button has visible text, so it already has an accessible name.
- role="status" announces the result without moving focus.
- The message is useful because it confirms that the action worked.
Example 2: Form field with hint and error
<label for="username">Username</label>
<input id="username" name="username" aria-describedby="usernameHint usernameError" aria-invalid="true">
<p id="usernameHint">Use 4 to 20 letters or numbers.</p>
<p id="usernameError">Username is required.</p>
- The label gives the input its accessible name.
- aria-describedby connects both the hint and current error.
- aria-invalid tells assistive technology the current value needs correction.
Example 3: Visible focus and reduced motion
.action:focus-visible {
outline: 3px solid #2563eb;
outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
.action {
transition: none;
}
}
- focus-visible keeps keyboard focus obvious without showing rings for every mouse click.
- outline-offset separates the focus indicator from the element edge.
- The reduced motion query keeps interaction calm for people who request it.
Example Explained
- The Color Contrast (WCAG Ratios) example starts with semantic HTML so the browser provides as much accessibility behavior as possible.
- Labels, text, headings, landmarks, and descriptions create the information assistive technology needs.
- ARIA is used only when it adds a missing relationship, state, or announcement.
- Keyboard behavior is part of the feature, not an optional extra.
- The example can be tested by completing a real task, not only by inspecting code.
How to Read This Example
- Find the interactive elements first: links, buttons, form fields, dialogs, menus, or custom widgets.
- Name each control out loud and check whether the visible text, label, aria-label, or aria-labelledby provides that name.
- Check role and state next, such as expanded, invalid, selected, pressed, checked, or hidden.
- Tab through the example and confirm the focus order follows the visual and logical task order.
- Change one part of the Color Contrast (WCAG Ratios) example, then retest with keyboard and automated checks.
Code Editor Example
Open a ready-made starter for this lesson in the live HTML, CSS, and JavaScript editor. You can change the code, then click Run to see the result immediately.
Open in Code EditorChecklist
- Test with keyboard only before relying on automated tools.
- Use visible labels, focus states, and clear error messages.
- Prefer semantic HTML and add ARIA only when it adds real meaning.
Common Mistakes
- Treating automated audit scores as the whole accessibility test.
- Removing focus outlines without replacing them.
- Using ARIA to patch invalid or non-semantic HTML instead of fixing the HTML.
Do and Don't
- Do: begin Color Contrast (WCAG Ratios) with real HTML elements, visible labels, and clear content.
- Do: keep focus indicators visible and test every interactive element with the keyboard.
- Do: connect helper text, errors, and dynamic status messages programmatically.
- Don't: use ARIA to hide invalid markup or avoid native controls.
- Don't: depend only on color, icon shape, placeholder text, animation, or mouse hover.
Practice Challenge
Test the Color Contrast (WCAG Ratios) pattern using only Tab, Shift+Tab, Enter, Space, and Escape, then check whether names and states are announced clearly.
Try These Changes
- Remove the visible label from one control, run the editor, then restore the label and compare the result.
- Add a validation error and connect it with aria-describedby and aria-invalid.
- Use only Tab, Shift+Tab, Enter, Space, and Escape to complete the example task.
- Change a button or link color and check whether the focus, hover, and active states still remain readable.
- Add one dynamic success message and decide whether it should move focus or use a live region.
Quick Check
- Question: Should ARIA be the first solution? Answer: No, use semantic HTML first and ARIA only when it adds needed meaning.
- Question: What should every control have? Answer: An accessible name and a visible or understandable purpose.
- Question: What catches focus order problems? Answer: Manual keyboard testing with Tab and Shift+Tab.
- Question: Can automated tools prove a page is accessible? Answer: No, they catch many code issues but not every human task issue.
- Question: What is a good first manual test? Answer: Complete the main task without using a mouse.
Debugging Checks
- Inspect the accessibility tree or browser accessibility panel to confirm names, roles, and states.
- Check whether hidden content is hidden from everyone or only visually hidden.
- Look for div or span elements that act like buttons, links, tabs, or menus without keyboard behavior.
- Confirm focus is visible, logical, and restored after dialogs, menus, validation, or route changes.
- Run automated checks after manual testing so code-level issues are not missed.
Mini Project
Build an alert and button set for Color Contrast (WCAG Ratios): normal, hover, focus, success, warning, and error states with readable text and non-color indicators.
Mastery Check
- You can test the Color Contrast (WCAG Ratios) pattern without a mouse.
- You can identify the accessible name and state of each control.
- You can explain which checks require manual testing.