Skip to main content

Command Palette

Search for a command to run...

Media Queries Level 5 are awesome

Updated
3 min read
Media Queries Level 5 are awesome

With modern css, you can almost get rid of sass. But there is one last pain point : media queries. Not being able to use variables or an easy, common syntax for typical breakpoints is really annoying. That is, until you meet Media Queries Level 5.

I’ve discovered them by chance by reading the Lightning CSS documentation (because, yes, modern css is great, but realistically you still need to transpile it for older browsers in most cases). This gives you the ability to do something like this:

@custom-media --modern (color), (hover);

@media (--modern) and (width > 1024px) {
  .a { color: green; }
}

Compile it with the --custom-media flag, and you are good to go!

lightningcss --minify --custom-media --bundle src/index.css -o dist/index.css

Taking Bootstrap breakpoints for a spin

So, how would this look like for a typical framework like Bootstrap. Let’s see. Combine this with the CSS Media Query Ranges and it’s actually really great.

/*

Bootstrap media queries using level 5 media queries

Example:

```css
@media (--lg-only) {
    ...
}
```

Note: requires --custom-media when using lightningcss

Documentation:
@link https://www.w3.org/TR/mediaqueries-5/
@link https://lightningcss.dev/transpilation.html#media-query-ranges
@link https://lightningcss.dev/transpilation.html#custom-media-queries

Breakpoint            Name    Dimensions
Extra small            None    <576px
Small                sm        ≥576px
Medium                md        ≥768px
Large                lg        ≥992px
Extra large            xl        ≥1200px
Extra extra large    xxl        ≥1400px
*/

/* Small devices (landscape phones, 576px and up) */
@custom-media --sm-up (width >= 576px);
/* Medium devices (tablets, 768px and up) */
@custom-media --md-up (width >= 768px);
/* Large devices (desktops, 992px and up) */
@custom-media --lg-up (width >= 992px);
/* X-Large devices (large desktops, 1200px and up) */
@custom-media --xl-up (width >= 1200px);
/* XX-Large devices (larger desktops, 1400px and up) */
@custom-media --xxl-up (width >= 1400px);

/*
Why subtract .02px?
Browsers don’t currently support range context queries,
so we work around the limitations of min- and max- prefixes and viewports
with fractional widths
(which can occur under certain conditions on high-dpi devices, for instance)
by using values with higher precision.
*/

/* `sm` applies to x-small devices (portrait phones, less than 576px) */
@custom-media --sm-down (width <= 575.98px);
/* `md` applies to small devices (landscape phones, less than 768px) */
@custom-media --md-down (width <= 767.98px);
/* `lg` applies to medium devices (tablets, less than 992px) */
@custom-media --lg-down (width <= 991.98px);
/* `xl` applies to large devices (desktops, less than 1200px) */
@custom-media --xl-down (width <= 1199.98px);
/* `xxl` applies to x-large devices (large desktops, less than 1400px) */
@custom-media --xxl-down (width <= 1399.98px);

/* `xs-only` is equivalent to `sm-down` */
@custom-media --sm-only (576px <= width <= 767.98px);
@custom-media --md-only (768px <= width <= 991.98px);
@custom-media --lg-only (992px <= width <= 1199.98px);
@custom-media --xl-only (1200px <= width <= 1399.98px);
/* `xxl-only` is equivalent to `xxl-up` */

And now, simply use it

@media (--lg-only) {
    .test {
        color: green;
    }
}
/* Outputs:
@media (min-width: 992px) and (max-width: 1199.98px) {
  .test {
    color: green;
  }
}
*/

This is actually even nicer than the equivalent Bootstrap syntax

@include media-breakpoint-only(lg) {
    .test {
        color: green;
    }
}

The CSS equivalent is both shorter and self documenting. What kind of output is the mixin going to produce? You can’t know for sure. But the CSS variable ? Just look at it and see its value.

The draft specification is not going to be usable for quite some time, so using a tool like lightning css is still required, but that seems like a small price to pay in my opinion.