|

CSS 40 ๐Ÿ’ป pointer and resolution media features

These two media features let you adapt styles based on the accuracy of the pointing device and the pixel density of the display โ€” essential for touch-friendly interfaces and high-DPI screens.


Overview of Features

FeatureDescriptionValues
pointerAccuracy of the primary pointing devicenone, coarse, fine
resolutionPixel density of the output devicedpi, dpcm, dppx

1. pointer

The pointer media feature queries the accuracy of the primary pointing device โ€” such as a mouse, touchpad, or touchscreen.

@media (pointer: fine) {
    .container {
        padding: 20px;
        border: 1px solid #add8e6;
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    }
}

Values

ValueDescriptionDevice Example
noneNo pointing device availableKeyboard-only device, TV remote
coarsePointing device with limited accuracyFinger on touchscreen, stylus
finePointing device with fine accuracyMouse, trackpad, precision stylus

Real-World Examples

Devicepointer Value
Desktop with mousefine
Laptop with trackpadfine
Smartphone (touch)coarse
Tablet (touch)coarse
Smart TV (remote)none or coarse
Gaming console (controller)none or coarse

pointer vs any-pointer

FeatureDescription
pointerPrimary pointing device’s accuracy
any-pointerBest accuracy among all pointing devices

Example:

  • Laptop with touchscreen and mouse:
    • pointer: fine (primary is mouse)
    • any-pointer: fine (at least one fine pointer)
  • Tablet with Bluetooth mouse:
    • pointer: coarse (primary is touch)
    • any-pointer: fine (mouse is fine)

2. resolution

The resolution media feature queries the pixel density of the output device.

@media (resolution: 150dpi) {
    .container {
        padding: 10px;
        border: 1px solid red;
    }
}

Values

UnitDescriptionExample
dpiDots per inch150dpi
dpcmDots per centimeter60dpcm
dppxDots per pixel unit (1dppx = 96dpi)2dppx

Variations

FeatureDescriptionExample
resolutionExact resolution@media (resolution: 150dpi)
min-resolutionMinimum resolution@media (min-resolution: 2dppx)
max-resolutionMaximum resolution@media (max-resolution: 72dpi)

Common Resolutions

DeviceResolutiondppx Equivalent
Older monitors72โ€“96 dpi0.75โ€“1 dppx
Standard laptops96โ€“120 dpi1โ€“1.25 dppx
Retina displays192โ€“220 dpi2โ€“2.3 dppx
High-end smartphones400โ€“500 dpi4โ€“5 dppx
4K monitors150โ€“200 dpi1.5โ€“2 dppx

Unit Conversions

1 dppx = 96 dpi
1 dpi = 1/96 dppx
1 dpcm = 2.54 dpi

Complete Example

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

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            padding: 20px;
            background: #f8f9fa;
            color: #333;
            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: 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 #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;
        }

        /* ====== POINTER DEMO ====== */
        .container {
            padding: 20px;
            border: 1px solid #ddd;
            border-radius: 8px;
            margin: 15px 0;
            transition: all 0.3s;
            text-align: center;
            font-weight: bold;
            font-size: 1.1rem;
            background: #f8f9fa;
        }

        /* Fine pointer (mouse) */
        @media (pointer: fine) {
            .container {
                padding: 20px;
                border: 2px solid #add8e6;
                box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
                background: #e3f2fd;
            }
            .container::after {
                content: " ๐Ÿ–ฑ๏ธ Fine pointer (mouse)";
                font-weight: normal;
                font-size: 0.85rem;
                color: #007bff;
            }
        }

        /* Coarse pointer (touch) */
        @media (pointer: coarse) {
            .container {
                padding: 10px;
                border: 2px solid #98fb98;
                box-shadow: none;
                background: #e8f5e9;
            }
            .container::after {
                content: " ๐Ÿ‘† Coarse pointer (touch)";
                font-weight: normal;
                font-size: 0.85rem;
                color: #28a745;
            }
        }

        /* No pointer */
        @media (pointer: none) {
            .container {
                padding: 15px;
                border: 2px dashed #dc3545;
                background: #f8d7da;
            }
            .container::after {
                content: " โŒจ๏ธ No pointing device";
                font-weight: normal;
                font-size: 0.85rem;
                color: #dc3545;
            }
        }

        /* ====== TOUCH-FRIENDLY BUTTONS ====== */
        .btn-group {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
            margin: 15px 0;
        }

        .btn {
            padding: 12px 24px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 8px;
            font-size: 1em;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.3s;
        }

        /* Larger buttons for touch */
        @media (pointer: coarse) {
            .btn {
                padding: 16px 32px;
                font-size: 1.1em;
                min-height: 48px;
                min-width: 120px;
            }
        }

        /* Smaller buttons for mouse */
        @media (pointer: fine) {
            .btn {
                padding: 10px 20px;
                font-size: 0.95em;
            }
            .btn:hover {
                background: #0056b3;
                transform: translateY(-2px);
            }
        }

        /* ====== RESOLUTION DEMO ====== */
        .resolution-demo {
            padding: 20px;
            border-radius: 8px;
            margin: 15px 0;
            text-align: center;
            font-weight: bold;
            font-size: 1.1rem;
            transition: all 0.3s;
            background: #e9ecef;
            border: 2px solid #ddd;
        }

        /* Low resolution (โ‰ค 72dpi) */
        @media (max-resolution: 72dpi) {
            .resolution-demo {
                background: #ff6b6b;
                color: white;
                border-color: #c92a2a;
            }
            .resolution-demo::after {
                content: " (low resolution โ‰ค 72dpi)";
                font-weight: normal;
                font-size: 0.85rem;
            }
        }

        /* Medium resolution (72โ€“150dpi) */
        @media (min-resolution: 72dpi) and (max-resolution: 192dpi) {
            .resolution-demo {
                background: #ffc107;
                color: #333;
                border-color: #d39e00;
            }
            .resolution-demo::after {
                content: " (medium resolution 72โ€“192dpi)";
                font-weight: normal;
                font-size: 0.85rem;
            }
        }

        /* High resolution (โ‰ฅ 2dppx / 192dpi) */
        @media (min-resolution: 2dppx) {
            .resolution-demo {
                background: #28a745;
                color: white;
                border-color: #1e7e34;
            }
            .resolution-demo::after {
                content: " (high resolution โ‰ฅ 2dppx)";
                font-weight: normal;
                font-size: 0.85rem;
            }
        }

        /* ====== HDPI IMAGE DEMO ====== */
        .hdpi-demo {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            align-items: center;
            margin: 15px 0;
        }

        .hdpi-demo .image-box {
            width: 200px;
            height: 150px;
            border-radius: 8px;
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-weight: bold;
            font-size: 1rem;
            text-align: center;
            padding: 20px;
            /* Standard resolution image */
            background: linear-gradient(135deg, #007bff, #6c5ce7);
            transition: all 0.3s;
        }

        /* Sharper image for high-DPI displays */
        @media (min-resolution: 2dppx) {
            .hdpi-demo .image-box {
                background: linear-gradient(135deg, #007bff, #6c5ce7);
                box-shadow: 0 0 0 2px #28a745, 0 4px 20px rgba(40, 167, 69, 0.3);
            }
            .hdpi-demo .image-box::after {
                content: " (HDPI enhanced)";
                font-weight: normal;
                font-size: 0.8rem;
            }
        }

        /* ====== BORDER WIDTH ADJUSTMENT ====== */
        .border-demo {
            padding: 20px;
            margin: 15px 0;
            border-radius: 8px;
            background: #f8f9fa;
            text-align: center;
            transition: all 0.3s;
            /* Default border */
            border: 1px solid #007bff;
        }

        /* Thinner borders on high-DPI (1px looks thicker) */
        @media (min-resolution: 2dppx) {
            .border-demo {
                border-width: 0.5px;
            }
        }

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

        /* ====== 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;
            display: flex;
            flex-direction: column;
            gap: 3px;
        }

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

        /* ====== PRACTICAL: TOUCH-FRIENDLY FORM ====== */
        .form-group {
            margin-bottom: 15px;
        }

        .form-group label {
            display: block;
            font-weight: bold;
            margin-bottom: 5px;
            color: #333;
        }

        .form-group input,
        .form-group select {
            width: 100%;
            padding: 10px;
            border: 2px solid #ddd;
            border-radius: 8px;
            font-size: 1em;
            transition: all 0.3s;
        }

        .form-group input:focus,
        .form-group select:focus {
            border-color: #007bff;
            outline: none;
            box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.15);
        }

        /* Larger touch targets for coarse pointers */
        @media (pointer: coarse) {
            .form-group input,
            .form-group select {
                padding: 16px;
                font-size: 1.1em;
                min-height: 48px;
            }
            .form-group label {
                font-size: 1.05em;
            }
        }
    </style>
</head>
<body>

    <h1>pointer and resolution Media Features</h1>

    <!-- ====== 1. POINTER DEMO ====== -->
    <section>
        <h2>1. pointer</h2>
        <p>Queries the <strong>accuracy of the primary pointing device</strong>.</p>

        <div class="container">
            Pointer Detection
        </div>

        <p class="note">On desktop with a mouse: fine. On mobile with touch: coarse. On keyboard-only: none.</p>

        <div class="code-block">
            /* Fine pointer (mouse, trackpad) */
            @media (pointer: fine) {
                .container {
                    padding: 20px;
                    border: 2px solid #add8e6;
                    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
                }
            }

            /* Coarse pointer (touch) */
            @media (pointer: coarse) {
                .container {
                    padding: 10px;
                    border: 2px solid #98fb98;
                    box-shadow: none;
                }
            }

            /* No pointer */
            @media (pointer: none) {
                .container {
                    border: 2px dashed #dc3545;
                }
            }
        </div>
    </section>

    <!-- ====== 2. TOUCH-FRIENDLY BUTTONS ====== -->
    <section>
        <h2>2. Touch-Friendly Buttons</h2>
        <p>Buttons adapt their size based on pointer accuracy.</p>

        <div class="btn-group">
            <button class="btn">Primary</button>
            <button class="btn">Secondary</button>
            <button class="btn">Tertiary</button>
        </div>

        <p class="note">On touch devices, buttons have larger touch targets (48px minimum).</p>

        <div class="code-block">
            /* Smaller buttons for mouse */
            @media (pointer: fine) {
                .btn {
                    padding: 10px 20px;
                }
                .btn:hover {
                    transform: translateY(-2px);
                }
            }

            /* Larger buttons for touch */
            @media (pointer: coarse) {
                .btn {
                    padding: 16px 32px;
                    min-height: 48px;
                    min-width: 120px;
                }
            }
        </div>
    </section>

    <!-- ====== 3. RESOLUTION DEMO ====== -->
    <section>
        <h2>3. resolution</h2>
        <p>Queries the <strong>pixel density</strong> of the output device.</p>

        <div class="resolution-demo">
            Resolution Detection
        </div>

        <div class="code-block">
            /* Low resolution */
            @media (max-resolution: 72dpi) {
                .demo { background: #ff6b6b; }
            }

            /* Medium resolution */
            @media (min-resolution: 72dpi) and (max-resolution: 192dpi) {
                .demo { background: #ffc107; }
            }

            /* High resolution */
            @media (min-resolution: 2dppx) {
                .demo { background: #28a745; }
            }
        </div>
    </section>

    <!-- ====== 4. HDPI IMAGE ENHANCEMENT ====== -->
    <section>
        <h2>4. HDPI Image Enhancement</h2>
        <p>Images can be enhanced on high-resolution displays.</p>

        <div class="hdpi-demo">
            <div class="image-box">๐Ÿ–ผ๏ธ HDPI Image</div>
            <p>On high-DPI displays (โ‰ฅ 2dppx), this image gets a sharper border and enhanced shadow.</p>
        </div>

        <div class="code-block">
            /* Sharper image for high-DPI displays */
            @media (min-resolution: 2dppx) {
                .image-box {
                    box-shadow: 0 0 0 2px #28a745, 0 4px 20px rgba(40, 167, 69, 0.3);
                }
            }
        </div>
    </section>

    <!-- ====== 5. BORDER WIDTH ADJUSTMENT ====== -->
    <section>
        <h2>5. Border Width Adjustment</h2>
        <p>Thin borders look thicker on high-DPI displays. This border adjusts accordingly.</p>

        <div class="border-demo">
            This border is 1px on standard displays and 0.5px on high-DPI displays.
        </div>

        <div class="code-block">
            /* Thinner borders on high-DPI */
            @media (min-resolution: 2dppx) {
                .border-demo {
                    border-width: 0.5px;
                }
            }
        </div>
    </section>

    <!-- ====== 6. PRACTICAL: TOUCH-FRIENDLY FORM ====== -->
    <section>
        <h2>6. Practical Example: Touch-Friendly Form</h2>
        <p>Form inputs adapt their size based on pointer accuracy.</p>

        <div class="form-group">
            <label for="name">Name:</label>
            <input type="text" id="name" placeholder="Enter your name">
        </div>

        <div class="form-group">
            <label for="email">Email:</label>
            <input type="email" id="email" placeholder="your@email.com">
        </div>

        <div class="form-group">
            <label for="country">Country:</label>
            <select id="country">
                <option value="">Select a country</option>
                <option value="us">United States</option>
                <option value="uk">United Kingdom</option>
                <option value="ca">Canada</option>
            </select>
        </div>

        <div class="code-block">
            /* Larger touch targets for coarse pointers */
            @media (pointer: coarse) {
                .form-group input,
                .form-group select {
                    padding: 16px;
                    font-size: 1.1em;
                    min-height: 48px;
                }
            }
        </div>
    </section>

    <!-- ====== 7. DETECTION SUMMARY ====== -->
    <section>
        <h2>7. 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="pointer-fine">
                <span class="label">pointer: fine</span>
                <span class="value" id="pointer-fine-value">Detecting...</span>
            </div>
            <div class="detection-card" id="pointer-coarse">
                <span class="label">pointer: coarse</span>
                <span class="value" id="pointer-coarse-value">Detecting...</span>
            </div>
            <div class="detection-card" id="pointer-none">
                <span class="label">pointer: none</span>
                <span class="value" id="pointer-none-value">Detecting...</span>
            </div>
            <div class="detection-card" id="any-pointer-fine">
                <span class="label">any-pointer: fine</span>
                <span class="value" id="any-pointer-fine-value">Detecting...</span>
            </div>
            <div class="detection-card" id="res-low">
                <span class="label">max-resolution: 72dpi</span>
                <span class="value" id="res-low-value">Detecting...</span>
            </div>
            <div class="detection-card" id="res-high">
                <span class="label">min-resolution: 2dppx</span>
                <span class="value" id="res-high-value">Detecting...</span>
            </div>
        </div>

        <div class="code-block">
            /* Detect pointer accuracy */
            @media (pointer: fine) { /* Mouse, trackpad */ }
            @media (pointer: coarse) { /* Touch */ }
            @media (pointer: none) { /* No pointer */ }

            /* Detect resolution */
            @media (max-resolution: 72dpi) { /* Low resolution */ }
            @media (min-resolution: 2dppx) { /* High resolution */ }
        </div>
    </section>

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

        <h3>pointer Values</h3>
        <table class="reference-table">
            <tr>
                <th>Value</th>
                <th>Description</th>
                <th>Device Example</th>
            </tr>
            <tr>
                <td><code>none</code></td>
                <td>No pointing device</td>
                <td>Keyboard-only, TV remote</td>
            </tr>
            <tr>
                <td><code>coarse</code></td>
                <td>Limited accuracy</td>
                <td>Finger on touchscreen, stylus</td>
            </tr>
            <tr>
                <td><code>fine</code></td>
                <td>Fine accuracy</td>
                <td>Mouse, trackpad, precision stylus</td>
            </tr>
        </table>

        <h3>pointer vs any-pointer</h3>
        <table class="reference-table">
            <tr>
                <th>Feature</th>
                <th>Description</th>
            </tr>
            <tr>
                <td><code>pointer</code></td>
                <td>Primary pointing device's accuracy</td>
            </tr>
            <tr>
                <td><code>any-pointer</code></td>
                <td>Best accuracy among all pointing devices</td>
            </tr>
        </table>

        <h3>resolution Units</h3>
        <table class="reference-table">
            <tr>
                <th>Unit</th>
                <th>Description</th>
                <th>Example</th>
            </tr>
            <tr>
                <td><code>dpi</code></td>
                <td>Dots per inch</td>
                <td><code>150dpi</code></td>
            </tr>
            <tr>
                <td><code>dpcm</code></td>
                <td>Dots per centimeter</td>
                <td><code>60dpcm</code></td>
            </tr>
            <tr>
                <td><code>dppx</code></td>
                <td>Dots per pixel unit (1dppx = 96dpi)</td>
                <td><code>2dppx</code></td>
            </tr>
        </table>

        <h3>Common Resolutions</h3>
        <table class="reference-table">
            <tr>
                <th>Device</th>
                <th>Resolution</th>
                <th>dppx</th>
            </tr>
            <tr>
                <td>Older monitors</td>
                <td>72โ€“96 dpi</td>
                <td>0.75โ€“1</td>
            </tr>
            <tr>
                <td>Standard laptops</td>
                <td>96โ€“120 dpi</td>
                <td>1โ€“1.25</td>
            </tr>
            <tr>
                <td>Retina displays</td>
                <td>192โ€“220 dpi</td>
                <td>2โ€“2.3</td>
            </tr>
            <tr>
                <td>High-end smartphones</td>
                <td>400โ€“500 dpi</td>
                <td>4โ€“5</td>
            </tr>
            <tr>
                <td>4K monitors</td>
                <td>150โ€“200 dpi</td>
                <td>1.5โ€“2</td>
            </tr>
        </table>
    </section>

    <!-- ====== 9. BEST PRACTICES ====== -->
    <section>
        <h2>9. 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>pointer: coarse</code> to create larger touch targets (48px minimum)</li>
                <li>Use <code>pointer: fine</code> for hover effects and smaller UI elements</li>
                <li>Use <code>resolution</code> to serve higher-quality images on high-DPI displays</li>
                <li>Adjust border widths for high-DPI displays (0.5px looks like 1px)</li>
                <li>Test on both touch and mouse devices</li>
                <li>Use <code>min-resolution: 2dppx</code> for Retina/HDPI optimizations</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 pointer type โ€” some devices have both</li>
                <li>Don't use tiny touch targets on touch devices</li>
                <li>Don't serve large images to low-resolution displays</li>
                <li>Don't assume all high-DPI displays are mobile</li>
                <li>Don't forget that <code>pointer</code> checks the primary device only</li>
                <li>Don't use <code>resolution</code> for critical functionality</li>
            </ul>
        </div>
    </section>

    <!-- ====== LIVE INDICATOR ====== -->
    <div class="live-indicator" id="live-indicator">
        <span id="indicator-pointer">Pointer: โ€”</span>
        <span class="detail" id="indicator-resolution">Resolution: โ€”</span>
    </div>

    <!-- ====== SCRIPT FOR DETECTION ====== -->
    <script>
        function updateIndicators() {
            // Pointer detection
            const pointerFine = document.getElementById('pointer-fine');
            const pointerCoarse = document.getElementById('pointer-coarse');
            const pointerNone = document.getElementById('pointer-none');
            const anyPointerFine = document.getElementById('any-pointer-fine');

            const isFine = window.matchMedia('(pointer: fine)').matches;
            const isCoarse = window.matchMedia('(pointer: coarse)').matches;
            const isNone = window.matchMedia('(pointer: none)').matches;
            const isAnyFine = window.matchMedia('(any-pointer: fine)').matches;

            function setCard(card, isActive, activeText, inactiveText) {
                const value = card.querySelector('.value');
                if (isActive) {
                    value.textContent = activeText;
                    card.style.background = '#d4edda';
                    card.style.borderColor = '#28a745';
                    value.style.color = '#28a745';
                } else {
                    value.textContent = inactiveText;
                    card.style.background = '#e9ecef';
                    card.style.borderColor = '#6c757d';
                    value.style.color = '#6c757d';
                }
            }

            setCard(pointerFine, isFine, 'Active โœ…', 'Not active');
            setCard(pointerCoarse, isCoarse, 'Active โœ…', 'Not active');
            setCard(pointerNone, isNone, 'Active โœ…', 'Not active');
            setCard(anyPointerFine, isAnyFine, 'Active โœ…', 'Not active');

            // Resolution detection
            const resLow = document.getElementById('res-low');
            const resHigh = document.getElementById('res-high');

            const isLowRes = window.matchMedia('(max-resolution: 72dpi)').matches;
            const isHighRes = window.matchMedia('(min-resolution: 2dppx)').matches;

            setCard(resLow, isLowRes, 'Low Res โœ…', 'Not low res');
            setCard(resHigh, isHighRes, 'High DPI โœ…', 'Not high DPI');

            // Live indicator
            const indicatorPointer = document.getElementById('indicator-pointer');
            const indicatorResolution = document.getElementById('indicator-resolution');
            const indicator = document.getElementById('live-indicator');

            let pointerText = '';
            if (isFine) pointerText = '๐Ÿ–ฑ๏ธ Fine (Mouse)';
            else if (isCoarse) pointerText = '๐Ÿ‘† Coarse (Touch)';
            else if (isNone) pointerText = 'โŒจ๏ธ None';
            else pointerText = 'โ“ Unknown';

            indicatorPointer.textContent = 'Pointer: ' + pointerText;

            // Resolution display
            const dpr = window.devicePixelRatio || 1;
            const dpi = Math.round(dpr * 96);
            let resText = dpr + 'x (' + dpi + 'dpi)';
            if (isHighRes) resText += ' โ€” HDPI';
            indicatorResolution.textContent = 'Resolution: ' + resText;

            // Color the indicator
            if (isFine) {
                indicator.style.background = '#007bff';
                indicator.style.color = 'white';
            } else if (isCoarse) {
                indicator.style.background = '#28a745';
                indicator.style.color = 'white';
            } else {
                indicator.style.background = '#dc3545';
                indicator.style.color = 'white';
            }

            if (isHighRes) {
                indicator.style.boxShadow = '0 4px 15px rgba(40, 167, 69, 0.5)';
            }
        }

        window.addEventListener('load', updateIndicators);
        window.addEventListener('resize', updateIndicators);

        updateIndicators();
    </script>

</body>
</html>

Quick Reference

FeatureDescriptionValues
pointerPrimary pointing device accuracynone, coarse, fine
resolutionPixel densitydpi, dpcm, dppx

pointer Values

ValueDescriptionDevice Example
noneNo pointing deviceKeyboard-only, TV remote
coarseLimited accuracyFinger on touchscreen
fineFine accuracyMouse, trackpad

resolution Units

UnitDescriptionExample
dpiDots per inch150dpi
dpcmDots per centimeter60dpcm
dppxDots per pixel unit (1dppx = 96dpi)2dppx

Common Resolutions

DeviceResolutiondppx
Older monitors72โ€“96 dpi0.75โ€“1
Standard laptops96โ€“120 dpi1โ€“1.25
Retina displays192โ€“220 dpi2โ€“2.3
High-end smartphones400โ€“500 dpi4โ€“5
4K monitors150โ€“200 dpi1.5โ€“2

Best Practices

โœ… Do This:

/* Larger touch targets for touch devices */
@media (pointer: coarse) {
    .btn {
        padding: 16px 32px;
        min-height: 48px;
        min-width: 120px;
    }
}

/* Hover effects only for mouse */
@media (pointer: fine) {
    .btn:hover {
        transform: translateY(-2px);
    }
}

/* Sharper images for HDPI */
@media (min-resolution: 2dppx) {
    .image {
        background-image: url('image@2x.png');
    }
}

/* Thinner borders on HDPI */
@media (min-resolution: 2dppx) {
    .border {
        border-width: 0.5px;
    }
}

โŒ Don’t Do This:

/* Don't use tiny touch targets */
@media (pointer: coarse) {
    .btn {
        padding: 4px 8px; /* Too small for fingers! */
    }
}

/* Don't assume all high-DPI displays are mobile */
@media (min-resolution: 2dppx) {
    /* This could be a 4K desktop monitor */
}

/* Don't rely on pointer type alone */
@media (pointer: fine) {
    /* Some devices have both mouse and touch */
}

Pro Tip: pointer is essential for touch-friendly design. Use pointer: coarse to create larger touch targets (48px minimum) and pointer: fine for hover effects and precision interactions. resolution is key for high-DPI optimization โ€” serve sharper images on Retina displays, and adjust border widths (0.5px looks like 1px on 2x displays). Remember: pointer checks the primary device, while any-pointer checks all devices. A laptop with both mouse and touchscreen has pointer: fine (mouse is primary) but any-pointer: fine too!


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!