Breakpoints Mixin Using Map or Custom Values
hiremarklittle opened this issue · comments
I have built a Sass mixin for breakpoints I think you'll find can be more useful. It does depend on a few custom functions, but the ones it needs are so useful outside of this mixin, that I don't see this as an issue. You could alternatively break the functions down inside the mixin, but it would make it more difficult to read.
This mixin is designed to pull data from a map if that data exists, or use custom values. It can use both min-width and max-width together, and it can include screen orientation.
Also, please pardon the Sass syntax. I typically only use SCSS syntax for maps.
Functions:
@function map-deep-get($map, $keys...)
@each $key in $keys
$map: map-get($map, $key)
@return $map
@function map-has-keys($map, $keys...)
@each $key in $keys
@if not map-has-key($map, $key)
@return false
@return true
@function map-has-nested-keys($map, $keys...)
@each $key in $keys
@if not map-has-key($map, $key)
@return false
$map: map-get($map, $key)
@return true
The mixin:
=break($screen-min: null, $screen-max: null, $orientation: null)
$min: $screen-min
$max: $screen-max
$o: $orientation
$query: unquote('only screen')
@if $min != null and $min != ''
@if map-has-nested-keys($base, sizes, $screen-min)
$min: map-deep-get($base, sizes, $screen-min, breakpoint)
@else
$min: $screen-min
@if is-number($min)
$query: append($query, unquote('and (min-width: #{$min})'))
@if $max != null and $max != ''
@if map-has-nested-keys($base, sizes, $screen-max)
$max: map-deep-get($base, sizes, $screen-max, breakpoint)
@else
$max: $screen-max
@if is-number($max)
$query: append($query, unquote('and (max-width: #{$max})'))
@if $orientation == landscape or $orientation == portrait
$o: $orientation
$query: append($query, unquote('and (orientation: #{$o})'))
@else
$o: null
@media #{$query}
@content
Calling the mixin:
+break(xs) //xs = 480px according to the map
...
+break(null, md) //md = 992px according to the map
...
+break($orientation: portrait)
...
+break(485px, 690px, portrait)
...
+break(300px, 600px)
Results:
@media only screen and (min-width: 480px) {...}
@media only screen and (max-width: 992px) {...}
@media only screen and (orientation: portrait) {...}
@media only screen and (min-width: 485px) and (max-width: 690px) and (orientation: portrait) {...}
@media only screen and (min-width: 300px) and (max-width: 600px) {...}