10

The @support rule allows one to do a feature query on CSS properties. I am wondering whether it is possible to do a feature check on specifically @media rules?

For example, I like to know if the browser supports the @media pointer or any-pointer condition:

@supports @media (pointer:fine) {

Or

@supports @media (pointer) {

This does not seem to work. Should it work?

Edit: This is not a duplicate of the referenced question. Perhaps I should clarify the question to explain why this is a different question, so here goes:

I do not want to nest @supports inside @media or vice versa. I want to feature detect whether the @media query itself is supported, in particular the @media rule for pointer. This is a completely different scenario from just nesting a random support query inside a media query.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Fer
  • 4,116
  • 16
  • 59
  • 102
  • tl;dr you need to nest the media query inside the @supports brackets. – TylerH May 29 '17 at 14:13
  • 1
    I'm not sure but have you tried nesting something like https://codepen.io/anon/pen/mmYNgp? – Michael Coker May 29 '17 at 14:14
  • @tylerh: the question is how? – Fer May 29 '17 at 18:26
  • @MichaelCoker: Thanks, I created a fork of your starting point: https://codepen.io/fchristant/pen/BRgoKN It basically proves that this approach does not work. It does not detect the rule nested inside @ media, yet on its own without nesting, it does work. So my question still stands. – Fer May 29 '17 at 18:28

1 Answers1

14

This does not seem to work. Should it work?

No; @supports only supports property declarations, not at-rules or indeed any other grammatical construct in CSS. You're not looking to check for support for the @media rule anyway; you're trying to check for support for specific media features. But @supports doesn't support that either, even though media features share the same declaration syntax with property declarations.

To that end, you don't need the @supports rule at all. To check if a browser supports a certain media feature, simply write a @media rule with a media query list containing both the media feature and its negation:

@media not all and (pointer), (pointer) {
  p { color: green; }
}
<p>If this text is green, your browser supports the <code>pointer</code> media feature.

(Note that Media Queries 4 removes the restriction of not requiring a media type from MQ3, so the negation really ought to be not (pointer), but no browser supports this yet and a media type is still required.)

Browsers that don't recognize the pointer media feature will interpret the @media rule as @media not all, not all (in spite of the not in the not all and (pointer) media query). See section 3.2 of the spec, which says

An unknown <mf-name> or <mf-value>, or disallowed <mf-value>, results in the value “unknown”. A <media-query> whose value is “unknown” must be replaced with not all.

If you need to apply CSS for when a browser does not support a media feature, these error handling rules mean you'll need to take advantage of the cascade (and if you don't know the original values in advance, you may be stuck):

p { color: red; }

@media not all and (pointer), (pointer) {
  p { color: currentcolor; }
}
<p>If this text is red, your browser does not support the <code>pointer</code> media feature.
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • Thank you, that is exactly what I was looking for! I do have one follow-up question for the sake of completeness: what would be the syntax in your example to do the opposite? To check if a browser does NOT support pointer? – Fer May 29 '17 at 18:53
  • @Ferdy: The cascade will be your friend in that case. I've updated my answer with an example. – BoltClock May 29 '17 at 18:54
  • 1
    I saw it happen in real-time, you are fast. Thanks! – Fer May 29 '17 at 18:55
  • This is just beautiful! For completion the answer for a pointer value: `@media not all and ( pointer: fine ), ( pointer: fine ) {}` – Volker E. Oct 14 '18 at 18:04