Skip to content

Instantly share code, notes, and snippets.

@hdodov
Last active December 6, 2018 20:03
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hdodov/0dd329487d7ecbc444b45dcb3515f23a to your computer and use it in GitHub Desktop.
Save hdodov/0dd329487d7ecbc444b45dcb3515f23a to your computer and use it in GitHub Desktop.
Flexible Sass media queries with no hardcoding. Specify your breakpoints and you'll have mixins for media queries that are smaller, larger or inside the device ranges. Mobile first (like Bootstrap).
// ----
// Sass (v3.4.21)
// Compass (v1.0.3)
// ----
$screens: (
"xs": 0px,
"sm": 768px,
"md": 992px,
"lg": 1200px
) !default;
@function ms_search_screens($search) {
$keys: map-keys($screens);
$keysCount: length($keys);
$prev: null;
$curr: null;
$next: null;
@for $i from 1 through $keysCount {
@if (nth($keys, $i) == $search) {
$curr: $search;
@if ($i < $keysCount) {
$next: nth($keys, $i + 1);
}
@if ($i > 1) {
$prev: nth($keys, $i - 1);
}
}
}
@return (
"previous": $prev,
"current": $curr,
"next": $next
);
}
@function ms_get_screen($search, $position: "current") {
$result: ms_search_screens($search);
@return map-get($result, $position);
}
@function ms_get_screen_size($search, $position: "current") {
@return map-get($screens, ms_get_screen($search, $position));
}
@mixin media-smaller($screen) {
$size: ms_get_screen_size($screen);
@if ($size) {
@if ($size > 2) {
@media (max-width: $size - 1) {
@content;
}
} @else {
@warn "can't have @media smaller than `#{$size}`";
}
} @else {
@warn "media type not found: #{$screen}";
}
}
@mixin media-only($screen) {
$previous: ms_get_screen($screen, "previous");
$current: ms_get_screen($screen, "current");
$next: ms_get_screen($screen, "next");
$currentSize: ms_get_screen_size($current);
$nextSize: ms_get_screen_size($next);
@if ($current) {
@if ($next) {
@if ($currentSize <= 0) {
@include media-smaller($next) {
@content;
};
} @else {
@media (min-width: $currentSize) and (max-width: $nextSize - 1) {
@content;
}
}
} @else if ($previous) {
@include media-larger($previous) {
@content;
}
}
} @else {
@warn "media type not found: #{$screen}";
}
}
@mixin media-larger($screen) {
@if (ms_get_screen($screen)) {
$nextSize: ms_get_screen_size($screen, "next");
@if ($nextSize) {
@media (min-width: $nextSize) {
@content;
}
} @else {
@warn "no breakpoint after `#{$screen}`"
}
} @else {
@warn "media type not found: #{$screen}";
}
}
/*///////////
EXAMPLE USAGE
///////////*/
$screens: (
"xs": 0px,
"sm": 768px,
"md": 992px,
"lg": 1200px
);
@include media-smaller("xs") {is: smaller-xs;} /* @warn: (max-width: 0px) is pointless */
@include media-smaller("sm") {is: smaller-sm;}
@include media-smaller("md") {is: smaller-md;}
@include media-smaller("lg") {is: smaller-lg;}
@include media-only("xs") {is: only-xs;}
@include media-only("sm") {is: only-sm;}
@include media-only("md") {is: only-md;}
@include media-only("lg") {is: only-lg;}
@include media-larger("xs") {is: larger-xs;}
@include media-larger("sm") {is: larger-sm;}
@include media-larger("md") {is: larger-md;}
@include media-larger("lg") {is: larger-lg;} /* @warn: can't be larger than the largest range */
/*////
OUTPUT
////*/
@media (max-width: 767px) {
is: smaller-sm;
}
@media (max-width: 991px) {
is: smaller-md;
}
@media (max-width: 1199px) {
is: smaller-lg;
}
@media (max-width: 767px) {
is: only-xs;
}
@media (min-width: 768px) and (max-width: 991px) {
is: only-sm;
}
@media (min-width: 992px) and (max-width: 1199px) {
is: only-md;
}
@media (min-width: 1200px) {
is: only-lg;
}
@media (min-width: 768px) {
is: larger-xs;
}
@media (min-width: 992px) {
is: larger-sm;
}
@media (min-width: 1200px) {
is: larger-md;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment