Feature Testing:

As we produce more advanced CSS properties, the possibility of creating something that is unusable in the absence of that property increases. For example: * the new layout modes (template, flexbox) may significantly screw up a page in a UA that supports CSS but not that specific layout mode * text-shadow may be used to render a run of text visible over a similar-color background

While you can in some cases design your page to fail gracefully, doing so becomes more difficult as time goes on, and restricting yourself to situations where you can do graceful fallback means missing out on a lot of useful and interesting types of displays.

It's time to bite the bullet and add feature-testing into CSS, so we can link together a suite of properties contingent on some of them being supported.

This is not going to be bulletproof. It's impossible to be so. But it can be at least as capable as capability-testing in javascript, and if done well can at least somewhat discourage using this for hacky UA-detection.


use the !required syntax, to allow the “ignore if you don't support” ability of CSS to spread to more than just the single invalid line.

When used in a normal declaration block, if the property that !required is used on is not supported, the entire declaration block will be ignored. Multiple !required properties must all be supported; if any are not, the entire block is ignored.

As well, a new @supports{} @-rule is introduced. Within this, all !required rules in all declaration blocks must be supported, or else the entire @supports block will be ignored.


h2 {
  background: white;
  color: black;
h2 {
  background: white;
  color: white;
  text-shadow: 0 0 2px black !required;

If text-shadow is supported, color is set to white and the text-shadow keeps it legible. If not, the entire second block is ignored, and color is set to black.

body { position: relative; width: 800px; }
#header { position: absolute; left: 0; right: 0; top: 0; height: 150px;}
#sidebar { position: absolute; left: 0; top: 150px; width: 200px;}
#content { position: absolute; left: 200px; right: 0;top: 150px; }
@supports {
  body {
    display: "aa" /150px
             "bc" /auto
              200px auto !required;
  #header { position: a; height: auto;}
  #sidebar { position: b; width: auto;}
  #content { position: c; }

In this example, if a browser supports Template Layout, the later `position` values override the previous values of “absolute” (and the left/top/right values are thus ignored), and the page is laid out according to the Template Layout spec. If the browser doesn't support Template Layout, though, then the entire @supports block is ignored, and the previous absolute positioning takes effect instead.


This sort of feature testing is as close to ideal as I think we can get something in this space. The feature that you're testing for is directly annotated, making it obvious what's required. The tested-for value must actually be used, which limits the ability to UA-detect in dangerous ways (in practice, some values can indeed still be used for this as they have irrelevant or inconsequential effects in the context you're using them in).

The user can, of course, trivially UA-detect by tying !required to a prefixed property. We really can't prevent this without gutting a substantial amount of power from the proposal (if I can't detect that -webkit-text-shadow is supported, I still can't use it in a way that would fail badly if it's not supported). However, we can at least be certain that UA-detection based on prefixes will be *correct*. You'll never see a webkit-based browser claim to support a -moz-* property or value. Thus the damage is actually relatively limited, and better than the current situation where UA-detection hacks in CSS can accidentally spread to other browsers when they start to support new properties.

ideas/feature-testing.txt · Last modified: 2014/12/09 15:48 (external edit)
Recent changes RSS feed Valid XHTML 1.0 Valid CSS Driven by DokuWiki