What Is the Most Practical Way to Check for "@Supports" Support Using Only CSS

What is the most practical way to check for @supports support using only CSS?

@supports currently only tests property/value combinations, and nothing else. Your other options don't work because none of them are valid (including the last one with just the at-keyword followed by the opening brace!). The property/value pair requirement is dictated by the grammar for @supports, which you can find in the spec.

Simply test for a property/value pair that you know is guaranteed to work across all user agents whether or not @supports is implemented. This (sort of) eliminates the possibility that you'll run into a user agent that implements @supports but not that property/value combination, focusing on its support for @supports instead.

Your given example of display: block will suffice. Your use of the cascade to check if a browser does not implement @supports by overriding declarations within a @supports rule for browsers that do support it is also acceptable (being the only obvious way to do it anyway).

Feature detection for @supports?

Using pure CSS, you can sort of rely on the cascade to determine whether a browser understands @supports by making a @supports rule with a universally-supported declaration, such as a color declaration, and overriding another such rule that is declared globally:

#test {
color: red;
}

@supports (color: green) {
#test {
color: green;
}
}

In any browser that implements @supports correctly, #test should have green text. Otherwise, it'll have red text.

See my answer to this question for a detailed explanation of the pure CSS method.

If you're looking to detect it using JavaScript, you can use the Modernizr feature detection library as mentioned in the comments (be sure to include css-supports in your download config):

if (Modernizr.supports) {
console.log('Your browser supports @supports.');
} else {
console.log('Your browser does not support @supports.');
}

CSS @supports vs Checking Support via JS

  1. What is the best approach to checking CSS property support with @supports in older browsers not supporting this CSS syntax?

    This depends entirely on what you're trying to do. If you're checking support for a specific value of a property (such as flex for the display property), it is sufficient to provide a fallback value and let the cascade handle it for you in most cases.

    Using your example, it's as simple as:

    div {
    display: none;
    display: flex;
    }

    If you're dealing with an entire property that may not be supported in older browsers, then it depends entirely on what you're trying to accomplish with or without that property. For example, border-radius usually doesn't have any adverse effects on layout, so older browsers that don't support it will degrade gracefully without you having to do anything else. But other properties may have adverse effects on layout, and you will need to account for different properties and layout configurations differently.

  2. Would it make sense or be practical to utilize both CSS and JS for this?

    If you're using JS to cover as many bases as possible, using CSS may either be redundant, or serve as a modern, non-JS alternative that will account for users who have disabled JS. This may also vary depending on what sort of feature you're detecting.

    Since this is about @supports, it's worth noting that there is a JavaScript API called CSS.supports which functions identically except you call it from within JavaScript. If you're not worried about users with scripting disabled, you can check if it is implemented and use it if it is, or your existing feature detection code otherwise:

    var supported = false;

    if (window.CSS) {
    supported = window.CSS.supports('display', 'flex');
    } else {
    // Your existing feature detection code here
    }
  3. Is there some sort of if/else syntax for CSS @supports?

    There is no if/else syntax for CSS conditional at-rules such as @supports and @media, and even if there were, browsers that don't support @supports will likely ignore the else portion. If you need to account for older browsers, your only option is to use the cascade as shown above (and even if browser support isn't an issue, it's much simpler and covers most use cases).

    The other way is to duplicate the condition and prepend not to negate it, and the CSS rules in each @supports rule will be mutually exclusive (which is helpful if you want to include other properties that should be applied only when the property is not supported, and cannot be emulated using legacy syntax for older browsers):

    @supports (display: flex) {
    div { display: flex; }
    }

    @supports not (display: flex) {
    div { display: none; }
    }

How to check if css value is supported by the browser?

I assume you meant to check whether the vh value is supported, not whether specifically DIV#id bears it?

function cssPropertyValueSupported(prop, value) {
var d = document.createElement('div');
d.style[prop] = value;
return d.style[prop] === value;
}
cssPropertyValueSupported('width', '1px');
// => true
cssPropertyValueSupported('width', '1vh');
// => maybe true, maybe false (true for me)
cssPropertyValueSupported('width', '1foobar');
// => false

Use CSS.supports() with media queries?

No.

CSS Conditional Rules Module Level 3 only provides for testing support for property: value.

CSS Conditional Rules Module Level 4 adds the ability to test for selectors.

There's no provision for testing for support for hover.

Note that even in browsers which do support it, it might not be accessible to the user (e.g. if they use a traditional desktop browser without a mouse/trackpad/etc).

I need an easy way to detect CSS3 media query support using jquery

You can create a stylesheet with a media query and see if it works.

In your HTML:

<style>@media all and (min-width:1px) {
.mediatest {position:absolute}
}</style>

(Or you could dynamically create the stylesheet, but that's harder)

Then in your script:

var d = document.createElement('div');
d.className = "mediatest";
document.body.appendChild(d);
if( window.getComputedStyle && window.getComputedStyle(d).position == "absolute") {
// supports media queries!
}
document.body.removeChild(d);

Media query for devices supporting hover

Thanks to Dekel's comments I solved this by running the logic in JS and applying a class instead:

e.g.

const canHover = !(matchMedia('(hover: none)').matches);
if(canHover) {
document.body.classList.add('can-hover');
}

Then in the stylesheet:

.myElement {
background: blue;
}
.can-hover .myElement:hover {
background: red;
}

I've tested this on desktop Chrome, Safari and Firefox, and iOS Safari and it works as expected.



Related Topics



Leave a reply



Submit