CSS Accessibility

Creating inclusive web experiences with CSS

β™Ώ What is CSS Accessibility?

CSS Accessibility ensures that your website is usable by everyone, including people with disabilities. This includes proper color contrast, readable fonts, keyboard navigation support, and responsive design for assistive technologies.


/* Accessible CSS principles */
.accessible-button {
    /* High contrast colors */
    background: #0066cc;
    color: white;
    
    /* Clear focus indicators */
    outline: 2px solid transparent;
    outline-offset: 2px;
}

.accessible-button:focus {
    outline-color: #ff6600;
}
                                    

Key Accessibility Areas

🎨

Color & Contrast

Ensure readable text for all users

WCAG AA 4.5:1 ratio Color blind
⌨️

Keyboard Navigation

Support users who can't use a mouse

Focus styles Tab order Skip links
πŸ“±

Responsive Design

Work on all devices and zoom levels

Mobile first Zoom 200% Touch targets
πŸ”€

Typography

Readable and scalable text

Font size Line height Font choice

πŸ”Ή Color Contrast & Accessibility

Ensure sufficient color contrast between text and background to meet WCAG guidelines (minimum 4.5:1 for normal text). Use tools like Chrome DevTools or WebAIM Contrast Checker to verify ratios. High contrast improves readability for users with low vision or in bright environments. Implement dynamic contrast adjustments via CSS variables for themes, and test with grayscale simulators. Accessible color choices prevent exclusion and support inclusive design, making content usable for everyone regardless of visual ability.

/* βœ… GOOD - High contrast (WCAG AA compliant) */
.good-contrast {
    background: #ffffff;
    color: #333333;        /* Contrast ratio: 12.6:1 */
}

.good-button {
    background: #0066cc;
    color: #ffffff;        /* Contrast ratio: 7.0:1 */
}

/* ❌ BAD - Low contrast (fails WCAG) */
.bad-contrast {
    background: #f0f0f0;
    color: #cccccc;        /* Contrast ratio: 1.6:1 - TOO LOW */
}

.bad-button {
    background: #ffff00;
    color: #ffffff;        /* Contrast ratio: 1.1:1 - TOO LOW */
}

/* βœ… BETTER - Accessible alternatives */
.accessible-light {
    background: #ffffff;
    color: #2c2c2c;        /* High contrast */
}

.accessible-dark {
    background: #1a1a1a;
    color: #ffffff;        /* High contrast */
}

/* Color-blind friendly palette */
.colorblind-safe {
    --blue: #0173b2;
    --orange: #de8f05;
    --green: #029e73;
    --red: #cc78bc;
}

Contrast Examples:

Good Contrast
Ratio: 12.6:1 βœ…
Good Button
Ratio: 7.0:1 βœ…
Poor Contrast
Ratio: 1.6:1 ❌

πŸ”Ή Focus Management & Keyboard Navigation

Provide clear, visible focus indicators for all interactive elements to support keyboard navigation. Use :focus and :focus-visible pseudo-classes to style focus rings without relying on default browser outlines. Ensure logical tab order matches visual layout, and manage focus programmatically in modals and dynamic content. This accessibility practice assists users with motor impairments, screen reader users, and anyone relying on keyboard input, improving overall usability and compliance with accessibility standards.

/* βœ… GOOD - Clear focus indicators */
.accessible-link {
    color: #0066cc;
    text-decoration: underline;
    
    /* Custom focus style */
    outline: 2px solid transparent;
    outline-offset: 2px;
    border-radius: 2px;
}

.accessible-link:focus {
    outline-color: #ff6600;
    background: rgba(255, 102, 0, 0.1);
}

.accessible-button {
    background: #0066cc;
    color: white;
    border: none;
    padding: 12px 24px;
    border-radius: 4px;
    cursor: pointer;
    
    /* Focus styles */
    outline: 2px solid transparent;
    outline-offset: 2px;
}

.accessible-button:focus {
    outline-color: #ff6600;
    box-shadow: 0 0 0 3px rgba(255, 102, 0, 0.3);
}

/* Skip link for keyboard navigation */
.skip-link {
    position: absolute;
    top: -40px;
    left: 6px;
    background: #000;
    color: #fff;
    padding: 8px;
    text-decoration: none;
    border-radius: 0 0 4px 4px;
    z-index: 1000;
}

.skip-link:focus {
    top: 0;
}

/* ❌ BAD - No focus indicators */
.bad-button {
    outline: none;         /* Removes focus indicator */
}

.bad-button:focus {
    outline: none;         /* Still no focus indicator */
}

Focus Examples:

Focused Link βœ…

πŸ”Ή Accessible Typography

Accessible typography involves choosing legible fonts, appropriate font sizes (minimum 16px for body), sufficient line height (1.5–1.6), and responsive scaling using relative units (em, rem). Avoid low-contrast colors and overly decorative typefaces for long text. Support zoom up to 200% without breaking layout. These choices benefit users with dyslexia, low vision, or cognitive disabilities, ensuring content is readable and comfortable across all devices and user settings in inclusive web design.

/* βœ… GOOD - Accessible typography */
body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-size: 16px;           /* Minimum 16px for body text */
    line-height: 1.5;          /* 1.4-1.6 for readability */
    color: #333;
    background: #fff;
}

.heading-1 {
    font-size: clamp(1.75rem, 4vw, 2.5rem);
    line-height: 1.2;
    margin-bottom: 1rem;
    font-weight: 600;
}

.body-text {
    font-size: clamp(1rem, 2.5vw, 1.125rem);
    line-height: 1.6;
    max-width: 65ch;           /* Optimal reading width */
    margin-bottom: 1rem;
}

.small-text {
    font-size: max(0.875rem, 14px);  /* Never smaller than 14px */
    line-height: 1.4;
}

/* ❌ BAD - Inaccessible typography */
.bad-typography {
    font-size: 12px;          /* Too small */
    line-height: 1.1;         /* Too tight */
    color: #999;              /* Low contrast */
    font-family: 'Fancy Script', cursive;  /* Hard to read */
}

/* βœ… BETTER - Responsive and accessible */
.responsive-text {
    font-size: clamp(1rem, 2.5vw, 1.25rem);
    line-height: 1.5;
    letter-spacing: 0.01em;    /* Slight spacing for clarity */
}

/* Dyslexia-friendly options */
.dyslexia-friendly {
    font-family: 'OpenDyslexic', Arial, sans-serif;
    letter-spacing: 0.12em;
    word-spacing: 0.16em;
    line-height: 1.8;
}

Typography Examples:

Good Typography: This text uses proper font size (16px+), line height (1.6), and optimal line length for comfortable reading.
Poor Typography: This text is too small, cramped, low contrast, and uses a decorative font that's hard to read.

πŸ”Ή Responsive & Mobile Accessibility

Ensure designs are usable at all screen sizes and zoom levels by using flexible layouts (Flexbox, Grid), responsive typography, and touch-friendly target sizes (minimum 44x44px). Test with device emulators and real devices, and consider portrait/landscape orientations. Support pinch-to-zoom and avoid disabling viewport scaling. Mobile accessibility also includes ensuring interactive elements are spaced properly, forms are easy to complete, and content reflows without horizontal scrolling for an inclusive mobile experience.

/* βœ… GOOD - Accessible responsive design */
.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: clamp(1rem, 5vw, 2rem);
}

/* Touch-friendly button sizes */
.touch-button {
    min-height: 44px;          /* Minimum touch target */
    min-width: 44px;
    padding: 12px 16px;
    margin: 4px;               /* Space between targets */
    border-radius: 4px;
    border: none;
    background: #0066cc;
    color: white;
    cursor: pointer;
}

/* Accessible form inputs */
.form-input {
    min-height: 44px;          /* Touch-friendly */
    padding: 12px 16px;
    font-size: max(16px, 1rem); /* Prevents zoom on iOS */
    border: 2px solid #ccc;
    border-radius: 4px;
    width: 100%;
}

.form-input:focus {
    border-color: #0066cc;
    outline: 2px solid #0066cc;
    outline-offset: 2px;
}

/* Zoom-friendly layout */
.zoom-friendly {
    /* Use relative units that scale */
    padding: 1rem;
    margin: 1rem 0;
    
    /* Flexible layouts */
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}

/* Media queries for accessibility */
@media (max-width: 768px) {
    .mobile-stack {
        flex-direction: column;
    }
    
    .mobile-text {
        font-size: max(18px, 1.125rem); /* Larger on mobile */
    }
}

/* Respect user preferences */
@media (prefers-reduced-motion: reduce) {
    * {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

πŸ”Ή Screen Reader & Assistive Technology Support

Support screen readers and assistive technologies with semantic HTML (headings, landmarks, ARIA roles), proper text alternatives for images, and managing dynamic content announcements. Use CSS to enhance rather than replace semantic meaningβ€”for example, hiding content visually but keeping it accessible to screen readers with clip-path or absolute positioning. Testing with NVDA, VoiceOver, or JAWS ensures that visual design does not create barriers for users relying on assistive technologies.

/* Screen reader only content */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Show on focus for keyboard users */
.sr-only-focusable:focus {
    position: static;
    width: auto;
    height: auto;
    padding: inherit;
    margin: inherit;
    overflow: visible;
    clip: auto;
    white-space: normal;
}

/* Hide decorative content from screen readers */
.decorative {
    /* Use aria-hidden="true" in HTML */
    /* This CSS ensures it's not focusable */
    pointer-events: none;
}

/* Ensure interactive elements are visible */
.interactive-element {
    /* Never use display: none or visibility: hidden on interactive elements */
    /* Use opacity: 0 with pointer-events: none if needed */
}

/* High contrast mode support */
@media (prefers-contrast: high) {
    .button {
        border: 2px solid;
    }
    
    .card {
        border: 1px solid;
    }
}

/* Reduced motion preferences */
@media (prefers-reduced-motion: reduce) {
    .animated-element {
        animation: none;
        transition: none;
    }
}

/* Dark mode support */
@media (prefers-color-scheme: dark) {
    :root {
        --bg-color: #1a1a1a;
        --text-color: #ffffff;
        --link-color: #66b3ff;
    }
}

πŸ”Ή Accessibility Testing & Tools

Testing Methods:

  • Keyboard Navigation: Tab through your entire site
  • Screen Reader: Test with NVDA, JAWS, or VoiceOver
  • Color Contrast: Use WebAIM Contrast Checker
  • Zoom Testing: Test at 200% zoom level
  • Mobile Testing: Test on actual devices

Automated Tools:

  • axe DevTools: Browser extension for accessibility testing
  • Lighthouse: Built-in Chrome accessibility audit
  • WAVE: Web accessibility evaluation tool
  • Color Oracle: Color blindness simulator

πŸ”Ή Accessibility Checklist

βœ… CSS Accessibility Checklist:

  1. Color Contrast: Minimum 4.5:1 for normal text, 3:1 for large text
  2. Focus Indicators: Visible focus styles for all interactive elements
  3. Font Size: Minimum 16px for body text, scalable with zoom
  4. Touch Targets: Minimum 44px Γ— 44px for mobile
  5. Color Independence: Don't rely solely on color to convey information
  6. Motion Preferences: Respect prefers-reduced-motion
  7. High Contrast: Support high contrast mode
  8. Zoom Support: Works at 200% zoom without horizontal scrolling
  9. Screen Reader: Proper hiding/showing of content
  10. Responsive Design: Works on all devices and orientations

🧠 Test Your Knowledge

What is the minimum color contrast ratio for normal text according to WCAG AA?