|

CSS 41 💻 prefers-color scheme and prefers-contrast media features

These two media features are essential for accessibility and personalization. They let you respect the user’s preferred color scheme (light/dark) and contrast level.


Overview of Features

FeatureDescriptionValues
prefers-color-schemeUser’s preferred color schemelight, dark
prefers-contrastUser’s preferred contrast levelno-preference, more, less, custom

1. prefers-color-scheme

The prefers-color-scheme media feature detects whether the user prefers a light or dark color theme.

@media (prefers-color-scheme: dark) {
    body {
        background-color: #333;
        color: white;
    }
}

Values

ValueDescription
lightUser prefers a light theme (or has no preference)
darkUser prefers a dark theme

How It Works

  • The user sets their preference in their operating system settings
  • Windows: Settings → Personalization → Colors → Choose your mode
  • macOS: System Preferences → General → Appearance
  • iOS: Settings → Display & Brightness → Appearance
  • Android: Settings → Display → Dark theme

Key Points:

  • light is the default if no preference is expressed
  • Always provide a light theme as the base, then enhance for dark
  • Use the same content and structure — only change colors
  • Test both themes for contrast and readability

2. prefers-contrast

The prefers-contrast media feature detects whether the user prefers more or less contrast.

@media (prefers-contrast: more) {
    body {
        background-color: #f0f0f0;
        color: #1a1a1a;
    }
}

Values

ValueDescription
no-preferenceNo specific preference (default)
moreUser prefers higher contrast
lessUser prefers lower contrast
customUser uses a specific set of colors/contrast

How It Works

  • The user sets their preference in their operating system accessibility settings
  • Windows: Settings → Ease of Access → Display → High contrast
  • macOS: System Preferences → Accessibility → Display → Increase contrast
  • iOS: Settings → Accessibility → Display & Text Size → Increase Contrast

Key Points:

  • more — increase contrast for better legibility
  • less — reduce contrast (for users sensitive to bright colors)
  • custom — user has chosen a specific color scheme (often with forced-colors)
  • Always ensure WCAG AAA contrast (7:1) for more

Complete Example

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>prefers-color-scheme and prefers-contrast</title>
    <style>
        *, *::before, *::after {
            box-sizing: border-box;
        }

        /* ====== BASE (LIGHT THEME) ====== */
        :root {
            --bg-primary: #ffffff;
            --bg-secondary: #f8f9fa;
            --bg-tertiary: #e9ecef;
            --text-primary: #212529;
            --text-secondary: #6c757d;
            --accent: #007bff;
            --accent-hover: #0056b3;
            --border: #dee2e6;
            --shadow: rgba(0, 0, 0, 0.1);
            --code-bg: #1e1e1e;
            --code-text: #d4d4d4;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            padding: 20px;
            background: var(--bg-secondary);
            color: var(--text-primary);
            max-width: 1200px;
            margin: 0 auto;
            line-height: 1.6;
            transition: background 0.3s, color 0.3s;
        }

        h1 {
            color: var(--accent);
            border-bottom: 3px solid var(--accent);
            padding-bottom: 10px;
        }

        h2 {
            color: var(--accent);
            border-left: 4px solid var(--accent);
            padding-left: 15px;
            margin-top: 30px;
        }

        h3 {
            color: var(--text-primary);
            margin-top: 20px;
        }

        section {
            background: var(--bg-primary);
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 10px var(--shadow);
            margin: 20px 0;
            transition: all 0.3s;
        }

        .code-block {
            background: var(--code-bg);
            color: var(--code-text);
            padding: 15px;
            border-radius: 8px;
            overflow-x: auto;
            font-family: 'Courier New', monospace;
            font-size: 0.9rem;
            line-height: 1.8;
            margin: 10px 0;
        }

        .reference-table {
            width: 100%;
            border-collapse: collapse;
            margin: 15px 0;
        }

        .reference-table th,
        .reference-table td {
            padding: 10px;
            border: 1px solid var(--border);
            text-align: left;
        }

        .reference-table th {
            background: var(--accent);
            color: white;
        }

        .reference-table tr:nth-child(even) {
            background: var(--bg-tertiary);
        }

        .note {
            font-size: 0.9rem;
            color: var(--text-secondary);
            margin-top: 5px;
        }

        .highlight {
            background: #ffc107;
            color: #333;
            padding: 2px 6px;
            border-radius: 4px;
            font-weight: bold;
        }

        /* ====== DARK THEME ====== */
        @media (prefers-color-scheme: dark) {
            :root {
                --bg-primary: #1a1a1a;
                --bg-secondary: #0d0d0d;
                --bg-tertiary: #2d2d2d;
                --text-primary: #f8f9fa;
                --text-secondary: #adb5bd;
                --accent: #4dabf7;
                --accent-hover: #339af0;
                --border: #444;
                --shadow: rgba(0, 0, 0, 0.5);
                --code-bg: #0d0d0d;
                --code-text: #d4d4d4;
            }
            .highlight {
                background: #4dabf7;
                color: #000;
            }
        }

        /* ====== HIGH CONTRAST ====== */
        @media (prefers-contrast: more) {
            :root {
                --bg-primary: #ffffff;
                --bg-secondary: #ffffff;
                --bg-tertiary: #f0f0f0;
                --text-primary: #000000;
                --text-secondary: #1a1a1a;
                --accent: #0000cc;
                --accent-hover: #000099;
                --border: #000000;
                --shadow: rgba(0, 0, 0, 0.3);
            }
            body {
                border: 2px solid #000;
                padding: 25px;
            }
            section {
                border: 2px solid #000;
                box-shadow: none;
            }
            h1 {
                border-bottom-width: 4px;
            }
            h2 {
                border-left-width: 6px;
            }
            .code-block {
                background: #000;
                color: #fff;
                border: 2px solid #000;
            }
            .reference-table th {
                background: #000;
                color: #fff;
            }
            .reference-table td {
                border-color: #000;
            }
            .note {
                color: #1a1a1a;
            }
            .highlight {
                background: #000;
                color: #fff;
                border: 1px solid #000;
            }
        }

        @media (prefers-contrast: more) and (prefers-color-scheme: dark) {
            :root {
                --bg-primary: #000000;
                --bg-secondary: #000000;
                --bg-tertiary: #1a1a1a;
                --text-primary: #ffffff;
                --text-secondary: #f0f0f0;
                --accent: #66b3ff;
                --accent-hover: #99ccff;
                --border: #ffffff;
            }
            body {
                border-color: #fff;
            }
            section {
                border-color: #fff;
            }
            .code-block {
                background: #000;
                color: #fff;
                border-color: #fff;
            }
            .reference-table th {
                background: #fff;
                color: #000;
            }
            .reference-table td {
                border-color: #fff;
            }
            .highlight {
                background: #fff;
                color: #000;
            }
        }

        /* ====== LOW CONTRAST ====== */
        @media (prefers-contrast: less) {
            :root {
                --bg-primary: #2d2d2d;
                --bg-secondary: #1a1a1a;
                --bg-tertiary: #3d3d3d;
                --text-primary: #d0d0d0;
                --text-secondary: #999;
                --accent: #6c9bd2;
                --accent-hover: #8aadd4;
                --border: #444;
                --shadow: rgba(0, 0, 0, 0.3);
            }
            .highlight {
                background: #6c9bd2;
                color: #1a1a1a;
            }
        }

        /* ====== DETECTION CARDS ====== */
        .detection-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 15px;
            margin: 20px 0;
        }

        .detection-card {
            padding: 15px;
            border-radius: 8px;
            text-align: center;
            border: 2px solid var(--border);
            background: var(--bg-tertiary);
            transition: all 0.3s;
        }

        .detection-card .label {
            font-size: 0.85rem;
            color: var(--text-secondary);
            display: block;
            margin-bottom: 5px;
        }

        .detection-card .value {
            font-size: 1.1rem;
            font-weight: bold;
            color: var(--accent);
        }

        .detection-card.active {
            border-color: var(--accent);
            background: var(--bg-primary);
        }

        /* ====== LIVE INDICATOR ====== */
        .live-indicator {
            position: fixed;
            bottom: 20px;
            right: 20px;
            background: var(--accent);
            color: white;
            padding: 12px 20px;
            border-radius: 50px;
            font-weight: bold;
            font-size: 0.85rem;
            box-shadow: 0 4px 15px var(--shadow);
            z-index: 1000;
            transition: all 0.3s;
            display: flex;
            flex-direction: column;
            gap: 3px;
        }

        .live-indicator .detail {
            font-size: 0.75rem;
            opacity: 0.9;
        }

        /* ====== PRACTICAL: THEME TOGGLE DEMO ====== */
        .theme-demo {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            margin: 15px 0;
        }

        .theme-card {
            flex: 1;
            min-width: 250px;
            padding: 20px;
            border-radius: 12px;
            border: 2px solid var(--border);
            background: var(--bg-primary);
            transition: all 0.3s;
        }

        .theme-card h4 {
            margin-top: 0;
            color: var(--accent);
        }

        .theme-card .preview {
            padding: 15px;
            border-radius: 8px;
            background: var(--bg-tertiary);
            margin: 10px 0;
            text-align: center;
            font-weight: bold;
            border: 1px solid var(--border);
        }

        /* Light preview */
        .light-preview {
            background: #ffffff;
            color: #212529;
        }

        /* Dark preview */
        .dark-preview {
            background: #1a1a1a;
            color: #f8f9fa;
        }

        /* ====== CONTRAST VISUALIZATION ====== */
        .contrast-demo {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            margin: 15px 0;
        }

        .contrast-box {
            flex: 1;
            min-width: 200px;
            padding: 20px;
            border-radius: 8px;
            text-align: center;
            font-weight: bold;
            border: 2px solid var(--border);
        }

        .contrast-normal {
            background: #ffffff;
            color: #6c757d;
        }

        .contrast-more {
            background: #ffffff;
            color: #000000;
            border-color: #000;
        }

        .contrast-less {
            background: #2d2d2d;
            color: #999;
        }

        /* ====== ACCESSIBILITY TIPS ====== */
        .tip-box {
            padding: 15px;
            border-radius: 8px;
            margin: 10px 0;
            border-left: 4px solid var(--accent);
            background: var(--bg-tertiary);
        }

        .tip-box.success {
            border-left-color: #28a745;
        }

        .tip-box.warning {
            border-left-color: #ffc107;
        }

        .tip-box.danger {
            border-left-color: #dc3545;
        }
    </style>
</head>
<body>

    <h1>prefers-color-scheme and prefers-contrast</h1>

    <!-- ====== 1. COLOR SCHEME DEMO ====== -->
    <section>
        <h2>1. prefers-color-scheme</h2>
        <p>Detects the user's preferred <strong>color scheme</strong> (light or dark).</p>

        <div class="theme-demo">
            <div class="theme-card">
                <h4>☀️ Light Theme</h4>
                <div class="preview light-preview">
                    This is a light theme preview
                </div>
                <p class="note">Applied when user prefers light mode (or has no preference).</p>
            </div>
            <div class="theme-card">
                <h4>🌙 Dark Theme</h4>
                <div class="preview dark-preview">
                    This is a dark theme preview
                </div>
                <p class="note">Applied when user prefers dark mode.</p>
            </div>
        </div>

        <div class="code-block">
            /* Light theme (default) */
            :root {
                --bg-primary: #ffffff;
                --text-primary: #212529;
                --accent: #007bff;
            }

            /* Dark theme */
            @media (prefers-color-scheme: dark) {
                :root {
                    --bg-primary: #1a1a1a;
                    --text-primary: #f8f9fa;
                    --accent: #4dabf7;
                }
            }
        </div>

        <p class="note"><strong>Try it:</strong> Change your OS theme to dark mode and watch this page adapt!</p>
    </section>

    <!-- ====== 2. CONTRAST DEMO ====== -->
    <section>
        <h2>2. prefers-contrast</h2>
        <p>Detects the user's preferred <strong>contrast level</strong>.</p>

        <div class="contrast-demo">
            <div class="contrast-box contrast-normal">
                Normal Contrast<br>
                <small>#6c757d on #ffffff</small>
            </div>
            <div class="contrast-box contrast-more">
                More Contrast<br>
                <small>#000000 on #ffffff</small>
            </div>
            <div class="contrast-box contrast-less">
                Less Contrast<br>
                <small>#999 on #2d2d2d</small>
            </div>
        </div>

        <div class="code-block">
            /* High contrast preference */
            @media (prefers-contrast: more) {
                :root {
                    --text-primary: #000000;
                    --bg-primary: #ffffff;
                    --accent: #0000cc;
                }
                section {
                    border: 2px solid #000;
                    box-shadow: none;
                }
            }

            /* Low contrast preference */
            @media (prefers-contrast: less) {
                :root {
                    --bg-primary: #2d2d2d;
                    --text-primary: #d0d0d0;
                    --accent: #6c9bd2;
                }
            }
        </div>
    </section>

    <!-- ====== 3. COMBINED THEME + CONTRAST ====== -->
    <section>
        <h2>3. Combined Color Scheme + Contrast</h2>
        <p>Both features can work together for a fully personalized experience.</p>

        <div class="code-block">
            /* Dark + High Contrast */
            @media (prefers-contrast: more) and (prefers-color-scheme: dark) {
                :root {
                    --bg-primary: #000000;
                    --text-primary: #ffffff;
                    --accent: #66b3ff;
                    --border: #ffffff;
                }
            }

            /* Dark + Low Contrast */
            @media (prefers-contrast: less) and (prefers-color-scheme: dark) {
                :root {
                    --bg-primary: #2d2d2d;
                    --text-primary: #d0d0d0;
                }
            }
        </div>
    </section>

    <!-- ====== 4. DETECTION SUMMARY ====== -->
    <section>
        <h2>4. Your Preferences</h2>
        <p>Below is a live detection of your preferences.</p>

        <div class="detection-grid">
            <div class="detection-card" id="scheme-light">
                <span class="label">prefers-color-scheme: light</span>
                <span class="value" id="scheme-light-value">Detecting...</span>
            </div>
            <div class="detection-card" id="scheme-dark">
                <span class="label">prefers-color-scheme: dark</span>
                <span class="value" id="scheme-dark-value">Detecting...</span>
            </div>
            <div class="detection-card" id="contrast-no-pref">
                <span class="label">prefers-contrast: no-preference</span>
                <span class="value" id="contrast-no-pref-value">Detecting...</span>
            </div>
            <div class="detection-card" id="contrast-more">
                <span class="label">prefers-contrast: more</span>
                <span class="value" id="contrast-more-value">Detecting...</span>
            </div>
            <div class="detection-card" id="contrast-less">
                <span class="label">prefers-contrast: less</span>
                <span class="value" id="contrast-less-value">Detecting...</span>
            </div>
            <div class="detection-card" id="contrast-custom">
                <span class="label">prefers-contrast: custom</span>
                <span class="value" id="contrast-custom-value">Detecting...</span>
            </div>
        </div>

        <div class="code-block">
            /* Detect color scheme */
            @media (prefers-color-scheme: light) { /* Light preference */ }
            @media (prefers-color-scheme: dark) { /* Dark preference */ }

            /* Detect contrast preference */
            @media (prefers-contrast: no-preference) { /* Default */ }
            @media (prefers-contrast: more) { /* High contrast */ }
            @media (prefers-contrast: less) { /* Low contrast */ }
            @media (prefers-contrast: custom) { /* Custom */ }
        </div>
    </section>

    <!-- ====== 5. ACCESSIBILITY TIPS ====== -->
    <section>
        <h2>5. Accessibility Tips</h2>

        <div class="tip-box success">
            <strong>✅ Do This:</strong>
            <ul style="margin: 5px 0;">
                <li>Start with light theme as the base</li>
                <li>Use CSS custom properties (variables) for easy theming</li>
                <li>Test both light and dark themes for contrast</li>
                <li>Respect the user's system preferences</li>
                <li>Ensure WCAG AA (4.5:1) or AAA (7:1) contrast</li>
            </ul>
        </div>

        <div class="tip-box warning">
            <strong>⚠️ Be Careful:</strong>
            <ul style="margin: 5px 0;">
                <li>Don't use pure black (#000) on pure white (#fff) — it's harsh</li>
                <li>Don't use pure white (#fff) on pure black (#000) — it causes halation</li>
                <li>Don't forget to test with actual users</li>
                <li>Don't override user preferences without good reason</li>
            </ul>
        </div>

        <div class="tip-box danger">
            <strong>❌ Don't Do This:</strong>
            <ul style="margin: 5px 0;">
                <li>Don't ignore user preferences — it's an accessibility issue</li>
                <li>Don't use low-contrast text (#999 on #fff)</li>
                <li>Don't rely solely on color to convey information</li>
                <li>Don't forget about images — they need dark mode variants too</li>
            </ul>
        </div>
    </section>

    <!-- ====== 6. REFERENCE TABLES ====== -->
    <section>
        <h2>6. Reference Tables</h2>

        <h3>prefers-color-scheme Values</h3>
        <table class="reference-table">
            <tr>
                <th>Value</th>
                <th>Description</th>
            </tr>
            <tr>
                <td><code>light</code></td>
                <td>User prefers a light theme (or has no preference)</td>
            </tr>
            <tr>
                <td><code>dark</code></td>
                <td>User prefers a dark theme</td>
            </tr>
        </table>

        <h3>prefers-contrast Values</h3>
        <table class="reference-table">
            <tr>
                <th>Value</th>
                <th>Description</th>
            </tr>
            <tr>
                <td><code>no-preference</code></td>
                <td>No specific preference (default)</td>
            </tr>
            <tr>
                <td><code>more</code></td>
                <td>User prefers higher contrast</td>
            </tr>
            <tr>
                <td><code>less</code></td>
                <td>User prefers lower contrast</td>
            </tr>
            <tr>
                <td><code>custom</code></td>
                <td>User uses a specific set of colors/contrast</td>
            </tr>
        </table>

        <h3>WCAG Contrast Requirements</h3>
        <table class="reference-table">
            <tr>
                <th>Level</th>
                <th>Normal Text</th>
                <th>Large Text</th>
            </tr>
            <tr>
                <td><strong>AA</strong></td>
                <td>4.5:1</td>
                <td>3:1</td>
            </tr>
            <tr>
                <td><strong>AAA</strong></td>
                <td>7:1</td>
                <td>4.5:1</td>
            </tr>
        </table>
    </section>

    <!-- ====== 7. BEST PRACTICES ====== -->
    <section>
        <h2>7. Best Practices</h2>

        <div style="background: #d4edda; padding: 20px; border-radius: 8px; border-left: 4px solid #28a745;">
            <h3 style="margin-top: 0; color: #155724;">✅ Do This:</h3>
            <ul>
                <li>Use CSS custom properties for theming</li>
                <li>Start with light theme, then add dark theme overrides</li>
                <li>Test both themes for readability and contrast</li>
                <li>Respect <code>prefers-contrast: more</code> for accessibility</li>
                <li>Use <code>prefers-contrast: less</code> for users sensitive to bright colors</li>
                <li>Combine both features for a fully personalized experience</li>
                <li>Test with real users who have accessibility needs</li>
            </ul>
        </div>

        <div style="background: #f8d7da; padding: 20px; border-radius: 8px; border-left: 4px solid #dc3545; margin-top: 15px;">
            <h3 style="margin-top: 0; color: #721c24;">❌ Don't Do This:</h3>
            <ul>
                <li>Don't ignore user preferences — it's an accessibility issue</li>
                <li>Don't use pure black on pure white (or vice versa)</li>
                <li>Don't forget to test with actual users</li>
                <li>Don't use color alone to convey information</li>
                <li>Don't force a theme on users without an option to change</li>
            </ul>
        </div>
    </section>

    <!-- ====== LIVE INDICATOR ====== -->
    <div class="live-indicator" id="live-indicator">
        <span id="indicator-scheme">Scheme: —</span>
        <span class="detail" id="indicator-contrast">Contrast: —</span>
    </div>

    <!-- ====== SCRIPT FOR DETECTION ====== -->
    <script>
        function updateIndicators() {
            // Color scheme detection
            const schemeLight = document.getElementById('scheme-light');
            const schemeDark = document.getElementById('scheme-dark');

            const isLight = window.matchMedia('(prefers-color-scheme: light)').matches;
            const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;

            function setCard(card, isActive, activeText, inactiveText) {
                const value = card.querySelector('.value');
                if (isActive) {
                    value.textContent = activeText;
                    card.classList.add('active');
                } else {
                    value.textContent = inactiveText;
                    card.classList.remove('active');
                }
            }

            setCard(schemeLight, isLight, 'Preferred ✅', 'Not preferred');
            setCard(schemeDark, isDark, 'Preferred ✅', 'Not preferred');

            // Contrast detection
            const contrastNoPref = document.getElementById('contrast-no-pref');
            const contrastMore = document.getElementById('contrast-more');
            const contrastLess = document.getElementById('contrast-less');
            const contrastCustom = document.getElementById('contrast-custom');

            const isNoPref = window.matchMedia('(prefers-contrast: no-preference)').matches;
            const isMore = window.matchMedia('(prefers-contrast: more)').matches;
            const isLess = window.matchMedia('(prefers-contrast: less)').matches;
            const isCustom = window.matchMedia('(prefers-contrast: custom)').matches;

            setCard(contrastNoPref, isNoPref, 'Active ✅', 'Not active');
            setCard(contrastMore, isMore, 'Active ✅', 'Not active');
            setCard(contrastLess, isLess, 'Active ✅', 'Not active');
            setCard(contrastCustom, isCustom, 'Active ✅', 'Not active');

            // Live indicator
            const indicatorScheme = document.getElementById('indicator-scheme');
            const indicatorContrast = document.getElementById('indicator-contrast');
            const indicator = document.getElementById('live-indicator');

            let schemeText = isDark ? '🌙 Dark' : '☀️ Light';
            indicatorScheme.textContent = 'Scheme: ' + schemeText;

            let contrastText = 'Default';
            if (isMore) contrastText = 'More';
            else if (isLess) contrastText = 'Less';
            else if (isCustom) contrastText = 'Custom';
            indicatorContrast.textContent = 'Contrast: ' + contrastText;

            // Update indicator color based on contrast
            if (isMore) {
                indicator.style.background = '#000';
                indicator.style.color = '#fff';
                indicator.style.border = '2px solid #fff';
            } else if (isLess) {
                indicator.style.background = '#6c9bd2';
                indicator.style.color = '#1a1a1a';
                indicator.style.border = 'none';
            } else {
                indicator.style.background = isDark ? '#4dabf7' : '#007bff';
                indicator.style.color = 'white';
                indicator.style.border = 'none';
            }
        }

        window.addEventListener('load', updateIndicators);

        // Listen for changes
        window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', updateIndicators);
        window.matchMedia('(prefers-contrast: more)').addEventListener('change', updateIndicators);
        window.matchMedia('(prefers-contrast: less)').addEventListener('change', updateIndicators);

        updateIndicators();
    </script>

</body>
</html>

Quick Reference

FeatureDescriptionValues
prefers-color-schemeUser’s preferred color schemelight, dark
prefers-contrastUser’s preferred contrast levelno-preference, more, less, custom

prefers-color-scheme Values

ValueDescription
lightUser prefers a light theme (or has no preference)
darkUser prefers a dark theme

prefers-contrast Values

ValueDescription
no-preferenceNo specific preference (default)
moreUser prefers higher contrast
lessUser prefers lower contrast
customUser uses a specific set of colors/contrast

WCAG Contrast Requirements

LevelNormal TextLarge Text
AA4.5:13:1
AAA7:14.5:1

Best Practices

Do This:

/* Base light theme */
:root {
    --bg: #ffffff;
    --text: #212529;
    --accent: #007bff;
}

/* Dark theme overrides */
@media (prefers-color-scheme: dark) {
    :root {
        --bg: #1a1a1a;
        --text: #f8f9fa;
        --accent: #4dabf7;
    }
}

/* High contrast */
@media (prefers-contrast: more) {
    :root {
        --bg: #ffffff;
        --text: #000000;
        --accent: #0000cc;
    }
    section {
        border: 2px solid #000;
        box-shadow: none;
    }
}

/* Combined dark + high contrast */
@media (prefers-contrast: more) and (prefers-color-scheme: dark) {
    :root {
        --bg: #000000;
        --text: #ffffff;
        --accent: #66b3ff;
    }
}

Don’t Do This:

/* Don't use pure black on pure white */
body {
    background: #fff;
    color: #000; /* Harsh — use #212529 instead */
}

/* Don't ignore user preferences */
body {
    background: #fff;
    color: #333;
    /* No dark mode support — accessibility issue */
}

/* Don't use low contrast */
.note {
    color: #ccc; /* On white — fails WCAG */
    background: #fff;
}

/* Don't rely solely on color */
.error {
    color: red; /* Add icons or text too */
}

Pro Tip: prefers-color-scheme and prefers-contrast are essential for accessibility. Always start with a light theme as the base, then enhance for dark mode. Use CSS custom properties for easy theming. Respect prefers-contrast: more by increasing contrast and adding borders. Remember: pure black on pure white is harsh — use off-black (#212529) and off-white (#f8f9fa) for better readability. Test with real users who have accessibility needs, and always ensure your text meets WCAG AA (4.5:1) or AAA (7:1) contrast ratios!


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!