Mixing an @supports with an @media query in CSS

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 ;)


This is a good use case for a CSS preprocessor. You can define a mixin containing your mobile/gridless styles, then use that mixin inside both an @supports and a @media block. That way you don't need to duplicate the styles in your source code.

For instance, in SCSS, you could write:

@mixin no-grid-css {
  /* Placeholder for mobile/no-grid styles */
  .foo {
    color: #baa;
  }
  .baz::after {
    content: "qux";
  }
}

@supports not (display:grid) {
  @include no-grid-css;  
}

@media screen and (max-width:700px) {
  @include no-grid-css;
}

When you compile this with sass styles.scss you'll get:

@supports not (display: grid) {
  /* Placeholder for mobile/no-grid styles */
  .foo {
    color: #baa;
  }

  .baz::after {
    content: "qux";
  }
}
@media screen and (max-width: 700px) {
  /* Placeholder for mobile/no-grid styles */
  .foo {
    color: #baa;
  }

  .baz::after {
    content: "qux";
  }
}

The downside of this approach is that the styles will still be duplicated in the CSS that gets sent to the user's browser. (Don't expect your web server's gzipping to save you, either - it won't do much to reduce the size penalty of duplicating a huge block of code.) So while it saves you from the maintenance headaches of duplicating the code, it doesn't save you from the performance penalty.