|

CSS 43 💻 prefers-reduced-transparency and scan media features

These two media features address accessibility (transparency preferences) and legacy display technology (interlaced vs progressive scanning).


Overview of Features

FeatureDescriptionValues
prefers-reduced-transparencyUser wants less transparencyno-preference, reduce
scanMonitor’s scanning processinterlaced, progressive

1. prefers-reduced-transparency

The prefers-reduced-transparency media feature detects if the user has requested reduced transparency — important for users who have difficulty reading text over translucent backgrounds.

@media (prefers-reduced-transparency: reduce) {
    body {
        background-color: #ffffff;
    }
}

Values

ValueDescription
no-preferenceUser has not expressed a preference (default)
reduceUser prefers reduced transparency

When to Use

  • Remove backdrop blur effects (backdrop-filter: blur())
  • Replace translucent backgrounds with solid colors
  • Remove opacity from overlays and modals
  • Simplify glassmorphism effects
  • Increase contrast for better readability

How Users Enable It

  • iOS: Settings → Accessibility → Motion → Reduce Transparency
  • macOS: System Preferences → Accessibility → Display → Reduce transparency
  • Windows: Settings → Personalization → Colors → Transparency effects (off)

⚠️ Important Note

prefers-reduced-transparency is a relatively new feature with limited browser support. Always provide a working fallback.


2. scan

The scan media feature detects the scanning process of the display — how the image is drawn on screen.

@media (scan: interlaced) {
    body {
        background-color: #f0f;
        color: #0ff;
    }
}

Values

ValueDescription
interlacedImage drawn in alternating lines (old CRT monitors)
progressiveEach frame is complete (modern displays)

Interlaced vs Progressive

Interlaced:              Progressive:
Frame 1:                 Frame 1:
┌─────────────┐          ┌─────────────┐
│ ███████████ │          │ ███████████ │
│             │          │ ███████████ │
│ ███████████ │          │ ███████████ │
│             │          │ ███████████ │
│ ███████████ │          │ ███████████ │
└─────────────┘          └─────────────┘
Odd lines first,         All lines at once
then even lines

Key Points

AspectInterlacedProgressive
TechnologyOld CRT monitorsModern LCD, OLED
RenderingAlternating linesComplete frames
MotionCan flicker with fast movementSmooth
Thin linesMay flicker (< 1px)No flicker
Current useRare (legacy)Universal

Design Considerations for Interlaced

  • Avoid thin lines (less than 1px) — they can flicker
  • Avoid fast movement — causes visible flicker
  • Use wider strokes for text and graphics
  • Reduce animation speed
  • Most modern developers will never encounter interlaced displays

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-reduced-transparency and scan</title>
    <style>
        *, *::before, *::after {
            box-sizing: border-box;
        }

        :root {
            --bg-primary: #ffffff;
            --bg-secondary: #f8f9fa;
            --bg-tertiary: #e9ecef;
            --text-primary: #212529;
            --text-secondary: #6c757d;
            --accent: #007bff;
            --border: #dee2e6;
            --shadow: rgba(0, 0, 0, 0.1);
        }

        @media (prefers-color-scheme: dark) {
            :root {
                --bg-primary: #1a1a1a;
                --bg-secondary: #0d0d0d;
                --bg-tertiary: #2d2d2d;
                --text-primary: #f8f9fa;
                --text-secondary: #adb5bd;
                --accent: #4dabf7;
                --border: #444;
                --shadow: rgba(0, 0, 0, 0.5);
            }
        }

        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: #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 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;
        }

        /* ====== TRANSPARENCY DEMO ====== */
        .transparency-demo {
            position: relative;
            padding: 40px 20px;
            border-radius: 12px;
            overflow: hidden;
            margin: 15px 0;
            min-height: 200px;
            display: flex;
            align-items: center;
            justify-content: center;
            /* Background image for transparency effect */
            background-image: linear-gradient(135deg, #007bff, #6c5ce7, #dc3545);
            background-size: cover;
        }

        .glass-card {
            background: rgba(255, 255, 255, 0.15);
            backdrop-filter: blur(10px);
            -webkit-backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.3);
            border-radius: 16px;
            padding: 30px;
            text-align: center;
            color: white;
            font-weight: bold;
            max-width: 400px;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
            transition: all 0.3s;
        }

        .glass-card h3 {
            margin-top: 0;
            color: white;
            text-shadow: 0 2px 10px rgba(0,0,0,0.3);
        }

        .glass-card p {
            margin-bottom: 0;
            font-size: 0.95rem;
            opacity: 0.95;
        }

        /* Reduced transparency: solid background */
        @media (prefers-reduced-transparency: reduce) {
            .glass-card {
                background: var(--bg-primary);
                backdrop-filter: none;
                -webkit-backdrop-filter: none;
                border: 2px solid var(--border);
                color: var(--text-primary);
                box-shadow: 0 4px 15px var(--shadow);
            }
            .glass-card h3 {
                color: var(--text-primary);
                text-shadow: none;
            }
            .glass-card p {
                color: var(--text-secondary);
            }
            .glass-card::after {
                content: " (reduced transparency)";
                display: block;
                font-size: 0.75rem;
                margin-top: 10px;
                color: var(--text-secondary);
                font-weight: normal;
            }
        }

        /* ====== TRANSPARENCY COMPARISON ====== */
        .transparency-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 20px;
            margin: 15px 0;
        }

        .transparency-box {
            padding: 25px;
            border-radius: 12px;
            text-align: center;
            font-weight: bold;
            color: white;
            min-height: 150px;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            /* Colorful background behind */
            background-image: linear-gradient(135deg, #ff6b6b, #ffc107, #28a745, #007bff, #6c5ce7);
            background-size: cover;
        }

        .transparency-box .inner {
            padding: 15px 25px;
            border-radius: 8px;
            width: 100%;
        }

        /* Transparent versions */
        .transparent-high {
            background: rgba(255, 255, 255, 0.2);
            backdrop-filter: blur(8px);
            -webkit-backdrop-filter: blur(8px);
            border: 1px solid rgba(255, 255, 255, 0.3);
        }

        .transparent-medium {
            background: rgba(255, 255, 255, 0.5);
            backdrop-filter: blur(5px);
            -webkit-backdrop-filter: blur(5px);
            border: 1px solid rgba(255, 255, 255, 0.5);
            color: #333;
        }

        .transparent-low {
            background: rgba(255, 255, 255, 0.9);
            color: #333;
            border: 1px solid rgba(0, 0, 0, 0.1);
        }

        /* Reduced transparency: all solid */
        @media (prefers-reduced-transparency: reduce) {
            .transparent-high,
            .transparent-medium,
            .transparent-low {
                background: var(--bg-primary);
                backdrop-filter: none;
                -webkit-backdrop-filter: none;
                border: 2px solid var(--border);
                color: var(--text-primary);
            }
        }

        /* ====== SCAN DEMO ====== */
        .scan-demo {
            padding: 25px;
            border-radius: 8px;
            margin: 15px 0;
            text-align: center;
            font-weight: bold;
            font-size: 1.1rem;
            transition: all 0.3s;
            background: var(--bg-tertiary);
            border: 2px solid var(--border);
        }

        /* Progressive scan (modern displays) */
        @media (scan: progressive) {
            .scan-demo {
                background: #cce5ff;
                color: #004085;
                border-color: #007bff;
            }
            .scan-demo::after {
                content: " (progressive scan — modern display)";
                font-weight: normal;
                font-size: 0.85rem;
            }
        }

        /* Interlaced scan (old CRT monitors) */
        @media (scan: interlaced) {
            .scan-demo {
                background: #f0f;
                color: #0ff;
                border-color: #f0f;
                /* Avoid thin lines and fast movement */
                font-weight: bold;
            }
            .scan-demo::after {
                content: " (interlaced scan — legacy display)";
                font-weight: normal;
                font-size: 0.85rem;
            }
            /* Wider strokes for interlaced */
            .scan-demo {
                border-width: 3px;
            }
        }

        /* ====== INTERLACED DESIGN CONSIDERATIONS ====== */
        .line-demo {
            display: flex;
            flex-direction: column;
            gap: 10px;
            margin: 15px 0;
        }

        .line-demo .thin-line {
            height: 1px;
            background: var(--text-primary);
            width: 100%;
        }

        .line-demo .thick-line {
            height: 4px;
            background: var(--accent);
            width: 100%;
        }

        .line-demo .text-sample {
            font-size: 16px;
            font-weight: 300;
            letter-spacing: 0.5px;
        }

        .line-demo .bold-sample {
            font-size: 16px;
            font-weight: 700;
            letter-spacing: 0.5px;
        }

        /* Interlaced: avoid thin lines and light fonts */
        @media (scan: interlaced) {
            .line-demo .thin-line {
                height: 3px;
            }
            .line-demo .text-sample {
                font-weight: 500;
                font-size: 18px;
            }
            .line-demo .bold-sample {
                font-weight: 900;
            }
        }

        /* ====== 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;
        }

        /* ====== 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; }

        /* ====== PRACTICAL: ACCESSIBLE MODAL ====== */
        .modal-demo {
            position: relative;
            padding: 40px 20px;
            border-radius: 12px;
            background-image: linear-gradient(135deg, #007bff, #6c5ce7);
            min-height: 250px;
            display: flex;
            align-items: center;
            justify-content: center;
            margin: 15px 0;
        }

        .modal-content {
            background: rgba(255, 255, 255, 0.95);
            border-radius: 12px;
            padding: 30px;
            max-width: 400px;
            text-align: center;
            color: #333;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
            transition: all 0.3s;
        }

        .modal-content h3 {
            margin-top: 0;
            color: #007bff;
        }

        /* Reduced transparency: solid modal */
        @media (prefers-reduced-transparency: reduce) {
            .modal-content {
                background: var(--bg-primary);
                color: var(--text-primary);
                border: 2px solid var(--border);
                box-shadow: 0 4px 15px var(--shadow);
            }
            .modal-content h3 {
                color: var(--accent);
            }
        }
    </style>
</head>
<body>

    <h1>prefers-reduced-transparency and scan</h1>

    <!-- ====== 1. TRANSPARENCY DEMO ====== -->
    <section>
        <h2>1. prefers-reduced-transparency</h2>
        <p>Detects if the user prefers <strong>reduced transparency</strong> — important for users who have difficulty reading text over translucent backgrounds.</p>

        <h3>Glassmorphism Card</h3>
        <div class="transparency-demo">
            <div class="glass-card">
                <h3>✨ Glass Card</h3>
                <p>This card uses transparency and backdrop blur. On reduced transparency, it becomes solid with a border.</p>
            </div>
        </div>

        <h3>Transparency Levels Comparison</h3>
        <div class="transparency-grid">
            <div class="transparency-box">
                <div class="inner transparent-high">High Transparency (0.2)</div>
            </div>
            <div class="transparency-box">
                <div class="inner transparent-medium">Medium Transparency (0.5)</div>
            </div>
            <div class="transparency-box">
                <div class="inner transparent-low">Low Transparency (0.9)</div>
            </div>
        </div>

        <div class="code-block">
            /* Default: glassmorphism with transparency */
            .glass-card {
                background: rgba(255, 255, 255, 0.15);
                backdrop-filter: blur(10px);
                border: 1px solid rgba(255, 255, 255, 0.3);
            }

            /* Reduced transparency: solid background */
            @media (prefers-reduced-transparency: reduce) {
                .glass-card {
                    background: var(--bg-primary);
                    backdrop-filter: none;
                    border: 2px solid var(--border);
                }
            }
        </div>

        <div class="tip-box warning">
            <strong>⚠️ Limited Support:</strong>
            <code>prefers-reduced-transparency</code> is a relatively new feature with limited browser support. Always provide a working fallback.
        </div>
    </section>

    <!-- ====== 2. SCAN DEMO ====== -->
    <section>
        <h2>2. scan</h2>
        <p>Detects the <strong>scanning process</strong> of the display — interlaced (old CRT) or progressive (modern).</p>

        <div class="scan-demo">
            Scan Detection
        </div>

        <h3>Interlaced Design Considerations</h3>
        <div class="line-demo">
            <div class="thin-line"></div>
            <div class="text-sample">Light text sample — thin strokes may flicker on interlaced</div>
            <div class="thick-line"></div>
            <div class="bold-sample">Bold text sample — thicker strokes are more stable</div>
        </div>
        <p class="note">On interlaced displays, thin lines and light fonts can flicker. Use thicker strokes and bolder fonts.</p>

        <div class="code-block">
            /* Progressive scan (modern displays) */
            @media (scan: progressive) {
                .demo {
                    /* Normal styles — thin lines and light fonts are fine */
                }
            }

            /* Interlaced scan (old CRT monitors) */
            @media (scan: interlaced) {
                .demo {
                    /* Use thicker lines and bolder fonts */
                    border-width: 3px;
                }
                .thin-line {
                    height: 3px; /* Avoid flicker */
                }
                .light-text {
                    font-weight: 500; /* Bolder than normal */
                }
            }
        </div>

        <div class="tip-box success">
            <strong>✅ Good News:</strong>
            Interlaced displays are extremely rare today. Most developers will never encounter them. The <code>scan</code> feature is primarily for legacy support.
        </div>
    </section>

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

        <div class="detection-grid">
            <div class="detection-card" id="transparency-no-pref">
                <span class="label">prefers-reduced-transparency: no-preference</span>
                <span class="value" id="transparency-no-pref-value">Detecting...</span>
            </div>
            <div class="detection-card" id="transparency-reduce">
                <span class="label">prefers-reduced-transparency: reduce</span>
                <span class="value" id="transparency-reduce-value">Detecting...</span>
            </div>
            <div class="detection-card" id="scan-interlaced">
                <span class="label">scan: interlaced</span>
                <span class="value" id="scan-interlaced-value">Detecting...</span>
            </div>
            <div class="detection-card" id="scan-progressive">
                <span class="label">scan: progressive</span>
                <span class="value" id="scan-progressive-value">Detecting...</span>
            </div>
        </div>

        <div class="code-block">
            /* Detect reduced transparency preference */
            @media (prefers-reduced-transparency: no-preference) { /* Normal */ }
            @media (prefers-reduced-transparency: reduce) { /* Reduced */ }

            /* Detect scan type */
            @media (scan: interlaced) { /* CRT monitor */ }
            @media (scan: progressive) { /* Modern display */ }
        </div>
    </section>

    <!-- ====== 4. PRACTICAL: ACCESSIBLE MODAL ====== -->
    <section>
        <h2>4. Practical Example: Accessible Modal</h2>
        <p>A modal that adapts to transparency preferences.</p>

        <div class="modal-demo">
            <div class="modal-content">
                <h3>📋 Modal Dialog</h3>
                <p>This modal uses a semi-transparent background. On reduced transparency, it becomes fully opaque with a solid border.</p>
            </div>
        </div>

        <div class="code-block">
            /* Default: semi-transparent modal */
            .modal-content {
                background: rgba(255, 255, 255, 0.95);
                box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
            }

            /* Reduced transparency: solid modal */
            @media (prefers-reduced-transparency: reduce) {
                .modal-content {
                    background: var(--bg-primary);
                    border: 2px solid var(--border);
                    box-shadow: 0 4px 15px var(--shadow);
                }
            }
        </div>
    </section>

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

        <h3>prefers-reduced-transparency Values</h3>
        <table class="reference-table">
            <tr>
                <th>Value</th>
                <th>Description</th>
            </tr>
            <tr>
                <td><code>no-preference</code></td>
                <td>User has not expressed a preference (default)</td>
            </tr>
            <tr>
                <td><code>reduce</code></td>
                <td>User prefers reduced transparency</td>
            </tr>
        </table>

        <h3>scan Values</h3>
        <table class="reference-table">
            <tr>
                <th>Value</th>
                <th>Description</th>
                <th>Display Type</th>
            </tr>
            <tr>
                <td><code>interlaced</code></td>
                <td>Image drawn in alternating lines</td>
                <td>Old CRT monitors</td>
            </tr>
            <tr>
                <td><code>progressive</code></td>
                <td>Each frame is complete</td>
                <td>Modern LCD, OLED</td>
            </tr>
        </table>

        <h3>Interlaced vs Progressive</h3>
        <table class="reference-table">
            <tr>
                <th>Aspect</th>
                <th>Interlaced</th>
                <th>Progressive</th>
            </tr>
            <tr>
                <td><strong>Technology</strong></td>
                <td>Old CRT monitors</td>
                <td>Modern displays</td>
            </tr>
            <tr>
                <td><strong>Rendering</strong></td>
                <td>Alternating lines</td>
                <td>Complete frames</td>
            </tr>
            <tr>
                <td><strong>Thin lines</strong></td>
                <td>May flicker (< 1px)</td>
                <td>No flicker</td>
            </tr>
            <tr>
                <td><strong>Fast motion</strong></td>
                <td>Can cause visible flicker</td>
                <td>Smooth</td>
            </tr>
            <tr>
                <td><strong>Current use</strong></td>
                <td>Rare (legacy)</td>
                <td>Universal</td>
            </tr>
        </table>

        <h3>When to Reduce Transparency</h3>
        <table class="reference-table">
            <tr>
                <th>Element</th>
                <th>Default</th>
                <th>Reduced Transparency</th>
            </tr>
            <tr>
                <td>Glassmorphism cards</td>
                <td>Translucent + blur</td>
                <td>Solid + border</td>
            </tr>
            <tr>
                <td>Modals/overlays</td>
                <td>Semi-transparent</td>
                <td>Fully opaque</td>
            </tr>
            <tr>
                <td>Navigation bars</td>
                <td>Translucent</td>
                <td>Solid</td>
            </tr>
            <tr>
                <td>Dropdown menus</td>
                <td>Transparent</td>
                <td>Solid with border</td>
            </tr>
            <tr>
                <td>Tooltips</td>
                <td>Translucent</td>
                <td>Solid</td>
            </tr>
        </table>
    </section>

    <!-- ====== 6. BEST PRACTICES ====== -->
    <section>
        <h2>6. 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>Respect <code>prefers-reduced-transparency: reduce</code> for accessibility</li>
                <li>Replace translucent backgrounds with solid colors</li>
                <li>Remove <code>backdrop-filter: blur()</code> on reduced transparency</li>
                <li>Add borders to maintain visual hierarchy without transparency</li>
                <li>Test with reduced transparency enabled in your OS</li>
                <li>Use <code>scan</code> only for legacy CRT support (rarely needed)</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 transparency for visual design</li>
                <li>Don't ignore reduced transparency — it's an accessibility issue</li>
                <li>Don't use <code>backdrop-filter</code> without a fallback</li>
                <li>Don't use thin lines (less than 1px) for critical UI on interlaced displays</li>
                <li>Don't assume all users can comfortably read text over translucent backgrounds</li>
            </ul>
        </div>
    </section>

    <!-- ====== LIVE INDICATOR ====== -->
    <div class="live-indicator" id="live-indicator">
        <span id="indicator-transparency">Transparency: —</span>
        <span class="detail" id="indicator-scan">Scan: —</span>
    </div>

    <!-- ====== SCRIPT FOR DETECTION ====== -->
    <script>
        function updateIndicators() {
            // Transparency detection
            const transparencyNoPref = document.getElementById('transparency-no-pref');
            const transparencyReduce = document.getElementById('transparency-reduce');

            const isNoPref = window.matchMedia('(prefers-reduced-transparency: no-preference)').matches;
            const isReduce = window.matchMedia('(prefers-reduced-transparency: reduce)').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(transparencyNoPref, isNoPref, 'Active ✅', 'Not active');
            setCard(transparencyReduce, isReduce, 'Active ✅', 'Not active');

            // Scan detection
            const scanInterlaced = document.getElementById('scan-interlaced');
            const scanProgressive = document.getElementById('scan-progressive');

            const isInterlaced = window.matchMedia('(scan: interlaced)').matches;
            const isProgressive = window.matchMedia('(scan: progressive)').matches;

            setCard(scanInterlaced, isInterlaced, 'Active ✅', 'Not active');
            setCard(scanProgressive, isProgressive, 'Active ✅', 'Not active');

            // Live indicator
            const indicatorTransparency = document.getElementById('indicator-transparency');
            const indicatorScan = document.getElementById('indicator-scan');
            const indicator = document.getElementById('live-indicator');

            indicatorTransparency.textContent = isReduce ? 'Transparency: Reduced 🚫' : 'Transparency: Normal ✨';

            let scanText = 'Unknown';
            if (isProgressive) scanText = 'Progressive ✅';
            else if (isInterlaced) scanText = 'Interlaced ⚠️';
            indicatorScan.textContent = 'Scan: ' + scanText;

            // Color the indicator
            if (isReduce || isInterlaced) {
                indicator.style.background = '#28a745';
                indicator.style.color = 'white';
            } else {
                indicator.style.background = '#007bff';
                indicator.style.color = 'white';
            }
        }

        window.addEventListener('load', updateIndicators);

        // Listen for changes
        window.matchMedia('(prefers-reduced-transparency: reduce)').addEventListener('change', updateIndicators);
        window.matchMedia('(scan: interlaced)').addEventListener('change', updateIndicators);

        updateIndicators();
    </script>

</body>
</html>

Quick Reference

FeatureDescriptionValues
prefers-reduced-transparencyUser wants less transparencyno-preference, reduce
scanMonitor’s scanning processinterlaced, progressive

prefers-reduced-transparency Values

ValueDescription
no-preferenceNo preference expressed (default)
reduceUser prefers reduced transparency

scan Values

ValueDescriptionDisplay Type
interlacedAlternating linesOld CRT monitors
progressiveComplete framesModern displays

Interlaced vs Progressive

AspectInterlacedProgressive
TechnologyOld CRTModern LCD/OLED
Thin linesMay flicker (< 1px)No flicker
Fast motionCan flickerSmooth
Current useRareUniversal

Best Practices

Do This:

/* Reduce transparency for accessibility */
@media (prefers-reduced-transparency: reduce) {
    .glass-card {
        background: #ffffff;
        backdrop-filter: none;
        border: 2px solid #ddd;
    }
}

/* Handle interlaced displays (rare) */
@media (scan: interlaced) {
    .thin-line {
        height: 3px; /* Avoid flicker */
    }
    .light-text {
        font-weight: 500;
    }
}

Don’t Do This:

/* Don't rely on transparency for design */
.glass {
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(10px);
    /* No fallback for reduced transparency */
}

/* Don't use thin lines on interlaced displays */
@media (scan: interlaced) {
    .border {
        border-width: 0.5px; /* Will flicker! */
    }
}

Pro Tip: prefers-reduced-transparency is essential for accessibility. Users with visual impairments may struggle to read text over translucent backgrounds. Always provide a solid fallback — replace backdrop-filter: blur() with a solid background and add a border to maintain visual hierarchy. Note that this feature has limited browser support, so test carefully. scan is a legacy feature — interlaced CRT monitors are extremely rare today, so most developers will never need it. If you do encounter it, use thicker lines (3px+) and bolder fonts to prevent flicker!


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!