CSS @supports vs Checking Support via JS
Asked Answered
D

1

5

While searching for a way to check CSS support in browsers I came across two different approaches: CSS and JavaScript. I have used JS before for checking feature support in browsers, but not for CSS properties. From what I can tell newer browsers have added support for CSS @supports, but what about the browsers that don't?

Example of CSS @supports:

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

So, if older browsers don't support CSS @supports, would it be practical to utilize both JS and CSS approaches? Regarding my example above, would it be possible to do almost an if/else statement with it such as:

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

I understand it probably wouldn't be the key word else, but being able to perform something along those lines would be beneficial. So, to sum up and organize my questions:

  1. What is the best approach to checking CSS property support with @supports in older browsers not supporting this CSS syntax?
  2. Would it make sense or be practical to utilize both CSS and JS for this?
  3. Is there some sort of if/else syntax for CSS @supports?
Downgrade answered 8/5, 2015 at 11:58 Comment(5)
As for the if/else syntax, this wouldn't be necessary as you'd use specificity to allow your @supports declarations to override your regular declarations.Offal
@JamesDonnelly You're right, that makes a lot more sense. Do you think it would be good or bad practice to include both CSS and JS when checking browser support for CSS properties?Downgrade
Or maybe a better question: What is the best way to check browser support for CSS properties (keeping in mind older browsers as well)?Downgrade
Sidenote: it seems sort of silly that the browsers you would likely need to use Support to check for features don't support @Support. caniuse.com/#search=%40supportsLampion
@DasBeasto: Browser support didn't become a huge problem until the mid-00s, so that explains why nobody came up with the brilliant idea of @supports until very recently.Qualification
Q
10
  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; }
    }
    
Qualification answered 8/5, 2015 at 12:22 Comment(2)
Wow, excellent answer. Very clear, touches each question, and provides multiple examples. I didn't know about the JS API for CSS supports, but I want to try to keep the CSS and JS separate in this case. What I have gathered from your post is CSS @supports really isn't needed when using a fallback as mentioned in your answer to Q1, correct?Downgrade
@NightOwlPrgmr: That is correct. @supports works best when dealing with properties implemented in versions of browsers that already support it.Qualification

© 2022 - 2024 — McMap. All rights reserved.