HTML & CSS
Article

Sass-based Media Queries With Breakpoint

By James Steinbach

This post is not going to be talking about any old Sass media query mixin. No. We are going to look at the @import (formerly Team Sass) Breakpoint Mixin. In May, Hugo Giraudel wrote a post comparing various ways of handling media queries with Sass. He mentions Breakpoint near the end of that article and today we’re going to take an in-depth look at managing responsive breakpoints with Sass using the Breakpoint plugin.

Why Use a Plugin?

If you’re like me, you might have started reading this article and thought, “I already have my own media query mixin, why use this one?” That is the exact same question I would have asked a few months ago. I’ve built my own mixin that I’m really comfortable with and I don’t see a need to switch. Even so, there are a few good reasons to look at and try another mixin.

First, we all have blindspots. While I may be completely happy with the code I wrote, I may be missing some great ways to improve it or overlooking a bug. Getting your hands dirty with someone else’s code is a great way to stretch your skills and improve your own code.

Second, it’s totally fine to depend on someone else’s code. There are no bonus points for being a ‘Lone Ranger’ programmer. Of course you need to evaluate the code and the reliability of its authors and maintainers, but having a useful plug-in that is maintained by a set of skilled volunteers is an incredible luxury.

Third, being familiar with multiple tools makes for a more versatile developer. This is especially true if you’re in a situation where you frequently “inherit” existing code. It ultimately doesn’t matter whether you love or hate new code that you try, trying it makes you more versatile and confident.

Basic Breakpoint

Installing Breakpoint

Breakpoint is a Compass extension so you’ll need to have Compass running before you can use it. Once that’s ready, you can find installation instructions on the Breakpoint website.

Setting Breakpoint Variables

To get started with Breakpoint you will need to set up a series of variables for your breakpoints. Breakpoint variables can be as simple as a measurement ($bp-large: 1200px), or as complex as a list of values ($bp-complex: (min-height 720px) (orientation landscape) (min-resolution: 300dpi);). Let’s look at the options for these variables.

One Measurement

If all you set in a variable is numeric, Breakpoint will default to a min-width media query.

$bp-one-measurement: 30em;
//output
@media (min-width: 30em) { ... }

Two Measurements

If your variable includes two measurements, Breakpoint will use the lower one as min-width and the higher as max-width:

$bp-two-measurements: 20em 40em;
//output
@media (min-width: 20em) and (max-width: 40em) { ... }

Feature and a Measurement

If your variable is a list with a string and a number, Breakpoint will use the string as a media query feature name and the number as its value.

$bp-feature-measurement: max-height 700px;
//output
@media (max-height: 700px) { ... }

Feature and a Value

You can probably see where we’re going with this one: you can put any media query feature-value pair into a variable and pass it to Breakpoint:

$bp-feature-value: orientation portrait;
//output
@media (orientation: portrait) { ... }

Multiple Feature Pairs

Let’s get crazy now. You can put together as many media query feature-value pairs as you’d like, just enclose each pair in parenthesis.

$bp-multiple-feature-pairs: (min-height 720px) (orientation landscape) (min-resolution: 300dpi);
//output
@media (min-height: 720px) and (orientation: landscape) and (min-width: min-resolution 300dpi) { ... }

Media Types

Remember media types? Screen, print, tv, projection, etc? Pass one of those labels into Breakpoint and it’ll be part of your output:

$bp-include-type: tv 30em;
//output
@media tv and (min-width: 30em) { ... }

Error Handling

Let’s say you put some bad stuff in a variable for Breakpoint. How much will it let you get away with? Breakpoint is pretty lenient: whatever you feed it, it returns. (GIGO, right?)

$bp-error: not-a-feature-or-value;
//output
@media (min-width: not-a-feature) { ... }

$bp-error: bogus pair;
//output
@media (pair: bogus) { ... }

$bp-error: (fake list) what;
//output
@media (list: fake) and (min-width: what) { ... }

What might surprise you here is that if you pass invalid strings as a feature-value pair, Breakpoint reverses their order. I’d expect $bp-error: bogus pair; to produce @media (bogus: pair) { ... }. This is because Breakpoint’s logic for handling a two-string pair only checks whether or not the first string is a valid media query value name. If it’s not, Breakpoint assumes it’s the value, doesn’t bother checking the second string, and assumes the second string is a valid feature name. While an @warn would be nice here, it’s basically a moot point since nothing is valid in this scenario anyway.

Calling the Media Queries

Now that you know what kind of craziness you can put into your media query variables for Breakpoint, let’s look at how to use it in your code. Of course the first thing to do is @import the Breakpoint library into your Sass. Once you’ve done that and set up your variables, you’re ready to use the breakpoint() mixin.

body {
  color: black;
  @include breakpoint($bp-one-measurement) {
    color: red;
  }
}
//output
body {
  color: black;
}
@media (min-width: 30em) {
  body {
    color: red;
  }
}

I recommend using the breakpoint() mixin inside whatever selector will be affected: Breakpoint will automatically re-create that selector inside the standard CSS @media (){} syntax. In my view, nesting the media query variations in relevant selector makes your Sass much easier to maintain.

However, if your project or organization requires separate media query partials, you can still use Breakpoint: just call the mixin and then put whatever selectors you want inside:

// _global.scss
body {
  color: black;

}
// _mq-30em.scss
@include breakpoint($bp-one-measurement) {
  body {
    color: red;
  }
}

//output = exactly the same
body {
  color: black;
}
@media (min-width: 30em) {
  body {
    color: red;
  }
}

Breakpoint – Beyond the Basics

Fallback for IE8

If you’re supporting IE8 or below, or other mq-less browsers (without using a JavaScript polyfill like respond.js), you can specify styles for that “fallback” state. (Personally, I’m happy serving IE8 a wider version of the single-column mobile-first styles, but you may need to serve those users a “full desktop” styled version of the site.) Breakpoint lets you do this with the $breakpoint-no-queries and $breakpoint-no-query-fallback variables.

$breakpoint-no-queries: false;
$breakpoint-no-query-fallbacks: true;
body {
  color: black;
  @include breakpoint(567px, $no-query: '.no-mqs') {
    color: red;
  }
}
//output
body {
  color: black;
}
@media (min-width: 567px) {
  body {
    color: red;
  }
}
.no-mqs body {
  color: red;
}

In this example we are using Modernizr’s .no-mqs body class to target browsers that don’t support media queries and giving them the “large” view of the site, without breaking a “mobile-first” cascade order.

If you need to print those fallback styles in a separate stylesheet, check out this part of the Breakpoint docs.

Media Query Context

Have you ever written a mixin that would output different styles depending on what breakpoint it was in? If so, Breakpoint gives you a helper function to find out: breakpoint-get-context($feature).

body {
  @include breakpoint($bp-multiple-feature-pairs) {
    orientation: breakpoint-get-context('orientation');
  }
}
//output
@media (min-height: 720px) and (orientation: landscape) and (min-width: min-resolution 300dpi) {
  body {
    orientation: landscape;
  }
}

Conclusion

Breakpoint is a powerful tool for managing media queries with Sass. In the interest of full disclosure, however, I don’t often use it. One reason: I put my breakpoints in a Sass map (and mostly just use min-width queries). However, for more complex projects (involving print, orientation, or resolution queries, for example), Breakpoint covers so much more than my simple min-width mixin and you can find out more from the Breakpoint github repo wiki.

You can play with the code behind these samples here on SassMeister.

Free Guide:

7 Habits of Successful CTOs

"What makes a great CTO?" Engineering skills? Business savvy? An innate tendency to channel a mythical creature (ahem, unicorn)? All of the above? Discover the top traits of the most successful CTOs in this free guide.

  • Bruno Seixas

    Looks like a good option for complex projects like you said.
    I couldn´t grasp all the information but after checking their website I found things a little more cristal, still it´s a powerful plugin but one needs time to understand all it´s features.

  • Sean Stopnik

    Not a fan of Compass at all. Much rather use my own mixin and not require the huge dependency of Compass just for simple mixins. But maybe thats just me….

    • julienp

      Same for me! I’ve wanted to try this for some time now, but I definitely don’t want to use Compass just or that as I already have other tools for my frontend work.

Recommended
Sponsors
Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in Front-end, once a week, for free.