Last active
February 8, 2017 18:47
-
-
Save btpoe/4f1077a6eb83e3b52f10 to your computer and use it in GitHub Desktop.
Smooth transitions for different screen widths
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//////////////////////////// | |
// Slope Calc Mixin // | |
//////////////////////////// | |
// | |
// Usage: | |
// | |
// .my-widget { | |
// @include slope-calc(padding, 20px 320px, 60px 1440px, 60px 1441px); | |
// } | |
// | |
// Outputs: | |
// | |
// .my-widget { | |
// padding: calc(3.57143vw + .53571rem); | |
// } | |
// | |
// @media only screen and (min-width: 90em) | |
// .my-widget { | |
// padding: 3.75rem; | |
// } | |
// } | |
// | |
// | |
// Flags: | |
// | |
// Flags are an optional argument passed in at the end of the slope-calc include. | |
// In scss, strings work with or without quotes. | |
// | |
// - important | |
// apply the css "!important" flag to the property (or properties) at all breakpoints. | |
// | |
// - clip | |
// at the largest breakpoint, set the property to a rem value to keep the property from growing any more. | |
// | |
// | |
@function remove($list, $value, $recursive: false) { | |
$result: (); | |
@for $i from 1 through length($list) { | |
@if type-of(nth($list, $i)) == list and $recursive { | |
$result: append($result, remove(nth($list, $i), $value, $recursive)); | |
} | |
@else if nth($list, $i) != $value { | |
$result: append($result, nth($list, $i)); | |
} | |
} | |
@return $result; | |
} | |
@function strip-unit($number) { | |
@if type-of($number) == 'number' and not unitless($number) { | |
@return $number / ($number * 0 + 1); | |
} | |
@return $number; | |
} | |
@function px-to-em($number, $base:16) { | |
@return (strip-unit($number)/$base) * 1em; | |
} | |
@function unitless-px($number, $base:16) { | |
@if(unitless($number)) { | |
@return $number; | |
} | |
@else { | |
$unit: unit($number); | |
$number: strip-unit($number); | |
@if ($unit == 'px') { | |
@return $number; | |
} | |
@return $number*$base; | |
} | |
} | |
@function rem($number, $base:16) { | |
@return unitless-px($number)/$base * 1rem; | |
} | |
@function slope-calc-internal($from, $to) { | |
$to-size: unitless-px(nth($to, 1)); | |
$to-breakpoint: unitless-px(nth($to, 2)) / 100; | |
$from-size: unitless-px(nth($from, 1)); | |
$from-breakpoint: unitless-px(nth($from, 2)) / 100; | |
@if($from-breakpoint > $to-breakpoint) { | |
$tmp: $to-breakpoint; | |
$to-breakpoint: $from-breakpoint; | |
$from-breakpoint: $tmp; | |
$tmp: $to-size; | |
$to-size: $from-size; | |
$from-size: $tmp; | |
} | |
$pieces: rem($from-size); | |
$calc: $pieces; | |
@if $from-size != $to-size { | |
$slope: ($to-size - $from-size) / ($to-breakpoint - $from-breakpoint); | |
$y-intercept: $from-size - ($from-breakpoint * $slope); | |
$pieces: $slope*1vw, ($y-intercept/16)*1rem; | |
$calc: calc(#{nth($pieces, 1)} + #{nth($pieces, 2)}); | |
} | |
@return ( | |
pieces: $pieces, | |
calc: $calc, | |
breakpoint: px-to-em($from-breakpoint*100px) | |
); | |
} | |
@function slope-calc($mobile, $desktop) { | |
@return map-get(slope-calc-internal($mobile, $desktop), calc); | |
} | |
@function slope-calc-transform($prop, $from, $to) { | |
$pieces: map-get(slope-calc-internal($from, $to), pieces); | |
@if type-of($pieces) == 'list' { | |
@return #{$prop + '(' + nth($pieces, 1) + ')'} #{$prop + '(' + nth($pieces, 2) + ')'}; | |
} | |
@return #{$prop + '(' + $pieces + ')'}; | |
} | |
@function slope-calc-args($slopes) { | |
$args: nth($slopes, length($slopes)); | |
@if type-of($args) == 'string' or type-of($args) == 'list' and type-of(nth($args, 1)) == 'string' { | |
$slopes: remove($slopes, $args); | |
@if type-of($args) == 'string' { | |
$args: append((), $args); | |
} | |
} | |
@else { | |
$args: (); | |
} | |
@return ( | |
args: $args, | |
slopes: $slopes | |
); | |
} | |
@mixin slope-calc($prop, $slopes...) { | |
@if type-of($prop) == 'list' { | |
@each $p in $prop { | |
@include slope-calc($p, $slopes...); | |
} | |
} | |
@else { | |
$getArgs: slope-calc-args($slopes); | |
$args: map-get($getArgs, args); | |
$slopes: map-get($getArgs, slopes); | |
$smallest: nth($slopes, 1); | |
@each $slope in $slopes { | |
@if unitless-px(nth($slope, 2)) < unitless-px(nth($smallest, 2)) { | |
$smallest: $slope; | |
} | |
} | |
$slopes: remove($slopes, $smallest); | |
$secondSmallest: nth($slopes, 1); | |
@each $slope in $slopes { | |
@if unitless-px(nth($slope, 2)) < unitless-px(nth($secondSmallest, 2)) { | |
$secondSmallest: $slope; | |
} | |
} | |
$results: slope-calc-internal($smallest, $secondSmallest); | |
$value: map-get($results, calc) if(index($args, important) != null, !important, null); | |
@if (nth($secondSmallest, 2) == (nth($smallest, 2) + 1)) { | |
$value: rem(unitless-px(nth($smallest, 1))); | |
} | |
@if index($args, media-query) == null { | |
#{$prop}: $value; | |
} | |
@else { | |
@media only screen and (min-width: #{map-get($results, breakpoint)}) { | |
#{$prop}: $value; | |
} | |
} | |
@if (index($args, media-query) == null) { | |
$args: append($args, media-query); | |
} | |
@if length($slopes) > 1 { | |
$slopes: append($slopes, $args); | |
@include slope-calc($prop, $slopes...); | |
} | |
@elseif (index($args, clip) != null) { | |
$args: remove($args, clip); | |
$slope: nth($slopes, 1); | |
$slopes: $slope, nth($slope, 1) nth($slope, 2) + 1, $args; | |
@include slope-calc($prop, $slopes...); | |
} | |
} | |
} | |
@mixin font-size($slopes...) { | |
@include slope-calc(font-size, $slopes...); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment