Skip to content

Instantly share code, notes, and snippets.

@eduardoboucas
Created April 4, 2015 00:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eduardoboucas/5192409e14efd3349376 to your computer and use it in GitHub Desktop.
Save eduardoboucas/5192409e14efd3349376 to your computer and use it in GitHub Desktop.
Generated by SassMeister.com.
// ----
// Sass (v3.4.12)
// Compass (v1.0.3)
// ----
// _ _ _ _ _
// (_) | | | | | (_)
// _ _ __ ___| |_ _ __| | ___ _ __ ___ ___ __| |_ __ _
// | | '_ \ / __| | | | |/ _` |/ _ \ | '_ ` _ \ / _ \/ _` | |/ _` |
// | | | | | (__| | |_| | (_| | __/ | | | | | | __/ (_| | | (_| |
// |_|_| |_|\___|_|\__,_|\__,_|\___| |_| |_| |_|\___|\__,_|_|\__,_|
//
// Simple, elegant and maintainable media queries in Sass
//
// http://include-media.com
//
// Author: Eduardo Boucas <mail@eduardoboucas.com>
//
///
/// Creates a list of global breakpoints
///
/// @author Eduardo Boucas
///
/// @example scss - Creates a single breakpoint with the label `phone`
/// $breakpoints: ('phone': 320px);
///
$breakpoints: (
'phone': 320px,
'tablet': 768px,
'desktop': 1024px
) !default;
///
/// Creates a list of static expressions or media types
///
/// @author Eduardo Boucas
///
/// @example scss - Creates a single media type (screen)
/// $media-expressions: ('screen': 'screen');
///
/// @example scss - Creates a static expression with logical disjunction (OR operator)
/// $media-expressions: (
/// 'retina2x': (
/// '(-webkit-min-device-pixel-ratio: 2)',
/// '(min-resolution: 192dpi)'
/// )
/// );
///
$media-expressions: (
'screen': 'screen',
'print': 'print',
'handheld': 'handheld',
'retina2x': (
'(-webkit-min-device-pixel-ratio: 2)',
'(min-resolution: 192dpi)'
),
'retina3x': (
'(-webkit-min-device-pixel-ratio: 3)',
'(min-resolution: 350dpi)'
)
) !default;
///
/// Defines a number to be added or subtracted from each unit when declaring breakpoints with exclusive intervals
///
/// @author Eduardo Boucas
///
/// @example scss - Interval for pixels is defined as `1` by default
/// @include media(">128px") {}
///
/// /* Generates: */
/// @media (min-width: 129px) {}
///
/// @example scss - Interval for ems is defined as `0.01` by default
/// @include media(">20em") {}
///
/// /* Generates: */
/// @media (min-width: 20.01em) {}
///
/// @example scss - Interval for rems is defined as `0.1` by default, to be used with `font-size: 62.5%;`
/// @include media(">2.0rem") {}
///
/// /* Generates: */
/// @media (min-width: 2.1rem) {}
///
$unit-intervals: (
'px': 1,
'em': 0.01,
'rem': 0.1
) !default;
///
/// Generates a media query based on a list of conditions
///
/// @author Eduardo Boucas
///
/// @param {List} $conditions - Media query conditions
///
/// @example scss - With a single set breakpoint
/// @include media(">phone") { }
///
/// @example scss - With two set breakpoints
/// @include media(">phone", "<=tablet") { }
///
/// @example scss - With custom values
/// @include media(">=358px", "<850px") { }
///
/// @example scss - With set breakpoints with custom values
/// @include media(">desktop", "<=1350px") { }
///
/// @example scss - With a static expression
/// @include media("retina2x") { }
///
/// @example scss - Mixing everything
/// @include media(">=350px", "<tablet", "retina3x") { }
///
@mixin media($conditions...) {
@for $i from 1 through length($conditions) {
$conditions: set-nth($conditions, $i, parse-expression(nth($conditions, $i)));
}
$branches: get-query-branches($conditions);
$query: '';
@each $branch in $branches {
@if (str-length($query) != 0) {
$query: $query + ', ';
}
$query: $query + $branch;
}
@media #{$query} {
@content;
}
}
///
/// Reads a list of media query expressions and separates logical disjunctions into different branches
///
/// @author Eduardo Boucas
///
/// @param {List} $expressions - list of expressions
///
/// @throws `$expression` is not a valid expression
///
/// @return {List | Null}
///
@function get-query-branches($expressions) {
$result: '';
$has-groups: false;
// Getting initial snapshot and looking for groups
@each $expression in $expressions {
@if (str-length($result) != 0) {
$result: $result + ' and ';
}
@if (type-of($expression) == 'string') {
$result: $result + $expression;
} @else if (type-of($expression) == 'list') {
$result: $result + nth($expression, 1);
$has-groups: true;
} @else {
@warn '#{$expression} is not a valid expression.';
}
}
// If we have groups, we have to create all possible combinations
@if $has-groups {
@each $expression in $expressions {
@if (type-of($expression) == 'list') {
$first: nth($expression, 1);
@each $member in $expression {
@if ($member != $first) {
@each $partial in $result {
$result: join($result, str-replace-first($first, $member, $partial));
}
}
}
}
}
}
@return $result;
}
///
/// Parses a string to form a media query expression
///
/// @author Eduardo Boucas
///
/// @param {String} $expression - expression (in string)
///
/// @throws Expression with type `type-of($expression)` detected, string expected
/// @throws `$expression` is missing an operator
/// @throws Unknown unit: `$unit`
///
/// @return {String | Null}
///
@function parse-expression($expression) {
$operator: '';
$value: '';
$element: '';
$result: '';
$is-value: true;
$dimension: 'width';
@if (type-of($expression) != 'string') {
@warn 'Expression with type `#{type-of($expression)}` detected, string expected.';
}
// Detecting the 'height' prefix
@if (str-slice($expression, 1, 6) == 'height') {
$dimension: 'height';
$expression: str-slice($expression, 7);
}
// Detecting (and ignoring) the 'width' prefix for consistency
@if (str-slice($expression, 1, 5) == 'width') {
$expression: str-slice($expression, 6);
}
// Separating the operator from the rest of the expression
@if (str-slice($expression, 2, 2) == '=') {
$operator: str-slice($expression, 1, 2);
$value: str-slice($expression, 3);
} @else {
$operator: str-slice($expression, 1, 1);
$value: str-slice($expression, 2);
}
// Checking what type of expression we're dealing with
@if map-has-key($breakpoints, $value) {
$result: map-get($breakpoints, $value);
} @else if map-has-key($media-expressions, $expression) {
$result: map-get($media-expressions, $expression);
$is-value: false;
} @else {
$result: to-number($value);
}
@if ($is-value) {
$unit: unit($result);
$interval: 0;
@if (map-has-key($unit-intervals, $unit)) {
$interval: map-get($unit-intervals, $unit);
} @else {
@warn 'Unknown unit: #{$unit}';
}
@if ($operator == '>') {
$element: '(min-#{$dimension}: #{$result + $interval})';
} @else if ($operator == '<') {
$element: '(max-#{$dimension}: #{$result - $interval})';
} @else if ($operator == '>=') {
$element: '(min-#{$dimension}: #{$result})';
} @else if ($operator == '<=') {
$element: '(max-#{$dimension}: #{$result})';
} @else {
@warn '#{$expression} is missing an operator.';
}
} @else {
$element: $result;
}
@return $element;
}
///
/// Replaces the first occurence of the string with the replacement string
///
/// @author Eduardo Boucas
///
/// @param {String} $search - The value being searched for
/// @param {String} $replace - The replacement string
/// @param {String} $subject - The string being replaced on
///
/// @return {String | Null}
///
@function str-replace-first($search, $replace, $subject) {
$search-start: str-index($subject, $search);
@if $search-start == null {
@return $subject;
}
$result: str-slice($subject, 0, $search-start - 1);
$result: $result + $replace;
$result: $result + str-slice($subject, $search-start + str-length($search));
@return $result;
}
///
/// Casts a number to a string
///
/// @author Hugo Giraudel
///
/// @param {String} $string - Number to be parsed
///
/// @return {List | Null}
///
@function to-number($string) {
// Matrices
$strings: '0' '1' '2' '3' '4' '5' '6' '7' '8' '9';
$numbers: 0 1 2 3 4 5 6 7 8 9;
// Result
$result: 0;
$divider: 0;
$minus: false;
// Looping through all characters
@for $i from 1 through str-length($string) {
$character: str-slice($string, $i, $i);
$index: index($strings, $character);
@if $character == '-' {
$minus: true;
}
@else if $character == '.' {
$divider: 1;
}
@else {
@if type-of($index) != 'number' {
$result: if($minus, $result * -1, $result);
@return _length($result, str-slice($string, $i));
}
$number: nth($numbers, $index);
@if $divider == 0 {
$result: $result * 10;
}
@else {
// Move the decimal dot to the left
$divider: $divider * 10;
$number: $number / $divider;
}
$result: $result + $number;
}
}
@return if($minus, $result * -1, $result);
}
@function _length($number, $unit) {
$strings: 'px' 'cm' 'mm' '%' 'ch' 'pica' 'in' 'em' 'rem' 'pt' 'pc' 'ex' 'vw' 'vh' 'vmin' 'vmax';
$units: 1px 1cm 1mm 1% 1ch 1pica 1in 1em 1rem 1pt 1pc 1ex 1vw 1vh 1vmin 1vmax;
$index: index($strings, $unit);
@if type-of($index) != 'number' {
@warn 'Unknown unit `#{$unit}`.';
@return false;
}
@return $number * nth($units, $index);
}
@include media('height>580px') {
color: tomato;
}
@media (min-height: 581px) {
color: tomato;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment