Potential use cases for script, hover and pointer CSS Level 4 Media Features

Having recently covered the luminosity media feature, I thought I’d take time to document the potential use cases for the other new media features in the CSS Level 4 Media Queries module. Note that at the time of writing these features don’t exist in any browser yet, so the following use cases are theoretical.

Having recently covered the luminosity media feature, I thought I’d take time to document the potential use cases for the other new media features in the CSS Level 4 Media Queries module. Note that at the time of writing these features don’t exist in any browser yet, so the following use cases are theoretical.

Introducing Script

The script media feature does largely the same job as existing feature detection methods albeit on a more limited scale (browsers that support CSS level 4 media queries). It checks to see if ECMAscript (commonly in the form of JavaScript on the web) is supported in the current document. That means if a user has JavaScript enabled or disabled in their browser, we can detect its state and make appropriate formatting adjustments in CSS.

There are certain limitations to what the script media feature can detect. If JavaScript is switched off and a page is loaded, the media feature will correctly report a value of “0” and it will report a value of “1” when JavaScript is enabled. But what happens to the media feature result when the user switches JavaScript off whilst viewing the page depends on the individual browser’s behaviour — it may or may not report a value of “0”. It also can’t be used as a way of providing a fallback if JavaScript errors cause something to break1 because the browser will correctly say that the current document is capable of showing scripts and return a value of “1”. The specification hints at future levels of CSS being able to provide fine-grained results of which scripts are allowed to run on a page2.

Use cases for script

Using the “not” keyword in a script media query would allow us to style fallbacks where JavaScript isn’t enabled. It could also be used for progressive enhancement where the presence of JavaScript isn’t taken for granted.

Here is an example of a script media query written with progressive enhancement in mind (assuming we have a JavaScript-powered carousel):


@media (script) {
    .carousel-links {
        display:inline-block;
                padding: 0.3em 0.6em;
                ...
    }
}

Introducing Hover

Similar to the script media feature hover returns a basic on/off (1/0) result depending on whether the primary pointing system on the device can hover3. Although touch-based devices may have the potential for hover capable input devices like a mouse, this media query will still report a value of “0” before any peripherals are attached.

The hover media feature solves a very common problem. Some UI elements that require a hover interacting like mega drop-down navigation menus often appear on touch-based devices that aren’t capable of hover functions. Their appearance is usually triggered by media queries based on screen dimensions which is not a reliable method for knowing if a device is capable of touch and/or hover inputs.

Currently the user agent on a touch device mimics a hover in some cases on the first tap of the hover menu item which seems to apply some sort of :hover and :active state. The point is — it’s not that reliable or user friendly. It takes a bit of guess work for the user to know a single tap activates hover. Thankfully the hover media query can help us fix this issue — as you’ve probably guessed, it detects the device’s ability to hover.

Use cases for hover

Upon detection of a hover-capable input device we could format our markup to enhance interfaces for such devices (e.g. drop-down menus, tooltips etc).

If we wanted drop down menus to only appear on devices that have hover input devices connected, then we would write:


@media (hover) {
    nav ul ul {
        display:none;
                /* Hide the sub menu and position absolutely to the parent li for a CSS-based hover drop down menu */
                ...
    }
        nav ul li:hover ul {
            display:block;
            /* Show the menu on hover of the parent li */
        }
}

Introducing Pointer

Pointer was generally thought of a way to differentiate between touch and other peripheral-based inputs. The media query produces 3 different values: none, coarse and fine — the assumption being that when implemented a non-touch or mouse-based device (like the 4th generation Kindles) would report “none”, an iPhone and iPad would report a value of “coarse” and a desktop machine would report “fine”.

Coarse means that the pointer limited accuracy. According to the spec4, that means that at a zoom level of 1 (your default zoom level) the pointing device would have trouble accurately selecting several small adjacent targets.

Inputs that would give a value of fine would likely be a mouse, a trackpad or even a stylus.

I have a couple of reservations about the pointer media feature and I can see potential misuse or misunderstanding of it.

A potential limitation might be when peripherals are used after the page load. For example would the media query update it’s values if I decided to switch to a stylus during browsing? Also the spec notes that for accessibility reasons some user agents may report a value of “coarse” in an environment where the input would normally be reported as “fine”.

The takeaway from all of this? Don’t rely on a coarse pointer to mean touch. Loading touch UI elements based on the accuracy of the input device is trying to solve a problem with the wrong tools. We should take pointer accuracy at face value — it can only tell us how accurate the input device is, therefore our formatting changes within a pointer media query should only make adjustments to for accuracy rather than input type. If you want to write CSS for touch enabled devices use Modernizr to detect touch capabilities because relying on the pointer media feature is like relying on a width media query to definitively say “this browser is a mobile phone”.

Use cases for pointer

The specification provides a good use case where you could theoretically enlarge tricky targets like radio buttons based on the accuracy of the pointer. Perhaps “coarse” would be a good default to work from - if we assume that the device is inaccurate then we can progressively enhance for accuracy.

The following code demonstrates how we could potentially improve accuracy on UI elements for devices with inaccurate pointers and reduce their size for devices with accurate pointers:


@media (pointer:coarse) {
  .btn {
        padding: 1.2em 2em;
        font-size: 1.6em;
  }
}

@media (pointer:fine) {
  .btn {
        padding: 0.6em 1em;
        font-size: 1em;
  }
}

The new media features offer great opportunities to progressively enhance our designs. I don’t think any of them should form the foundation for a design, nor do I think that they were ever intended to be used in such a way. What they do provide is a way for us to finesse the details. Make sure to check PalmReader to see when the new media features arrive on your device.