Feature Queries, a hypothetical CSS vendor prefix alternative

Web browsers can be pretty self-absorbed. Vendor prefixes (and conditional comments before them) are narcissistic solutions that favor browser detection over feature detection, contrary to our industry’s best practices. As a result, browser makers have gotten themselves in a bit of a pickle.

To be fair, their intentions were (and still are) good. Our designs have benefited from proprietary or burning-edge CSS features, most of which would be difficult or impossible to implement without vendor prefixes.

The problem is, we got here by asking the wrong questions.

We shouldn’t care about whether or not our design is viewed in a “WebKit” browser, Firefox or Internet Explorer. We also shouldn’t care about whether or not a feature is in “alpha” or “beta”, distinctions too broad and subjective to be of much practical use.

Here’s what we really need to know:

  1. Does the browser support this feature?
  2. Can the browser successfully parse the syntax I’m using?

Media queries already work this way. The browser only renders the styles therein when the query is true. Because CSS is fault-tolerant, browsers that don’t support media queries will ignore the ruleset entirely.

What if we adopted a similar syntax for feature detection? Let’s use our imaginations and dive in to this 100% fictitious, hypothetical example:

@feature (transition) {
    .example {
        transition: background-color .25s ease-in-out;
    }
}

The .example ruleset will only be rendered if the browser supports the @feature query and the transition property.

By implementing the not operator from media queries, we could get hardboiled and only use queries for fallbacks:

.example {
    transition: background-color .25s ease-in-out;
}
@feature not (transition) {
    /* Fallback rules */
}

If these (again, hypothetical) feature queries could be extended to test values as well as properties, we could test for differences in syntax:

/* -moz syntax */
@feature (linear-gradient(left, white, gray)) {
    .example {
        background-image: linear-gradient(left, white, gray);
    }
}
/* -webkit syntax */
@feature (linear-gradient(linear, left center, right center, from(white), to(gray))) {
    .example {
        background-image: linear-gradient(linear, left center, right center, from(white), to(gray));
    }
}

This idea obviously has its flaws. In the latter example, things can get pretty verbose (not to mention repetitive). Also, it feels a little unintuitive to group rules by feature instead of by element or media (even though Modernizr already encourages this, albeit much more succinctly). In spite of these flaws, feature queries would allow us to design for features instead of browsers, which feels like a step in the right direction.

Then again, I may be woefully misguided. Thoughts?