Last active
January 30, 2017 12:21
-
-
Save killercup/2394ef0c8f27a78dd267b8bd39d64b90 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$breakpoints: ( | |
s: 450px, | |
m: 600px, | |
l: 900px, | |
xl: 1200px | |
) !default; | |
@function get-breakpoint($name, $breakpoints: $breakpoints) { | |
$breakpoint: map-get($breakpoints, $name); | |
@if $breakpoint == null { | |
@error "Could not find breakpoint `#{$name}` in `#{$breakpoints}`."; | |
} | |
@return $breakpoint; | |
} | |
/// Viewport mixin to ergonomically generate media queries | |
/// | |
/// # Parameters | |
/// | |
/// - `$query`: The breakpoint constrait for this viewport. This is not | |
/// formatted like a CSS media query, please see the documentation below. | |
/// - `$breakpoints`: Optional, map of size names to breakpoints (e.g., | |
/// `(phone: 600px, desktop: 1200px)`). | |
/// - `@content` block. | |
/// | |
/// ## Query syntax | |
/// | |
/// The `$query` paramter can be in one of the following forms: | |
/// | |
/// - `$breakpoint`: Covers everything up to and including `$breakpoint` | |
/// - `below $breakpoint`: Covers everything up to but not including | |
/// `$breakpoint` | |
/// - `above $breakpoint`: Covers everything just above `$breakpoint` | |
/// - `from $narrow to $wide`: Covers everything from `$narrow` up to but not | |
/// including `$wide`. (I originally wanted to call this `between $x and $y` | |
/// but SCSS interprets the `and` as an operator and thus sees this as a tuple | |
/// with `between` and the result of `$x and $y` in it.) | |
/// | |
/// # Examples | |
/// | |
/// ```scss | |
/// @include viewport(s) { /* */ } | |
/// @include viewport(above m) { .t3 { content: "above m" } } | |
/// @include viewport(below xl) { .t4 { content: "below xl" } } | |
/// @include viewport(from m to l) { .t2 { content: "between m and l" } } | |
/// ``` | |
@mixin viewport($query, $breakpoints: $breakpoints) { | |
$parse-error: "Viewport mixin could not parse query `#{$query}`."; | |
// Usage: `viewport($breakpoint)` | |
@if length($query) == 1 { | |
$breakpoint: get-breakpoint($query, $breakpoints); | |
@media screen and (max-width: $breakpoint) { | |
@content; | |
} | |
} | |
// Usage: `viewport(above|below $breakpoint)` | |
@else if length($query) == 2 { | |
$direction: nth($query, 1); | |
$breakpoint: get-breakpoint(nth($query, 2), $breakpoints); | |
@if $direction == "above" { | |
@media screen and (min-width: $breakpoint) { | |
@content; | |
} | |
} @else if $direction == "below" { | |
@media screen and (max-width: $breakpoint - 1px) { | |
@content; | |
} | |
} @else { | |
@error $parse-error; | |
} | |
} | |
// Usage: `viewport(from $narrow to $wide)` | |
@else if length($query) == 4 { | |
@if (nth($query, 1) != "from") or (nth($query, 3) != "to") { | |
@error $parse-error; | |
} | |
$narrow: get-breakpoint(nth($query, 2), $breakpoints); | |
$wide: get-breakpoint(nth($query, 4), $breakpoints); | |
@media screen and (min-width: $narrow) and (max-width: $wide - 1px) { | |
@content; | |
} | |
} @else { | |
@error $parse-error; | |
} | |
} | |
// Tests | |
// - Compile success | |
@include viewport(s) { .t1 { content: "s" } } | |
@include viewport(above m) { .t3 { content: "above m" } } | |
@include viewport(below xl) { .t4 { content: "below xl" } } | |
@include viewport(from m to l) { .t2 { content: "between m and l" } } | |
// - Compile fail | |
// @include viewport() { /* the endless void */ } | |
// @include viewport(nope) { /* so sad */ } | |
// @include viewport(what is going on) { /* dafuq */ } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment