Variable media queries in Less CSS

Version 1.3.0 of lesscss introduced nice features that were available in Sass earlier, but were missing in less – you can now nest media queries and they are bubbling.

What does that mean to us? Thanks to them, you can add media-specific styles without having to worry that all these media queries we put at the end of our stylesheets break the flow or use repeated selectors.

In the changelog we read that Media-query features can now be a variable, but it’s usage isn’t mentioned in the documentation.

I wanted to target devices with a higher pixel density, like iPhone 4 or 4S with Retina display. If I had to do this the old-fashined way (without @media bubbling), I would have to do the following:

.logo {
    background: url(/static/images/logo.png) no-repeat 0 0;
}
 
@media only screen and (min-device-pixel-ratio: 1.5) {
    .logo {
        background-image: url(/static/images/logo@2x.png);
        background-size: contain;
    }
}

Notice, that I had to repeat .logo selector which is not very good in terms of maintenance.

If I were to use @media bubbling, the code simplifies to:

.logo {
    background: url(/static/images/logo.png) no-repeat 0 0;
 
    @media only screen and (min-device-pixel-ratio: 1.5) {
        background-image: url(/static/images/logo@2x.png);
        background-size: contain;
    }
}

This is already nice, as we’re not dealing with repeated selectors anymore, but the @media part is verbose and if we wanted to use unprefixed version of min-device-pixel-ratio query a dozens of times it would not be maintainable at all. In the next example I have used full, vendor prefixed version of the query. This is where variable @media queries come into play:

@highdensity: ~"only screen and (-webkit-min-device-pixel-ratio: 1.5)",
              ~"only screen and (min--moz-device-pixel-ratio: 1.5)",
              ~"only screen and (-o-min-device-pixel-ratio: 3/2)",
              ~"only screen and (min-device-pixel-ratio: 1.5)";
 
.logo {
    background: url(/static/images/logo.png) no-repeat 0 0;
 
    @media @highdensity {
        background-image: url(/static/images/logo@2x.png);
        background-size: contain;
    }
}

Isn’t it great already? Let’s go further.

Mixing multiple media queries together

Having two or more media queries is as easy as adding selectors to query. Just insert it after a comma:

@highdensity: ~"only screen and (-webkit-min-device-pixel-ratio: 1.5)",
              ~"only screen and (min--moz-device-pixel-ratio: 1.5)",
              ~"only screen and (-o-min-device-pixel-ratio: 3/2)",
              ~"only screen and (min-device-pixel-ratio: 1.5)";
@mobile: ~"only screen and (max-width: 320px)";
 
.logo {
    background: url(/static/images/logo.png) no-repeat 0 0;
 
    @media @highdensity, @mobile {
        background-image: url(/static/images/logo@2x.png);
        background-size: contain;
    }
}

You could as well make them bubble up, but in the above example it’s not necessary.

Comments

  1. Johan Degrieck on

    Very nice article, your solution works like a charm! Just what I was looking for without knowing it :) I will certainly use this technique to tackle responsive design glitches on specific HTML elements. Thanks a lot!

    Reply
  2. Pingback: Responsive Drupal Theming, Done the Right Way… At Least For Now Anyway | CMS Radar

  3. PDXIII on

    Thank you! I was thinking about that today, that it would so awesome, if it would work like that, And it does, and you showed me. Thanks!

    Reply
  4. Bobby on

    Great explanation with examples. I have been wondering how to media queries in LESS style. Thanks a lot.

    Reply
  5. lesscss on

    Excellent work…

    Reply
  6. Pingback: Does less have the "respond-to" technique like SCSS | Technology & Programming

  7. Marcos Zanona on

    Thanks man, very useful!! I was wondering how to achieve that through LESS and here it is, the potential of mixing up variables is great as well.

    Reply
  8. davidenkeDavid on

    Thank you, works wonderful!

    Reply
  9. csswithless on

    Thanks!! :)

    Reply
  10. Thomas on

    Thanks, very handy

    Reply
  11. Gustavo Melki Portaluri on

    Doens’t works on IE8?

    Reply
    • Michał Ochman on

      Media queries are not supported in IE8. You can use one of existing polyfills written in JavaScript if you really need to use it in IE8.

      Reply
  12. Pingback: How to use LESS for media query variables in responsive design | Vodori Blog : Vodori.com Blog

  13. Nicolas De Boni on

    Very useful post! Thanks!

    Reply
  14. Daniel on

    It seems to me that this technique is making media queries for every css rule it is used in. It would get bloated quite a bit. Correct me if I’m wrong. It might be helpful occasionally but I think I would avoid it.

    Reply

Leave a Reply