Breakpoint makes writing media queries in Sass super simple.
Here's one:

$high-tide: 500px;

I told you it was simple. Check it out. You can use that variable in the Breakpoint mixin like this.


.johnny-utah {
  @include breakpoint($high-tide) {
    content: 'Whoa.';
  }
}

@media (min-width: 500px) {
  .johnny-utah {
    content: 'Whoa.';
  }
}

That just did two things that are really helpful. First, we reduced the media query down to the one value that really matters here, the min-width value. (You can also build complex queries and override the defaults. We’ll get to those.) And second, we gave that media query a meaningful name. And once we start calling media queries by name we can start managing them systematically. Whoa.

Let’s add a few more.


// assume min-width (by default) if only a number
$high-tide: 500px;
// set min-width/max-width if both values are numbers
$ex-presidents: 600px 800px;
// if one value is a string, assume a feature/value pair
$surfboard-width: max-width 1000px;
// string tests together within parentheses, assume each item is a feature value pair
$surfboard-height: (min-height 1000px) (orientation portrait);

And look at each in turn.

  1. $high-tide uses the defaults. Pass Breakpoint just a number and it assumes you want it to write a min-width query.

    
       .reagan {
         @include breakpoint($high-tide) {
           content: 'High tide';
         }
       }
       
    
       @media (min-width: 500px) {
         .reagan {
           content: 'High tide';
         }
       }
       
  2. $ex-presidents is made up of two numbers. When Breakpoint sees that it will turn that into a min-width/max-width query.

    
     .nixon {
       @include breakpoint($ex-presidents) {
       content: 'Ex-Presidents';
       }
     }
     
    
     @media (min-width: 600px) and (max-width: 800px) {
       .nixon {
         content: 'Ex-Presidents';
       }
     }
     
  3. $surfboard-width is made up of a number and the name of a feature to test. Breakpoint will turn these into feature/value pairs

    
     .johnson {
       @include breakpoint($surfboard-width) {
         content: 'Surfboard Width';
       }
     }
     
    
     @media (max-width: 1000px) {
       .johnson {
         content: 'Surfboard Width';
       }
     }
     
  4. $surfboard-height has a feature/value pair, and adds a second non-numeric pair. Breakpoint can interpret text-based tests and can string together as many queries as you need.

    
     .carter {
       @include breakpoint($surfboard-height) {
         content: 'Surfboard Height, Portrait';
       }
     }
     
    
     @media (min-height: 1000px) and (orientation: portrait) {
       .carter {
         content: 'Surfboard Height, Portrait';
       }
     }
     

That’s the basics, but wait there’s more.

Breakpoint also builds in robust support for no query fallbacks, the ability to pass the media query context to your own custom mixins, and special handling for device-pixel-ratio.

Get Started

For the full documentation, check out our wiki. Read on for an overview.

Breakpoint is a Compass extension, so make sure you have Sass and Compass Installed in order to use its awesomeness!

gem install compass

Install and Add Breakpoint to Your Project

gem install breakpoint

If creating a new project or adding to existing project, in config.rb

compass create MY_PROJECT -r breakpoint
require 'breakpoint'

Import the breakpoint partial at the top of your working file

@import "breakpoint";

Using Breakpoint

First, we set up our breakpoint variables.


// create $breakpoint variables like so
// assume min-width (by default) if only a number
$breakpoint-medium-width: 500px;
$breakpoint-medium-width-em: 30em;
// set min-width/max-width if both values are numbers
$breakpoint-medium-not-wide: 500px 700px;
// set min/max of feature if there are two numbers
$breakpoint-medium-height: height 300px 700px;
// if one value is a string, assume a feature/value pair
$breakpoint-kind-of-wide: min-width 700px;
$breakpoint-not-too-wide: max-width 700px;
// for multidimensional lists, assume each item is a feature value pair
$breakpoint-wide-portrait: (max-width 700px) (orientation portrait);
// handle one-sided features (ie. monochrome)
$breakpoint-wide-portrait-mono: (max-width 700px) (orientation portrait) (monochrome);
$breakpoint-mono: monochrome;
$breakpoint-hi-rez: min-resolution 1.5dppx;

Call the mixin and pass one of your breakpoint variables. You can also call it with a la carte arguments.


.foo {
  @include breakpoint($breakpoint-medium-width) {
    content: 'medium widths';
  }
}
.bar {
  @include breakpoint($breakpoint-medium-width-em) {
    content: 'medium widths measured in ems';
  }
}
.baz {
  @include breakpoint($breakpoint-medium-not-wide) {
    content: 'medium, but not too wide';
  }
}
.tgif {
 @include breakpoint($breakpoint-medium-height) {
   content: 'medium heights';
 }
}
.omg {
  @include breakpoint($breakpoint-kind-of-wide) {
    content: 'kind of wide';
  }
}
.wtf {
  @include breakpoint($breakpoint-not-too-wide) {
    content: 'not too wide';
  }
}
.bbq {
  @include breakpoint($breakpoint-wide-portrait) {
    content: 'wide, portrait';
  }
}
.zztop {
  @include breakpoint($breakpoint-wide-portrait-mono) {
    content: 'wide, portrait, monochrome';
  }
}
.csny {
  @include breakpoint($breakpoint-mono) {
    content: 'monochrome';
  }
}
.elp {
  @include breakpoint($breakpoint-mono, print) {
    content: 'monochrome, print';
  }
}
.omgdpr {
 @include breakpoint($breakpoint-hi-rez) {
  content: 'hi resolutions';
 }
}

// You can use breakpoint without variables too.
.rhcp {
  @include breakpoint(30em 40em) {
    content: 'between 30 and 40ems';
  }
}

@media (min-width: 500px) {
  .foo {
    content: 'medium widths';
  }
}

@media (min-width: 30em) {
  .bar {
    content: 'medium widths measured in ems';
  }
}

@media (min-width: 500px) and (max-width: 700px) {
  .baz {
    content: 'medium, but not too wide';
  }
}

@media (min-height: 300px) and (max-height: 700px) {
  .tgif {
    content: 'medium heights';
  }
}

@media (min-width: 700px) {
  .omg {
    content: 'kind of wide';
  }
}

@media (max-width: 700px) {
  .wtf {
    content: 'not too wide';
  }
}

@media (max-width: 700px) and (orientation: portrait) {
  .bbq {
    content: 'wide, portrait';
  }
}

@media (max-width: 700px) and (orientation: portrait) and (monochrome) {
  .zztop {
    content: 'wide, portrait, monochrome';
  }
}

@media (monochrome) {
  .csny {
    content: 'monochrome';
  }
}

@media print and (monochrome) {
  .elp {
    content: 'monochrome, print';
  }
}

@media (-webkit-device-pixel-ratio: 2) {
  .omgdpr {
    content: 'hi resolutions';
  }
}

@media (min-resolution: 1.5dppx), (-webkit-min-device-pixel-ratio: 1.5), (min--moz-device-pixel-ratio: 1.5), (min-resolution: 144dpi) {
  .omgdpr {
    content: 'hi resolutions';
  }
}

@media (min-width: 30em) and (max-width: 40em) {
  .rhcp {
    content: 'between 30 and 40ems';
  }
}

@media (min-width: 31.25em) {
  .foo {
    content: 'medium widths';
  }
}

@media (min-width: 30em) {
  .bar {
    content: 'medium widths measured in ems';
  }
}

@media (min-width: 31.25em) and (max-width: 43.75em) {
  .baz {
    content: 'medium, but not too wide';
  }
}

@media (min-height: 18.75em) and (max-height: 43.75em) {
  .tgif {
    content: 'medium heights';
  }
}

@media (min-width: 43.75em) {
  .omg {
    content: 'kind of wide';
  }
}

@media (max-width: 43.75em) {
  .wtf {
    content: 'not too wide';
  }
}

@media (max-width: 43.75em) and (orientation: portrait) {
  .bbq {
    content: 'wide, portrait';
  }
}

@media (max-width: 43.75em) and (orientation: portrait) and (monochrome) {
  .zztop {
    content: 'wide, portrait, monochrome';
  }
}

@media print and (monochrome) {
  .elp {
    content: 'monochrome, print';
  }
}

@media (min-width: 30em) and (max-width: 40em) {
  .rhcp {
    content: 'between 30 and 40ems';
  }
}

Advanced Features

No Query Fallback

Breakpoint provides a way to generate fallback CSS for if you would like the CSS to apply even if media queries aren’t available. There are three methodologies we discovered cover most, if not all, of the stylistic options a user could have in a system like this: a wrapping selector within the same stylesheet, a seperate stylesheet with no wrapping selector, and a seperate stylesheet with a wrapping selector. For both of these, bare in mind that Sass cannot create separate stylesheets automatically (yet), so you’re going to need to do it by hand, but the tools we’ve provided are very powerful, so we think you’ll like.

There are now two new breakpoint flags to set that control no query support, $breakpoint-no-queries for specifying that only no query output should be output by Breakpoint and $breakpoint-no-query-fallbacks for specifying that you want no query wrappers to be printed. Both of the new flags, $breakpoint-no-queries and $breakpoint-no-query-fallbacks default to false, toggling them to true activates them. For the purposes of clarity in the following code samples, I’m including both flags even though the false flags are not explicitly needed. When passing in a wrapper, you must write the whole wrapper and may include a compound wrapper, i.e. '.no-mqs' or '#print' or '.high-dpi.no-mqs'. Variables may also be passed in, but they still require the whole wrapper.

Wrapping Selector, Same Stylesheet


$breakpoint-no-queries: false;
$breakpoint-no-query-fallbacks: true;

#foo {
  background: red;
  @include breakpoint(567px, $no-query: '.no-mqs') {
    background: green;
  }
}

#foo {
  background: red;
}

@media (min-width: 567px) {
  #foo {
    background: green;
  }
}
.no-mqs #foo {
  background: green;
}

No Wrapping Selector, Separate Stylesheet


#foo {
  background: red;
  @include breakpoint(567px, $no-query: true) {
    background: green;
  }
}

$breakpoint-no-queries: false;
$breakpoint-no-query-fallbacks: false;

@import 'layout';

$breakpoint-no-queries: true;
$breakpoint-no-query-fallbacks: false;

@import 'layout';

#foo {
  background: red;
}

@media (min-width: 567px) {
  #foo {
    background: green;
  }
}
#foo {
  background: red;
  background: green;
}

Wrapping Selector, Separate Stylesheet


#foo {
  background: red;
  @include breakpoint(567px, $no-query: '.no-mq') {
    background: green;
  }
}

$breakpoint-no-queries: false;
$breakpoint-no-query-fallbacks: false;

@import 'layout';

$breakpoint-no-queries: true;
$breakpoint-no-query-fallbacks: true;

@import 'layout';

#foo {
  background: red;
}

@media (min-width: 567px) {
  #foo {
    background: green;
  }
}
#foo {
  background: red;
}

.no-mq #foo {
  background: green;
}

Media Query Context

Ever wanted to get the context of a media query from within a mixin or function? Well we have, so we’ve made that possible! Simply call the breakpoint-get-context($feature) function which will either return the contextual value for that feature (min-width, max-width, etc…) or false. You can then do all the awesomeness that you’ve ever wanted to do with that information.

Caviats with Media Query context:

  • If you have $breakpoint-to-ems set to true, you will get returns in base ems. You can run non-em based values through breakpoint-to-base-em($value) to convert them to base ems.
  • If you are testing for a prefixed feature (such as device-pixel-ratio), you need to test for the prefixed value (-webkit-device-pixel-ratio, min--moz-device-pixel-ratio, etc…).

device-pixel-ratio

Note re: `-o-device-pixel-ratio` If you're a savvy reader, you'll have noticed that we've not included `-o-device-pixel-ratio` as a prefixed option, and we would encourage you not to either. Opera has decided that their implementation should be written as a fraction, not as a decimal, and we are currently not prepared to support automatic conversion of decimals to fractions. This leaves us in the position of either supporting only fractions for unprefixed `device-pixel-ratio`, which is counter to the way the two largest browsers support the query, or suggesting that if you want to use `-o-device-pixel-ratio` that you write a separate media query for it, and we've chosen the later.

Credits

By Your Friends,

License

Licensed under GPL2/MIT: GPL2 license MIT license