Nested retina media queries with Sass

Since switching from LESS to Sass I’ve been excited to learn how Sass makes responsive web design easier with @content blocks and @media mixins.

During a recent project I was interested to know if these mixins could be combined and nested with retina based media queries (mq). Could a retina-based mq be nested within a pixel based one? Turns out the answer is yes!

Here’s the media query mixin:

@mixin mq($mq) {
  @if $mq == 690  { @media (max-width: 690px)  { @content; } }
  @if $mq == 320  { @media (max-width: 320px)  { @content; } }

  @if $mq == retina {
    @media
      only screen and (-webkit-min-device-pixel-ratio: 2),
      only screen and (   min--moz-device-pixel-ratio: 2),
      only screen and (     -o-min-device-pixel-ratio: 2/1),
      only screen and (        min-device-pixel-ratio: 2),
      only screen and (                min-resolution: 192dpi),
      only screen and (                min-resolution: 2dppx) {
        @content;
    }
  }
}

And here’s the Scss for a logo image replacement. Note the retina mq is nested within the 690 media query:

#site-title a {
  @include hide-text;
  display: block;
  background: url(img/icons/spigot-logo.png) center center no-repeat;
  width: 250px;
  height: 100px;
  position: relative;
  top:5px;
  left: -13px;

    @include mq(retina) {
      background-image: url(img/icons/spigot-logo@2x.png);
      background-size: 250px 100px;
      
    }
    
    @include mq(690) {
      background: url(img/icons/spigot-logo-small.png) center center no-repeat;
      width: 90px;
      height: 125px;
      top: -3px;
      left: -6px;

      @include mq(retina) {
        background-image: url(img/icons/spigot-logo-small@2x.png);
        background-size: 90px 125px;
      }
    }

After compiling the file I was pleasantly surprised that the code not only worked, but output the final css in a pleasant manner, combining the @media logic into a single query:

@media only screen and (max-width: 690px) and (-webkit-min-device-pixel-ratio: 2), only screen and (max-width: 690px) and (min--moz-device-pixel-ratio: 2), only screen and (max-width: 690px) and (-o-min-device-pixel-ratio: 2 / 1), only screen and (max-width: 690px) and (min-device-pixel-ratio: 2), only screen and (max-width: 690px) and (min-resolution: 192dpi), only screen and (max-width: 690px) and (min-resolution: 2dppx) {
  
  #site-title a {
    background-image: url(img/icons/spigot-logo-small@2x.png);
    background-size: 90px 125px;
  }
}

Update: A reader emailed me with the following comment:

Good article, but I don’t know why you would write all that code if you could just run the Retina image through ImageOptim and call it a day. I ran the Retina version of your logo (attached) through ImageOptim and it went from 13k to 5k. No loss in quality at all.

— Clint

Clint makes a great point – delivering a 5k retina sized image to non retina screens is trivial, and saves the extra css code. I still believe the technique is worth while when delivering larger images.

Photo: Beijing National Stadium

1 Comment


Hello,

I think the function could be made more reusable by rewriting it to accept any size instead of only pre-defined ones.
I\’m new to sass so I hope I didn\’t make any mistake in the following rewrite of your function

@mixin mq($mq) {
@if $mq == retina {
@media
only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and ( min–moz-device-pixel-ratio: 2),
only screen and ( -o-min-device-pixel-ratio: 2/1),
only screen and ( min-device-pixel-ratio: 2),
only screen and ( min-resolution: 192dpi),
only screen and ( min-resolution: 2dppx) {
@content;
}
} @else {
@media (max-width: $mqpx) { @content; }
}
}

Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Check out our Complete Website Package

Chat with us about your project or click below to find out more!

Learn More   Chat with us

Hi. We are Spigot. Telemarketers pronounce it Spy-got.

We are a Park City, Utah based web design shop that excels at building custom websites powered by WordPress and WooCommerce. We love content - content strategy, content curation, content soup...????Have a look around the site. As you browse you'll find useful navigation links in the sidebar on the left. We hope you find them useful anyway... Please let us know what you think, shoot us a message here.