|

CSS 35 💻 forced-colors and grid media features

These two media features let you adapt styles for accessibility (high-contrast mode) and legacy devices (grid-based screens).


Overview of Features

FeatureDescriptionValues
forced-colorsDetects forced colors mode (e.g., Windows High Contrast)none, active
gridDetects if the device uses a grid-based screen0, 1

1. forced-colors

The forced-colors media feature detects when the user agent has forced colors mode enabled — such as Windows High Contrast mode or similar accessibility features.

@media (forced-colors: active) {
    button {
        border: 1px solid ButtonBorder;
    }
}

Values

ValueDescription
noneForced colors mode is not active (default)
activeForced colors mode is active

What Happens in Forced Colors Mode

When forced colors mode is active, the browser overrides many CSS properties:

PropertyForced To
box-shadownone
text-shadownone
background-imagenone
color-schemelight dark
scrollbar-colorauto
colorSystem color
background-colorSystem color
border-colorSystem color
outline-colorSystem color
text-decoration-colorSystem color
column-rule-colorSystem color

System Colors

You can use system colors that adapt to the user’s forced colors theme:

System ColorDescription
CanvasBackground of the document
CanvasTextText color
LinkTextLink color
ButtonFaceButton background
ButtonTextButton text
ButtonBorderButton border
HighlightSelected item background
HighlightTextSelected item text
GrayTextDisabled text
FieldInput field background
FieldTextInput field text
/* Use system colors in forced colors mode */
@media (forced-colors: active) {
    button {
        border: 1px solid ButtonBorder;
        background: ButtonFace;
        color: ButtonText;
    }
}

2. grid

The grid media feature checks whether the output device uses a grid-based screen (like old text-only terminals) or a bitmap-based screen (like modern computers and smartphones).

@media (grid: 0) {
    .text {
        color: red;
    }
}

@media (grid: 1) {
    .text {
        color: black;
    }
}

Values

ValueDescription
0Bitmap-based screen (modern devices)
1Grid-based screen (text-only terminals)

Grid vs Bitmap

Screen TypeDescriptionExamples
BitmapPixel-based, can display any imageComputers, smartphones, tablets
GridCharacter-based, fixed grid of charactersText-only terminals, old phones, braille displays

Key Points:

  • Modern devices almost always match grid: 0
  • Grid-based devices are rare (legacy or specialized)
  • Use grid: 1 to optimize for text-only terminals
  • Most developers will never need this feature — it’s for extreme edge cases

Complete Example

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

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            padding: 20px;
            background: #f8f9fa;
            max-width: 1200px;
            margin: 0 auto;
            line-height: 1.6;
            transition: background 0.3s, color 0.3s;
        }

        h1 {
            color: #007bff;
            border-bottom: 3px solid #007bff;
            padding-bottom: 10px;
        }

        h2 {
            color: #28a745;
            border-left: 4px solid #28a745;
            padding-left: 15px;
            margin-top: 30px;
        }

        h3 {
            color: #333;
            margin-top: 20px;
        }

        section {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            margin: 20px 0;
            transition: background 0.3s;
        }

        .code-block {
            background: #1e1e1e;
            color: #d4d4d4;
            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 #ddd;
            text-align: left;
        }

        .reference-table th {
            background: #007bff;
            color: white;
        }

        .reference-table tr:nth-child(even) {
            background: #f8f9fa;
        }

        .note {
            font-size: 0.9rem;
            color: #6c757d;
            margin-top: 5px;
        }

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

        /* ====== BUTTON STYLES ====== */
        button {
            padding: 12px 24px;
            color: white;
            background-color: #007bff;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-size: 1em;
            font-weight: bold;
            transition: all 0.3s;
            margin: 5px;
        }

        button:hover {
            background-color: #0056b3;
            transform: translateY(-2px);
        }

        button.btn-danger {
            background-color: #dc3545;
        }
        button.btn-danger:hover {
            background-color: #a71d2a;
        }

        button.btn-success {
            background-color: #28a745;
        }
        button.btn-success:hover {
            background-color: #1e7e34;
        }

        button.btn-warning {
            background-color: #ffc107;
            color: #333;
        }
        button.btn-warning:hover {
            background-color: #d39e00;
        }

        /* ====== FORCED COLORS DEMO ====== */
        .forced-colors-demo {
            padding: 20px;
            border-radius: 8px;
            background: #e9ecef;
            margin: 15px 0;
            border: 2px solid #ddd;
            transition: all 0.3s;
        }

        .forced-colors-demo .demo-box {
            padding: 15px;
            background: #007bff;
            color: white;
            border-radius: 8px;
            margin: 10px 0;
            text-align: center;
            font-weight: bold;
            transition: all 0.3s;
        }

        /* Forced colors mode styles */
        @media (forced-colors: active) {
            body {
                background: Canvas;
                color: CanvasText;
            }
            section {
                background: Canvas;
                border: 1px solid CanvasText;
            }
            h1, h2, h3 {
                color: CanvasText;
            }
            h1 {
                border-bottom-color: CanvasText;
            }
            h2 {
                border-left-color: CanvasText;
            }
            .forced-colors-demo {
                background: Canvas;
                border: 1px solid CanvasText;
            }
            .forced-colors-demo .demo-box {
                background: ButtonFace;
                color: ButtonText;
                border: 1px solid ButtonBorder;
            }
            button {
                border: 1px solid ButtonBorder;
                background: ButtonFace;
                color: ButtonText;
            }
            button:hover {
                background: Highlight;
                color: HighlightText;
            }
            .code-block {
                background: Canvas;
                color: CanvasText;
                border: 1px solid CanvasText;
            }
            .reference-table th {
                background: ButtonFace;
                color: ButtonText;
                border: 1px solid ButtonBorder;
            }
            .reference-table td {
                border: 1px solid CanvasText;
            }
            .reference-table tr:nth-child(even) {
                background: Canvas;
            }
            a {
                color: LinkText;
            }
            .highlight {
                background: Highlight;
                color: HighlightText;
            }
        }

        /* ====== GRID DEMO ====== */
        .grid-demo {
            padding: 20px;
            border-radius: 8px;
            background: #e9ecef;
            margin: 15px 0;
            border: 2px solid #ddd;
            transition: all 0.3s;
        }

        .grid-demo .header {
            font-size: 1.2rem;
            font-weight: bold;
            margin-bottom: 10px;
            transition: color 0.3s;
        }

        .grid-demo .text {
            transition: color 0.3s;
        }

        /* Bitmap-based screen (modern devices) */
        @media (grid: 0) {
            .grid-demo .header {
                color: #6c757d;
            }
            .grid-demo .text {
                color: #dc3545;
            }
        }

        /* Grid-based screen (text-only terminals) */
        @media (grid: 1) {
            .grid-demo .header {
                color: #6c757d;
            }
            .grid-demo .text {
                color: #000;
            }
        }

        /* ====== 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 #ddd;
            background: #f8f9fa;
            transition: all 0.3s;
        }

        .detection-card .label {
            font-size: 0.85rem;
            color: #666;
            display: block;
            margin-bottom: 5px;
        }

        .detection-card .value {
            font-size: 1.1rem;
            font-weight: bold;
            color: #007bff;
        }

        /* ====== SYSTEM COLORS DEMO ====== */
        .system-colors-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 10px;
            margin: 15px 0;
        }

        .system-color-box {
            padding: 15px;
            border-radius: 8px;
            text-align: center;
            font-weight: bold;
            border: 2px solid #ddd;
            transition: all 0.3s;
        }

        /* Default colors */
        .sys-canvas { background: #ffffff; color: #000000; }
        .sys-canvastext { background: #f0f0f0; color: #000000; }
        .sys-linktext { background: #e0e0ff; color: #0000ff; }
        .sys-buttonface { background: #e9ecef; color: #333; }
        .sys-buttontext { background: #007bff; color: #ffffff; }
        .sys-buttonborder { background: #e9ecef; color: #333; border: 3px solid #007bff; }
        .sys-highlight { background: #ffc107; color: #333; }
        .sys-highlighttext { background: #fff3cd; color: #856404; }
        .sys-graytext { background: #e9ecef; color: #999; }
        .sys-field { background: #ffffff; color: #333; border: 2px solid #ccc; }
        .sys-fieldtext { background: #ffffff; color: #333; }

        /* Forced colors mode: use system colors */
        @media (forced-colors: active) {
            .sys-canvas { background: Canvas; color: CanvasText; }
            .sys-canvastext { background: Canvas; color: CanvasText; }
            .sys-linktext { background: Canvas; color: LinkText; }
            .sys-buttonface { background: ButtonFace; color: ButtonText; }
            .sys-buttontext { background: ButtonFace; color: ButtonText; }
            .sys-buttonborder { background: ButtonFace; color: ButtonText; border-color: ButtonBorder; }
            .sys-highlight { background: Highlight; color: HighlightText; }
            .sys-highlighttext { background: Highlight; color: HighlightText; }
            .sys-graytext { background: Canvas; color: GrayText; }
            .sys-field { background: Field; color: FieldText; }
            .sys-fieldtext { background: Field; color: FieldText; }
        }

        /* ====== LIVE INDICATOR ====== */
        .live-indicator {
            position: fixed;
            bottom: 20px;
            right: 20px;
            background: #007bff;
            color: white;
            padding: 12px 20px;
            border-radius: 50px;
            font-weight: bold;
            font-size: 0.85rem;
            box-shadow: 0 4px 15px rgba(0,123,255,0.4);
            z-index: 1000;
            transition: all 0.3s;
        }

        @media (forced-colors: active) {
            .live-indicator {
                background: Highlight;
                color: HighlightText;
                border: 1px solid ButtonBorder;
                box-shadow: none;
            }
        }

        /* ====== BEST PRACTICE DEMO ====== */
        .best-practice-card {
            background: white;
            border: 2px solid #ddd;
            border-radius: 12px;
            padding: 20px;
            max-width: 400px;
            margin: 20px auto;
            text-align: center;
            box-shadow: 0 4px 15px rgba(0,0,0,0.1);
            transition: all 0.3s;
        }

        .best-practice-card h3 {
            margin-top: 0;
            color: #007bff;
        }

        .best-practice-card .btn {
            display: inline-block;
            padding: 12px 30px;
            background: #007bff;
            color: white;
            border-radius: 8px;
            text-decoration: none;
            font-weight: bold;
            margin-top: 10px;
            transition: all 0.3s;
        }

        .best-practice-card .btn:hover {
            background: #28a745;
            transform: scale(1.02);
        }

        @media (forced-colors: active) {
            .best-practice-card {
                background: Canvas;
                border: 1px solid CanvasText;
                box-shadow: none;
            }
            .best-practice-card h3 {
                color: CanvasText;
            }
            .best-practice-card .btn {
                background: ButtonFace;
                color: ButtonText;
                border: 1px solid ButtonBorder;
            }
            .best-practice-card .btn:hover {
                background: Highlight;
                color: HighlightText;
            }
        }
    </style>
</head>
<body>

    <h1>forced-colors and grid Media Features</h1>

    <!-- ====== 1. FORCED-COLORS DEMO ====== -->
    <section>
        <h2>1. forced-colors</h2>
        <p>Detects when the user has <strong>forced colors mode</strong> enabled (e.g., Windows High Contrast).</p>

        <div class="forced-colors-demo">
            <h3>Forced Colors Demo</h3>
            <p>This box adapts to forced colors mode:</p>
            <div class="demo-box">
                I change colors in forced colors mode!
            </div>

            <div style="margin-top: 15px;">
                <button>Primary Button</button>
                <button class="btn-danger">Danger Button</button>
                <button class="btn-success">Success Button</button>
                <button class="btn-warning">Warning Button</button>
            </div>
        </div>

        <p class="note">
            <strong>Try it:</strong> Enable Windows High Contrast mode or a similar accessibility feature to see these styles change.
        </p>

        <div class="code-block">
            /* Detect forced colors mode */
            @media (forced-colors: active) {
                button {
                    border: 1px solid ButtonBorder;
                    background: ButtonFace;
                    color: ButtonText;
                }
                button:hover {
                    background: Highlight;
                    color: HighlightText;
                }
            }
        </div>
    </section>

    <!-- ====== 2. SYSTEM COLORS DEMO ====== -->
    <section>
        <h2>2. System Colors</h2>
        <p>System colors adapt to the user's forced colors theme.</p>

        <div class="system-colors-grid">
            <div class="system-color-box sys-canvas">Canvas</div>
            <div class="system-color-box sys-canvastext">CanvasText</div>
            <div class="system-color-box sys-linktext">LinkText</div>
            <div class="system-color-box sys-buttonface">ButtonFace</div>
            <div class="system-color-box sys-buttontext">ButtonText</div>
            <div class="system-color-box sys-buttonborder">ButtonBorder</div>
            <div class="system-color-box sys-highlight">Highlight</div>
            <div class="system-color-box sys-highlighttext">HighlightText</div>
            <div class="system-color-box sys-graytext">GrayText</div>
            <div class="system-color-box sys-field">Field</div>
            <div class="system-color-box sys-fieldtext">FieldText</div>
        </div>

        <div class="code-block">
            /* System colors adapt automatically */
            .button {
                background: ButtonFace;
                color: ButtonText;
                border: 1px solid ButtonBorder;
            }

            .selected {
                background: Highlight;
                color: HighlightText;
            }

            .disabled {
                color: GrayText;
            }

            input {
                background: Field;
                color: FieldText;
            }
        </div>
    </section>

    <!-- ====== 3. GRID DEMO ====== -->
    <section>
        <h2>3. grid</h2>
        <p>Detects whether the device uses a <strong>grid-based screen</strong> (text-only terminal) or <strong>bitmap-based screen</strong> (modern device).</p>

        <div class="grid-demo">
            <div class="header">Header (always gray)</div>
            <div class="text">
                This text is <span class="highlight">red</span> on bitmap screens and <span class="highlight">black</span> on grid-based screens.
            </div>
        </div>

        <div id="grid-detection" class="detection-card" style="margin: 15px 0;">
            <span class="label">Current screen type:</span>
            <span class="value" id="grid-value">Detecting...</span>
        </div>

        <div class="code-block">
            /* Bitmap-based screen (modern devices) */
            @media (grid: 0) {
                .text {
                    color: red;
                }
            }

            /* Grid-based screen (text-only terminals) */
            @media (grid: 1) {
                .text {
                    color: black;
                }
            }
        </div>

        <p class="note"><strong>Note:</strong> Modern devices almost always match <code>grid: 0</code>. Grid-based devices are rare (legacy terminals, braille displays).</p>
    </section>

    <!-- ====== 4. DETECTION SUMMARY ====== -->
    <section>
        <h2>4. Your Device's Capabilities</h2>
        <p>Below is a live detection of your device's capabilities.</p>

        <div class="detection-grid">
            <div class="detection-card" id="fc-active">
                <span class="label">forced-colors: active</span>
                <span class="value" id="fc-active-value">Detecting...</span>
            </div>
            <div class="detection-card" id="fc-none">
                <span class="label">forced-colors: none</span>
                <span class="value" id="fc-none-value">Detecting...</span>
            </div>
            <div class="detection-card" id="grid-0">
                <span class="label">grid: 0 (bitmap)</span>
                <span class="value" id="grid-0-value">Detecting...</span>
            </div>
            <div class="detection-card" id="grid-1">
                <span class="label">grid: 1 (grid-based)</span>
                <span class="value" id="grid-1-value">Detecting...</span>
            </div>
        </div>

        <div class="code-block">
            /* Detect forced colors */
            @media (forced-colors: active) { /* Forced colors ON */ }
            @media (forced-colors: none) { /* Forced colors OFF */ }

            /* Detect screen type */
            @media (grid: 0) { /* Bitmap screen */ }
            @media (grid: 1) { /* Grid-based screen */ }
        </div>
    </section>

    <!-- ====== 5. PRACTICAL EXAMPLE ====== -->
    <section>
        <h2>5. Practical Example: Accessible Card</h2>
        <p>This card is fully accessible in forced colors mode.</p>

        <div class="best-practice-card">
            <h3>📱 Accessible Card</h3>
            <p>This card uses system colors and proper borders to remain usable in forced colors mode.</p>
            <a href="#" class="btn">Learn More</a>
        </div>

        <div class="code-block">
            /* Default styles */
            .card {
                background: white;
                border: 2px solid #ddd;
            }

            /* Forced colors mode */
            @media (forced-colors: active) {
                .card {
                    background: Canvas;
                    border: 1px solid CanvasText;
                }
                .card .btn {
                    background: ButtonFace;
                    color: ButtonText;
                    border: 1px solid ButtonBorder;
                }
            }
        </div>
    </section>

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

        <h3>forced-colors Values</h3>
        <table class="reference-table">
            <tr>
                <th>Value</th>
                <th>Description</th>
            </tr>
            <tr>
                <td><code>none</code></td>
                <td>Forced colors mode is not active (default)</td>
            </tr>
            <tr>
                <td><code>active</code></td>
                <td>Forced colors mode is active</td>
            </tr>
        </table>

        <h3>Properties Forced in Forced Colors Mode</h3>
        <table class="reference-table">
            <tr>
                <th>Property</th>
                <th>Forced To</th>
            </tr>
            <tr>
                <td><code>box-shadow</code></td>
                <td><code>none</code></td>
            </tr>
            <tr>
                <td><code>text-shadow</code></td>
                <td><code>none</code></td>
            </tr>
            <tr>
                <td><code>background-image</code></td>
                <td><code>none</code></td>
            </tr>
            <tr>
                <td><code>color-scheme</code></td>
                <td><code>light dark</code></td>
            </tr>
            <tr>
                <td><code>scrollbar-color</code></td>
                <td><code>auto</code></td>
            </tr>
        </table>

        <h3>Common System Colors</h3>
        <table class="reference-table">
            <tr>
                <th>System Color</th>
                <th>Description</th>
            </tr>
            <tr>
                <td><code>Canvas</code></td>
                <td>Background of the document</td>
            </tr>
            <tr>
                <td><code>CanvasText</code></td>
                <td>Text color</td>
            </tr>
            <tr>
                <td><code>LinkText</code></td>
                <td>Link color</td>
            </tr>
            <tr>
                <td><code>ButtonFace</code></td>
                <td>Button background</td>
            </tr>
            <tr>
                <td><code>ButtonText</code></td>
                <td>Button text</td>
            </tr>
            <tr>
                <td><code>ButtonBorder</code></td>
                <td>Button border</td>
            </tr>
            <tr>
                <td><code>Highlight</code></td>
                <td>Selected item background</td>
            </tr>
            <tr>
                <td><code>HighlightText</code></td>
                <td>Selected item text</td>
            </tr>
            <tr>
                <td><code>GrayText</code></td>
                <td>Disabled text</td>
            </tr>
            <tr>
                <td><code>Field</code></td>
                <td>Input field background</td>
            </tr>
            <tr>
                <td><code>FieldText</code></td>
                <td>Input field text</td>
            </tr>
        </table>

        <h3>grid Values</h3>
        <table class="reference-table">
            <tr>
                <th>Value</th>
                <th>Description</th>
                <th>Examples</th>
            </tr>
            <tr>
                <td><code>0</code></td>
                <td>Bitmap-based screen (modern)</td>
                <td>Computers, smartphones, tablets</td>
            </tr>
            <tr>
                <td><code>1</code></td>
                <td>Grid-based screen (character-based)</td>
                <td>Text-only terminals, braille displays</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 <code>forced-colors</code> to ensure your site is usable in high-contrast mode</li>
                <li>Use <strong>system colors</strong> (ButtonFace, CanvasText, etc.) for forced colors mode</li>
                <li>Add borders to elements that rely on background color for boundaries</li>
                <li>Test your site with Windows High Contrast mode enabled</li>
                <li>Use <code>grid</code> only if you need to support text-only terminals</li>
                <li>Provide meaningful content even without images or shadows</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 rely solely on background colors to convey meaning</li>
                <li>Don't use box-shadows as the only visual separator in forced colors mode</li>
                <li>Don't forget to test with accessibility features enabled</li>
                <li>Don't use <code>grid: 1</code> styles for modern devices (they won't match)</li>
                <li>Don't ignore forced colors mode — it affects millions of users</li>
            </ul>
        </div>
    </section>

    <!-- ====== LIVE INDICATOR ====== -->
    <div class="live-indicator" id="live-indicator">Detecting...</div>

    <!-- ====== SCRIPT FOR DETECTION ====== -->
    <script>
        function updateIndicators() {
            const indicator = document.getElementById('live-indicator');

            // Forced colors detection
            const fcActive = document.getElementById('fc-active');
            const fcNone = document.getElementById('fc-none');

            const isForcedColors = window.matchMedia('(forced-colors: active)').matches;

            if (isForcedColors) {
                fcActive.querySelector('.value').textContent = 'Active ✅';
                fcActive.style.background = '#fff3cd';
                fcActive.style.borderColor = '#ffc107';
                fcActive.querySelector('.value').style.color = '#856404';

                fcNone.querySelector('.value').textContent = 'Inactive';
                fcNone.style.background = '#e9ecef';
                fcNone.style.borderColor = '#6c757d';
                fcNone.querySelector('.value').style.color = '#6c757d';

                indicator.textContent = '♿ Forced Colors Active';
                indicator.style.background = '#ffc107';
                indicator.style.color = '#333';
            } else {
                fcActive.querySelector('.value').textContent = 'Not active';
                fcActive.style.background = '#e9ecef';
                fcActive.style.borderColor = '#6c757d';
                fcActive.querySelector('.value').style.color = '#6c757d';

                fcNone.querySelector('.value').textContent = 'Active (default) ✅';
                fcNone.style.background = '#d4edda';
                fcNone.style.borderColor = '#28a745';
                fcNone.querySelector('.value').style.color = '#28a745';

                indicator.textContent = '🎨 Normal Colors';
                indicator.style.background = '#007bff';
                indicator.style.color = 'white';
            }

            // Grid detection
            const grid0 = document.getElementById('grid-0');
            const grid1 = document.getElementById('grid-1');
            const gridValue = document.getElementById('grid-value');

            if (window.matchMedia('(grid: 0)').matches) {
                grid0.querySelector('.value').textContent = 'Bitmap ✅';
                grid0.style.background = '#cce5ff';
                grid0.style.borderColor = '#007bff';
                grid0.querySelector('.value').style.color = '#007bff';

                grid1.querySelector('.value').textContent = 'Not grid-based';
                grid1.style.background = '#e9ecef';
                grid1.style.borderColor = '#6c757d';
                grid1.querySelector('.value').style.color = '#6c757d';

                if (gridValue) gridValue.textContent = '🖥️ Bitmap-based screen (modern device)';
            } else if (window.matchMedia('(grid: 1)').matches) {
                grid1.querySelector('.value').textContent = 'Grid-based ✅';
                grid1.style.background = '#fff3cd';
                grid1.style.borderColor = '#ffc107';
                grid1.querySelector('.value').style.color = '#856404';

                grid0.querySelector('.value').textContent = 'Not bitmap';
                grid0.style.background = '#e9ecef';
                grid0.style.borderColor = '#6c757d';
                grid0.querySelector('.value').style.color = '#6c757d';

                if (gridValue) gridValue.textContent = '📟 Grid-based screen (text-only terminal)';
            }
        }

        window.addEventListener('load', updateIndicators);

        // Listen for forced colors changes
        window.matchMedia('(forced-colors: active)').addEventListener('change', updateIndicators);

        updateIndicators();
    </script>

</body>
</html>

Quick Reference

FeatureDescriptionValues
forced-colorsDetects forced colors modenone, active
gridDetects grid-based screens0, 1

forced-colors Values

ValueDescription
noneForced colors mode is not active (default)
activeForced colors mode is active

Properties Forced in Forced Colors Mode

PropertyForced To
box-shadownone
text-shadownone
background-imagenone
color-schemelight dark
scrollbar-colorauto

Common System Colors

System ColorDescription
CanvasBackground of the document
CanvasTextText color
LinkTextLink color
ButtonFaceButton background
ButtonTextButton text
ButtonBorderButton border
HighlightSelected item background
HighlightTextSelected item text
GrayTextDisabled text
FieldInput field background
FieldTextInput field text

grid Values

ValueDescriptionExamples
0Bitmap-based screen (modern)Computers, smartphones, tablets
1Grid-based screen (character-based)Text-only terminals, braille displays

Best Practices

Do This:

/* Support forced colors mode */
@media (forced-colors: active) {
    button {
        border: 1px solid ButtonBorder;
        background: ButtonFace;
        color: ButtonText;
    }
    button:hover {
        background: Highlight;
        color: HighlightText;
    }
}

/* Use system colors for accessibility */
.card {
    background: Canvas;
    color: CanvasText;
    border: 1px solid CanvasText;
}

/* Optimize for grid-based devices */
@media (grid: 1) {
    .text {
        color: black;
    }
}

Don’t Do This:

/* Don't rely on shadows for boundaries */
.card {
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
    /* Shadow disappears in forced colors mode! */
}

/* Don't rely on background colors alone */
.error {
    background: #ff0000; /* May not be visible in high contrast */
}

/* Don't ignore forced colors mode */
/* Test with Windows High Contrast mode! */

Pro Tip: forced-colors is essential for accessibility. Millions of users rely on high-contrast modes due to visual impairments. Always test your site with Windows High Contrast mode or similar features. Use system colors (ButtonFace, CanvasText, etc.) and add borders to elements that rely on background colors for boundaries. grid is a legacy feature — modern devices almost always match grid: 0, but it’s good to know for extreme


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!