Skip to content

Instantly share code, notes, and snippets.

@jsonberry
Last active October 29, 2018 20:39
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 jsonberry/c35d4940077011fb2f7d100730a10656 to your computer and use it in GitHub Desktop.
Save jsonberry/c35d4940077011fb2f7d100730a10656 to your computer and use it in GitHub Desktop.
/// Breakpoints
/// @author Jason Awbrey
/// @param { phone | tablet-portrait | tablet-landscape | desktop | desktop-big } $type [no default]
/// @return { Number } Rem calculated value for a given breakpoint
@function bp($type) {
/// @prop
$breakpoints: (phone: 599, tablet-portrait: 600, tablet-landscape: 900, desktop: 1200, desktop-big: 1800);
@if (map-has-key($breakpoints, $type) != true) {
@error "$type must be one of these: #{map-keys($breakpoints)}";
}
@return rem(map-get($breakpoints, $type));
}
.class, span {
@include fluid-size('height', (bp(phone): rem(55), bp(desktop): rem(100))
}
// fluid-sizing
// https://medium.com/@jakobud/css-polyfluidsizing-using-calc-vw-breakpoints-and-linear-equations-8e15505d21ab
//
// Generate linear interpolated size values through multiple break points
// @param $property - A string CSS property name
// @param $map - A SASS map of viewport unit and size value pairs
// @requires function linear-interpolation
// @requires function map-sort
// @example
// @include poly-fluid-sizing('font-size', (576px: 22px, 768px: 24px, 992px: 34px));
// @author Jake Wilson <jake.e.wilson@gmail.com>
@mixin fluid-size($property, $map) {
// Get the number of provided breakpoints
$length: length(map-keys($map));
// Error if the number of breakpoints is < 2
@if ($length < 2) {
@error "fluid-size() $map requires at least values";
}
// Sort the map by viewport width (key)
$map: map-sort($map);
$keys: map-keys($map);
// Minimum size
#{$property}: map-get($map, nth($keys,1));
// Interpolated size through breakpoints
@for $i from 1 through ($length - 1) {
@media (min-width:nth($keys,$i)){
$value1: map-get($map, nth($keys,$i));
$value2: map-get($map, nth($keys,($i + 1)));
// If values are not equal, perform linear interpolation
@if ($value1 != $value2) {
#{$property}: linear-interpolation((nth($keys,$i): $value1, nth($keys,($i+1)): $value2));
}
@else {
#{$property}: $value1;
}
}
}
// Maxmimum size
@media (min-width:nth($keys,$length)) {
#{$property}: map-get($map, nth($keys,$length));
}
}
/// linear-interpolation
/// Calculate the definition of a line between two points
/// [jsa] Required for the fluid-size mixin
/// https://medium.com/@jakobud/css-polyfluidsizing-using-calc-vw-breakpoints-and-linear-equations-8e15505d21ab
/// @param $map - A SASS map of viewport widths and size value pairs
/// @returns { VW Calculation } A linear equation as a calc() function
/// @example
/// font-size: linear-interpolation((320px: 18px, 768px: 26px));
/// @author Jake Wilson <jake.e.wilson@gmail.com>
@function linear-interpolation($map) {
$keys: map-keys($map);
@if (length($keys) != 2) {
@error "linear-interpolation() $map must be exactly 2 values";
}
// The slope
$m: (map-get($map, nth($keys, 2)) - map-get($map, nth($keys, 1)))/(nth($keys, 2) - nth($keys,1));
// The y-intercept
$b: map-get($map, nth($keys, 1)) - $m * nth($keys, 1);
// Determine if the sign should be positive or negative
$sign: "+";
@if ($b < 0) {
$sign: "-";
$b: abs($b);
}
@return calc(#{$m*100}vw #{$sign} #{$b});
}
/// list-remove
/// Remove an item from a list
/// [jsa] Required for the fluid-size mixin
/// https://medium.com/@jakobud/css-polyfluidsizing-using-calc-vw-breakpoints-and-linear-equations-8e15505d21ab
/// @param $list - A SASS list
/// @param $index - The list index to remove
/// @returns { Immutable new list with removed index } A SASS list
/// @author Jake Wilson <jake.e.wilson@gmail.com>
@function list-remove($list, $index) {
$newList: ();
@for $i from 1 through length($list) {
@if $i != $index{
$newList: append($newList, nth($list,$i), 'space');
}
}
@return $newList;
}
/// list-sort
/// Sort a SASS list
/// [jsa] Required for the fluid-size mixin
/// https://medium.com/@jakobud/css-polyfluidsizing-using-calc-vw-breakpoints-and-linear-equations-8e15505d21ab
/// @param $list - A SASS list
/// @returns { A sorted SASS list }
/// @requires { function } list-remove
/// @author Jake Wilson <jake.e.wilson@gmail.com>
@function list-sort($list) {
$sortedlist: ();
@while length($list) > 0 {
$value: nth($list,1);
@each $item in $list {
@if $item < $value{
$value: $item;
}
}
$sortedlist: append($sortedlist, $value, 'space');
$list: list-remove($list, index($list, $value));
}
@return $sortedlist;
}
/// map-sort
/// Sort map by keys
/// [jsa] Required for the fluid-size mixin
/// https://medium.com/@jakobud/css-polyfluidsizing-using-calc-vw-breakpoints-and-linear-equations-8e15505d21ab
/// @param $map - A SASS map
/// @returns { A SASS map sorted by keys }
/// @requires function list-sort
/// @author Jake Wilson <jake.e.wilson@gmail.com>
@function map-sort($map) {
$keys: list-sort(map-keys($map));
$sortedMap: ();
@each $key in $keys {
$sortedMap: map-merge($sortedMap, ($key: map-get($map, $key)));
}
@return $sortedMap;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment