Skip to content

Instantly share code, notes, and snippets.

@morewry
Last active October 1, 2015 21:07
Show Gist options
  • Save morewry/9635438 to your computer and use it in GitHub Desktop.
Save morewry/9635438 to your computer and use it in GitHub Desktop.
Sass mixin for nicknamed, comma-separated "or" media queries
/*
# Responsive Design Utilties
A few Sass functions and mixins helpful for responsive designs including a function to convert between CSS measurement units and a respond-to media query mixin that supports comma-separated "or" queries.
*/
// ---------------------------------------
// ---------------------------------------
/*
## Strip Units (function)
For a given CSS measurement, return as a unitless number.
strip-units( $value )
// Usage
strip-units( 16px ) // returns 16
strip-units( 1em ) // returns 1
*/
// ---------------------------------------
@function strip-units( $n ) {
@return $n / ($n * 0 + 1);
}
// ---------------------------------------
/*
## Size (function)
For a given CSS measurement, output as px, rem, em, %, or a unitless ratio ($as: "/"). Define $font-size and $config-base-font-size globals for best results.
size( $value, $as: "", $num: 1, $root: false )
// Usage
size( 16px ) // returns 1rem
size( 24px, em ) // returns 1.5em
size( 16px, "/" ) // returns 1
*/
// ---------------------------------------
@function size($value, $as: "", $num: 1, $root: false) {
$result: $value;
$n: strip-units($value);
$as: get-units($as);
$base: 16;
// base for when unit type is proportional
@if not $root {
@if variable-exists(font-size) {
$base: strip-units($font-size);
}
}
@else {
@if variable-exists(config-base-font-size) {
$base: strip-units($config-base-font-size);
}
} // if
// convert unit (with optional multiple)
@if $as == px {
$result: ($n * 1px) * $num;
}
@else if $as == rem {
$result: (($n / $base) * 1rem) * $num;
}
@else if $as == em {
$result: (($n / $base) * 1em) * $num;
}
@else if $as == "/" {
$result: (($n / $base)) * $num;
}
@else if $as == "%" {
$result: (($n / $base) * 100%) * $num;
}
@return $result;
}
// ---------------------------------------
/*
## Respond To (mixin)
For one or more screen size nicknames, output CSS properties in a media query.
respond-to( $screens... )
// Usage
@include respond-to( small, medium, large )
*/
// ---------------------------------------
@mixin respond-to ( $screens... ) {
// /* debug: mixin from app */
// /* debug: respond-to screens #{$screens} */
$query: "only screen";
$comma: ",";
$count: 0;
$ranges: (
xtrasm: (
min: size(0px, em, $root: true),
max: size(320px, em, $root: true)
),
small: (
min: size(320px, em, $root: true),
max: size(640px, em, $root: true)
),
medium: (
min: size(640px, em, $root: true),
max: size(1280px, em, $root: true)
),
large: (
min: size(1280px, em, $root: true),
max: size(2560px, em, $root: true)
),
xtralg: (
min: size(2560px, em, $root: true),
max: size(6000px, em, $root: true)
)
);
@each $size in $screens {
// /* debug: respond-to size #{$size} */
$count: $count + 1;
@if $count == 1 {
$comma: "and";
}
@else {
$comma: ",";
}
$query: "#{$query} #{$comma} (min-width: #{map-get(map-get($ranges, $size), min)}) and (max-width: #{map-get(map-get($ranges, $size), max)})";
} // each
@if $count > 0 {
@media #{$query} { @content }
}
@else {
@warn "no screen sizes provided to respond-to mixin";
} // if
} // respond-to
// ---------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment