cssmedia-queriesprogressive-enhancement

Mixing an @supports with an @media query in CSS


I'm building a website with CSS grid for the first time. Since not all browsers support this, I have made a set of fallback styles, and I conditionally apply those with @supports not (display:grid). But I also want to use this as the mobile stylesheet, and only use CSS grids on the larger screens - this could be achieved by a simple media query @media screen and (max-width:700px). The problem now is - if either of these is true, that is, if either the browser doesn't support CSS grid or the browser window isn't wider than 700 pixels, I want to use my fallback stylesheet.

So my question is - how do I ask the browser for @supports or @media at the same time? Nesting them isn't going to work as that's essentially asking for both of them to be true, and it feels wrong to just have that entire stylesheet copy-pasted from @supports to @media.

Basically, I want something like this:

(@supports not (display:grid)) or (@media screen and (max-width:700px)){
    /*my stylesheet*/
}

Solution

  • There isn't a way to combine two different conditional at-rules into one with OR logic (AND logic, as you've stated, can be done by nesting, even though strictly speaking they're still two separate rules). Unless you have plumbing that can automatically duplicate your CSS across two separate conditional rules for you, you will have to do that manually.

    If possible, consider approaching this from a progressive-enhancement point of view rather than a graceful-degradation one. That is, rather than applying fallback styles to browsers that either don't support grid or are displaying on smaller screens, apply grid styles to browsers that support grid and are displaying on larger screens — this is where the nesting of rules you mention then makes sense:

    @supports (display: grid) {
        /* Or screen and (min-width: 701px),
           or not screen and (max-width: 700px),
           depending on your needs and preferences */
        @media screen and (min-width: 700px) {
            /* Grid styles */
        }
    }
    

    If you're not a fan of the extra indentation, you can reduce it somewhat, or just not indent at all ;)