|

CSS 31 ๐Ÿ’ป any-hover and any-pointer media features

These two media features let you detect the input capabilities of a user’s device โ€” whether they have a mouse that can hover, a touch screen, or both. This is crucial for creating interfaces that work well across all device types.


Overview of Features

FeatureDescriptionValues
any-hoverDetects if any pointing device can hovernone, hover
any-pointerDetects the accuracy of any pointing devicenone, coarse, fine

1. any-hover

The any-hover media feature detects whether any available pointing device can hover over elements.

@media (any-hover: none) {
    .container {
        background-color: lightcoral;
    }
}

Values

ValueDescription
noneNo pointing device can hover
hoverAt least one pointing device can hover

Key Points:

  • Desktop browsers with a mouse โ†’ any-hover: hover
  • Mobile browsers with touch input โ†’ any-hover: none
  • Devices with both mouse and touch โ†’ any-hover: hover (because the mouse can hover)

2. any-pointer

The any-pointer media feature detects the accuracy of any available pointing device.

@media (any-pointer: none) {
    .container {
        background-color: lightcoral;
    }
}

Values

ValueDescription
noneNo pointing device available
coarsePointing device with limited accuracy (e.g., touch, stylus)
finePointing device with fine accuracy (e.g., mouse, trackpad)

Key Points:

  • Desktop with mouse โ†’ any-pointer: fine
  • Mobile with touch โ†’ any-pointer: coarse
  • Devices with both โ†’ any-pointer: fine (because at least one device is fine)

any-hover vs hover

FeatureDescription
hoverDetects the primary pointing device’s hover capability
any-hoverDetects if any pointing device can hover

Example:

  • A laptop with a touchscreen and a mouse:
  • hover: hover (primary device is mouse)
  • any-hover: hover (at least one device can hover)
  • A tablet with a Bluetooth mouse:
  • hover: none (primary device is touch)
  • any-hover: hover (mouse can hover)

any-pointer vs pointer

FeatureDescription
pointerDetects the primary pointing device’s accuracy
any-pointerDetects the best accuracy among all pointing devices

Example:

  • A laptop with a touchscreen and a mouse:
  • pointer: fine (primary device is mouse)
  • any-pointer: fine (at least one device is fine)
  • A tablet with a Bluetooth mouse:
  • pointer: coarse (primary device is touch)
  • any-pointer: fine (mouse is fine)

Complete Example

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

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

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

        .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;
        }

        /* ====== DEMO CONTAINER ====== */
        .container {
            width: 200px;
            height: 200px;
            background-color: lightblue;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            font-size: 18px;
            border-radius: 12px;
            margin: 20px auto;
            cursor: pointer;
            transition: all 0.3s;
            text-align: center;
            padding: 20px;
        }

        .container:hover {
            background-color: lightgreen;
            transform: scale(1.05);
        }

        .container .status {
            font-size: 0.8rem;
            margin-top: 10px;
            font-weight: normal;
        }

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

        .detection-card {
            padding: 15px;
            border-radius: 8px;
            text-align: center;
            font-weight: bold;
            background: #e9ecef;
            border: 2px solid #ddd;
        }

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

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

        /* ====== HOVER CAPABILITY ====== */
        .hover-capable {
            background: #d4edda;
            border-color: #28a745;
            color: #155724;
        }

        .hover-capable .feature-value {
            color: #28a745;
        }

        .hover-not-capable {
            background: #f8d7da;
            border-color: #dc3545;
            color: #721c24;
        }

        .hover-not-capable .feature-value {
            color: #dc3545;
        }

        /* ====== POINTER CAPABILITY ====== */
        .pointer-fine {
            background: #cce5ff;
            border-color: #007bff;
            color: #004085;
        }

        .pointer-fine .feature-value {
            color: #007bff;
        }

        .pointer-coarse {
            background: #fff3cd;
            border-color: #ffc107;
            color: #856404;
        }

        .pointer-coarse .feature-value {
            color: #856404;
        }

        .pointer-none {
            background: #f8d7da;
            border-color: #dc3545;
            color: #721c24;
        }

        .pointer-none .feature-value {
            color: #dc3545;
        }

        /* ====== MEDIA QUERY DEMOS ====== */
        @media (any-hover: none) {
            .container {
                background-color: lightcoral;
            }
            .container:hover {
                background-color: lightcoral;
                transform: none;
            }
            .container .status::after {
                content: " (no hover available)";
                font-style: italic;
            }
        }

        @media (any-hover: hover) {
            .container .status::after {
                content: " (hover available!)";
                font-style: italic;
            }
        }

        @media (any-pointer: none) {
            .pointer-demo {
                background-color: #dc3545;
                color: white;
            }
            .pointer-demo::after {
                content: " โ€” No pointing device detected";
            }
        }

        @media (any-pointer: coarse) {
            .pointer-demo {
                background-color: #ffc107;
                color: #333;
            }
            .pointer-demo::after {
                content: " โ€” Coarse pointer (touch)";
            }
        }

        @media (any-pointer: fine) {
            .pointer-demo {
                background-color: #28a745;
                color: white;
            }
            .pointer-demo::after {
                content: " โ€” Fine pointer (mouse)";
            }
        }

        /* ====== INTERACTIVE DEMO ====== */
        .interactive-demo {
            display: flex;
            flex-wrap: wrap;
            gap: 15px;
            justify-content: center;
            margin: 20px 0;
        }

        .interactive-box {
            width: 150px;
            height: 100px;
            background: #007bff;
            color: white;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 8px;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.3s;
        }

        .interactive-box:hover {
            background: #28a745;
            transform: scale(1.05);
        }

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

        .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);
        }

        /* Hide hover-only elements on touch devices */
        @media (any-hover: none) {
            .hover-only {
                display: none;
            }
        }

        @media (any-hover: hover) {
            .hover-only {
                display: inline;
            }
        }
    </style>
</head>
<body>

    <h1>any-hover and any-pointer Media Features</h1>

    <!-- ====== 1. ANY-HOVER DEMO ====== -->
    <section>
        <h2>1. any-hover</h2>
        <p>Detects whether <strong>any</strong> pointing device can hover over elements.</p>

        <div class="container">
            <strong>Hover over me!</strong>
            <span class="status">Testing any-hover</span>
        </div>

        <p class="note">On desktop, the box turns green on hover. On touch devices with no hover, it stays coral.</p>

        <div class="code-block">
            /* Default state */
            .container {
                background-color: lightblue;
            }

            .container:hover {
                background-color: lightgreen;
            }

            /* No hover capability */
            @media (any-hover: none) {
                .container {
                    background-color: lightcoral;
                }
                .container:hover {
                    background-color: lightcoral; /* Disable hover effect */
                    transform: none;
                }
            }
        </div>
    </section>

    <!-- ====== 2. ANY-POINTER DEMO ====== -->
    <section>
        <h2>2. any-pointer</h2>
        <p>Detects the <strong>accuracy</strong> of any available pointing device.</p>

        <div class="pointer-demo" style="padding: 20px; border-radius: 8px; text-align: center; font-weight: bold; margin: 15px 0;">
            Pointer Detection
        </div>

        <div class="code-block">
            /* No pointing device */
            @media (any-pointer: none) {
                .pointer-demo {
                    background-color: #dc3545;
                    color: white;
                }
            }

            /* Coarse pointer (touch) */
            @media (any-pointer: coarse) {
                .pointer-demo {
                    background-color: #ffc107;
                    color: #333;
                }
            }

            /* Fine pointer (mouse) */
            @media (any-pointer: fine) {
                .pointer-demo {
                    background-color: #28a745;
                    color: white;
                }
            }
        </div>
    </section>

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

        <div class="detection-grid">
            <div class="detection-card" id="any-hover-card">
                <span class="feature-name">any-hover</span>
                <span class="feature-value" id="any-hover-value">Detecting...</span>
            </div>
            <div class="detection-card" id="any-pointer-card">
                <span class="feature-name">any-pointer</span>
                <span class="feature-value" id="any-pointer-value">Detecting...</span>
            </div>
            <div class="detection-card" id="hover-card">
                <span class="feature-name">hover (primary)</span>
                <span class="feature-value" id="hover-value">Detecting...</span>
            </div>
            <div class="detection-card" id="pointer-card">
                <span class="feature-name">pointer (primary)</span>
                <span class="feature-value" id="pointer-value">Detecting...</span>
            </div>
        </div>

        <div class="code-block">
            /* Detect any-hover */
            @media (any-hover: hover) { /* At least one device can hover */ }
            @media (any-hover: none) { /* No device can hover */ }

            /* Detect any-pointer */
            @media (any-pointer: fine) { /* At least one fine pointer */ }
            @media (any-pointer: coarse) { /* At least one coarse pointer */ }
            @media (any-pointer: none) { /* No pointer available */ }
        </div>
    </section>

    <!-- ====== 4. PRACTICAL USE CASE ====== -->
    <section>
        <h2>4. Practical Use Case: Hover-Only Elements</h2>
        <p>Some UI elements only make sense with a mouse. Here's how to handle them.</p>

        <div class="best-practice-card">
            <h3>๐Ÿ“ฑ Touch-Friendly Card</h3>
            <p>
                This card shows a "hover to see more" message
                <span class="hover-only"> โ€” hover over the button to see the effect!</span>
            </p>
            <a href="#" class="btn">Learn More</a>
        </div>

        <p class="note">On touch devices, hover-only elements are hidden or replaced with tap-friendly alternatives.</p>

        <div class="code-block">
            /* Hide hover-only elements on touch devices */
            @media (any-hover: none) {
                .hover-only {
                    display: none;
                }
            }

            @media (any-hover: hover) {
                .hover-only {
                    display: inline;
                }
            }
        </div>
    </section>

    <!-- ====== 5. SIDE-BY-SIDE COMPARISON ====== -->
    <section>
        <h2>5. Side-by-Side Comparison</h2>

        <h3>any-hover vs hover</h3>
        <table class="reference-table">
            <tr>
                <th>Feature</th>
                <th>Description</th>
                <th>Use Case</th>
            </tr>
            <tr>
                <td><code>hover</code></td>
                <td>Primary pointing device can hover</td>
                <td>Optimizing for the main input method</td>
            </tr>
            <tr>
                <td><code>any-hover</code></td>
                <td>At least one pointing device can hover</td>
                <td>Detecting if hover effects are possible at all</td>
            </tr>
        </table>

        <h3>any-pointer vs pointer</h3>
        <table class="reference-table">
            <tr>
                <th>Feature</th>
                <th>Description</th>
                <th>Use Case</th>
            </tr>
            <tr>
                <td><code>pointer</code></td>
                <td>Primary pointing device accuracy</td>
                <td>Optimizing for the main input method</td>
            </tr>
            <tr>
                <td><code>any-pointer</code></td>
                <td>Best accuracy among all pointing devices</td>
                <td>Detecting if precise input is possible</td>
            </tr>
        </table>

        <h3>Detection Scenarios</h3>
        <table class="reference-table">
            <tr>
                <th>Device</th>
                <th>hover</th>
                <th>any-hover</th>
                <th>pointer</th>
                <th>any-pointer</th>
            </tr>
            <tr>
                <td>Desktop with mouse</td>
                <td><code>hover</code></td>
                <td><code>hover</code></td>
                <td><code>fine</code></td>
                <td><code>fine</code></td>
            </tr>
            <tr>
                <td>Mobile phone (touch)</td>
                <td><code>none</code></td>
                <td><code>none</code></td>
                <td><code>coarse</code></td>
                <td><code>coarse</code></td>
            </tr>
            <tr>
                <td>Tablet with stylus</td>
                <td><code>none</code></td>
                <td><code>hover</code></td>
                <td><code>coarse</code></td>
                <td><code>fine</code></td>
            </tr>
            <tr>
                <td>Laptop with touchscreen</td>
                <td><code>hover</code></td>
                <td><code>hover</code></td>
                <td><code>fine</code></td>
                <td><code>fine</code></td>
            </tr>
            <tr>
                <td>Tablet with Bluetooth mouse</td>
                <td><code>none</code></td>
                <td><code>hover</code></td>
                <td><code>coarse</code></td>
                <td><code>fine</code></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>Use <code>any-hover</code> to detect if hover effects are possible at all</li>
                <li>Use <code>any-pointer</code> to detect if precise input is available</li>
                <li>Provide tap-friendly alternatives for touch devices</li>
                <li>Hide hover-only UI elements on touch devices</li>
                <li>Test on both desktop and mobile devices</li>
                <li>Use <code>hover: hover</code> for primary input optimization</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 hover for critical functionality</li>
                <li>Don't confuse <code>hover</code> with <code>any-hover</code></li>
                <li>Don't forget that touch devices have no hover capability</li>
                <li>Don't hide important content on touch devices</li>
                <li>Don't assume all desktops have a mouse (some use touch)</li>
            </ul>
        </div>
    </section>

    <!-- ====== SCRIPT FOR DETECTION ====== -->
    <script>
        // Detect any-hover
        function updateAnyHover() {
            const card = document.getElementById('any-hover-card');
            const value = document.getElementById('any-hover-value');
            if (window.matchMedia('(any-hover: hover)').matches) {
                value.textContent = 'hover โœ…';
                card.className = 'detection-card hover-capable';
            } else {
                value.textContent = 'none โŒ';
                card.className = 'detection-card hover-not-capable';
            }
        }

        // Detect any-pointer
        function updateAnyPointer() {
            const card = document.getElementById('any-pointer-card');
            const value = document.getElementById('any-pointer-value');
            if (window.matchMedia('(any-pointer: fine)').matches) {
                value.textContent = 'fine ๐Ÿ–ฑ๏ธ';
                card.className = 'detection-card pointer-fine';
            } else if (window.matchMedia('(any-pointer: coarse)').matches) {
                value.textContent = 'coarse ๐Ÿ‘†';
                card.className = 'detection-card pointer-coarse';
            } else {
                value.textContent = 'none โŒ';
                card.className = 'detection-card pointer-none';
            }
        }

        // Detect hover (primary)
        function updateHover() {
            const card = document.getElementById('hover-card');
            const value = document.getElementById('hover-value');
            if (window.matchMedia('(hover: hover)').matches) {
                value.textContent = 'hover โœ…';
                card.className = 'detection-card hover-capable';
            } else {
                value.textContent = 'none โŒ';
                card.className = 'detection-card hover-not-capable';
            }
        }

        // Detect pointer (primary)
        function updatePointer() {
            const card = document.getElementById('pointer-card');
            const value = document.getElementById('pointer-value');
            if (window.matchMedia('(pointer: fine)').matches) {
                value.textContent = 'fine ๐Ÿ–ฑ๏ธ';
                card.className = 'detection-card pointer-fine';
            } else if (window.matchMedia('(pointer: coarse)').matches) {
                value.textContent = 'coarse ๐Ÿ‘†';
                card.className = 'detection-card pointer-coarse';
            } else {
                value.textContent = 'none โŒ';
                card.className = 'detection-card pointer-none';
            }
        }

        // Update all on load and resize
        function updateAll() {
            updateAnyHover();
            updateAnyPointer();
            updateHover();
            updatePointer();
        }

        window.addEventListener('load', updateAll);
        window.addEventListener('resize', updateAll);
        updateAll();
    </script>

</body>
</html>

Quick Reference

FeatureDescriptionValues
any-hoverAny pointing device can hovernone, hover
any-pointerAccuracy of any pointing devicenone, coarse, fine

any-hover vs hover

FeatureDescription
hoverPrimary pointing device’s hover capability
any-hoverAny pointing device’s hover capability

any-pointer vs pointer

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

Detection Scenarios

Devicehoverany-hoverpointerany-pointer
Desktop with mousehoverhoverfinefine
Mobile phone (touch)nonenonecoarsecoarse
Tablet with stylusnonehovercoarsefine
Laptop with touchscreenhoverhoverfinefine
Tablet with Bluetooth mousenonehovercoarsefine

Best Practices

โœ… Do This:

/* Hide hover-only elements on touch devices */
@media (any-hover: none) {
    .hover-only {
        display: none;
    }
}

/* Provide tap-friendly alternatives */
@media (any-hover: hover) {
    .tooltip:hover .tooltip-text {
        display: block;
    }
}

/* Detect fine pointers for precision UI */
@media (any-pointer: fine) {
    .color-picker {
        display: block;
    }
}

@media (any-pointer: coarse) {
    .color-picker {
        display: none; /* Hide precision UI on touch */
    }
}

โŒ Don’t Do This:

/* Don't rely on hover for critical functionality */
.delete-btn {
    display: none; /* Only visible on hover โ€” bad for touch! */
}
.item:hover .delete-btn {
    display: block;
}

/* Don't confuse hover with any-hover */
@media (hover: none) {
    /* Only checks primary device โ€” may miss secondary devices */
}

/* Don't assume all desktops have a mouse */
@media (min-width: 1024px) {
    .hover-effect { /* May fail on touchscreen laptops */ }
}

Pro Tip: Use any-hover and any-pointer to create input-aware interfaces. The key insight is that hover/pointer check the primary input device, while any-hover/any-pointer check all available devices. For example, a tablet with a Bluetooth mouse has hover: none (primary is touch) but any-hover: hover (mouse can hover). Use any-hover to detect if hover effects are possible at all, and any-pointer to detect if precise input is available. Always provide tap-friendly alternatives for touch devices!


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!