Created
January 16, 2021 19:26
-
-
Save tedw/f8ba9be15cf926d2dc983a7004c089a6 to your computer and use it in GitHub Desktop.
Generated by SassMeister.com.
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
/// Base font size | |
/// @group Main | |
/// @type Number | |
$fs-base-font-size: 16px !default; | |
/// Convert px to em | |
/// @group Main | |
/// @param {Number | Map} $values - Value or values to convert | |
/// @param {Number} $context [$fs-base-font-size] - Base font size | |
/// @return {*} - Converted value or list of values | |
/// @require {variable} $fs-base-font-size - Base font size | |
@function fs-em($values, $context: $fs-base-font-size) { | |
// Ensure context size is in pixels | |
@if unit($context) != 'px' { | |
@error '🔴 #{$context} size must be in pixels'; | |
} | |
// Placeholder list for converted values | |
$output: (); | |
@each $val in $values { | |
// Check if pixel value | |
@if type-of($val) == 'number' and unit($val) == 'px' { | |
// Convert to ems | |
$val: ($val / $context) * 1em; | |
} | |
// Do nothing to all other values | |
@else if $fs-debug-mode { | |
@warn '⚠️ Can’t convert non-pixel value to ems: #{$val}'; | |
} | |
// Append value to output list | |
$output: append($output, $val); | |
} | |
// Return converted value(s) | |
@return $output; | |
} | |
/// Convert px to rem | |
/// @group Main | |
/// @param {Number | Map} $values - Value values to convert | |
/// @param {Number} $context [$fs-base-font-size] - Base font size | |
/// @return {*} - Converted value or list of values | |
/// @require {variable} $fs-base-font-size - Base font size | |
@function fs-rem($values) { | |
// Placeholder list for converted values | |
$output: (); | |
@each $val in $values { | |
// Check if pixel value | |
@if type-of($val) == 'number' and unit($val) == 'px' { | |
// Convert to rems | |
$val: ($val / $fs-base-font-size) * 1rem; | |
} | |
// Do nothing to all other values | |
@else if $fs-debug-mode and $val != 0 { | |
@warn '⚠️ Can’t convert non-pixel value to rems: #{$val}'; | |
} | |
// Append value to output list | |
$output: append($output, $val); | |
} | |
// Return converted value(s) | |
@return $output; | |
} | |
//// | |
/// @group Main | |
//// | |
/// Base media query mixin | |
/// @param {Number | Map} $conditions - Width or map of conditions | |
/// | |
/// @example scss | |
/// @include fs-media((min-width: 600px)) {…} | |
/// | |
/// @include fs-media((min-width: 600px, max-width: 900px, min-height: 500px, min-aspect-ratio: "1/1")) {…} | |
/// | |
/// @ignore Convert units to ems when applicable http://zellwk.com/blog/media-query-units/ | |
/// @ignore Note: EMs in media queries are relative to the initial browser font-size (16px) http://www.w3.org/TR/css3-mediaqueries/#units | |
/// @ignore Demo: http://www.sassmeister.com/gist/908ff8ee2e2e0b18f768fcbc87df385c | |
@mixin fs-media($conditions) { | |
// Check if $conditions is a valid map | |
@if type-of($conditions) != 'map' { | |
@error '🔴 “#{$conditions}” is not a valid Sass map'; | |
} | |
@else { | |
$mq-conditions: ''; | |
// Convert map to properly formatted media query string | |
@each $type, $value in $conditions { | |
// If value is a number, we may need to convert to ems | |
@if type-of($value) == 'number' { | |
// Convert px to em | |
@if unit($value) == 'px' { | |
$value: ($value / 16px) * 1em; | |
} | |
// Convert rem to em | |
@else if unit($value) == 'rem' { | |
$value: ($value / 1rem) * 1em; | |
} | |
} | |
// Use str-insert() with -1 index to append value to the end | |
$mq-conditions: str-insert($mq-conditions, 'and (#{$type}: #{$value}) ', -1); | |
} | |
// Output the media query | |
@media all #{$mq-conditions} { | |
@content; | |
} | |
} | |
} | |
/// Min-width media query helper | |
/// @require {mixin} fs-media | |
/// @param {Number} $width - Breakpoint width | |
/// | |
/// @example scss | |
/// @include fs-min-width(960px) {…} | |
/// | |
@mixin fs-min-width($width) { | |
@include fs-media((min-width: $width)) { | |
@content; | |
} | |
} | |
/// Max-width media query helper | |
/// @require {mixin} fs-media | |
/// @param {Number} $width - Breakpoint width | |
/// | |
/// @example scss | |
/// @include fs-max-width(960px) {…} | |
/// | |
@mixin fs-max-width($width) { | |
@include fs-media((max-width: $width)) { | |
@content; | |
} | |
} | |
/// Min-height media query helper | |
/// @require {mixin} fs-media | |
/// @param {Number} $height - Breakpoint height | |
/// | |
/// @example scss | |
/// @include fs-min-height(500px) {…} | |
/// | |
@mixin fs-min-height($height) { | |
@include fs-media((min-height: $height)) { | |
@content; | |
} | |
} | |
/// Max-height media query helper | |
/// @require {mixin} fs-media | |
/// @param {Number} $height - Breakpoint height | |
/// | |
/// @example scss | |
/// @include fs-max-height(500px) {…} | |
/// | |
@mixin fs-max-height($height) { | |
@include fs-media((max-height: $height)) { | |
@content; | |
} | |
} | |
@function fs-scale($start, $end, $min-width, $max-width, $units: 'rem') { | |
@if $start > 0 and $end > 0 and unit($start) != unit($end) { | |
@error '🔴 fs-scale() units don’t match'; | |
} | |
$slope: ($end - $start) / ($max-width - $min-width); | |
$intercept: $end - ($slope * $max-width); | |
@if (fs-strip-unit($intercept) == 0) { | |
@return $slope * 100vw; | |
} | |
@else { | |
@if $units == 'em' { | |
@return calc(#{$slope * 100vw} + #{fs-em($intercept)}); | |
} | |
@else { | |
@return calc(#{$slope * 100vw} + #{fs-rem($intercept)}); | |
} | |
} | |
} | |
/// Scale a value for any number of properites relative to the viewport width | |
/// @group Main | |
/// @param {String | List} $properties - Properties to scale | |
/// @param {Number} $start - Starting value | |
/// @param {String} $units - Output units | |
/// @require {function} fs-rem | |
/// @require {function} fs-scale | |
/// @require {mixin} fs-min-width | |
/// @require {mixin} fs-max-width | |
/// @ignore Demo https://www.sassmeister.com/gist/9f87f8c19e91c811831d84fc8484ed24 | |
/// @link http://www.sassmeister.com/gist/7f22e44ace49b5124eec | |
/// @link http://madebymike.com.au/writing/precise-control-responsive-typography/ | |
/// @link https://zellwk.com/blog/viewport-based-typography/ | |
/// @link http://codepen.io/indrekpaas/pen/VarLaJ?editors=1100 | |
/// @link http://codepen.io/maranomynet/pen/ozNpXV?editors=1100 | |
/// @link https://www.smashingmagazine.com/2016/05/fluid-typography/ | |
/// @example scss | |
/// @include fs-scale(font-size, (320px:18px, 768px:26px, 1024px:38px); | |
/// @example scss | |
/// @include fs-scale(margin-bottom margin-top, (320px:18px, 768px:26px, 1024px:38px)); | |
@mixin fs-scale-poly($properties, $map, $units: 'rem') { | |
$length: length($map); | |
@if ($length < 2) { | |
@error "fs-scale() requires at least two breakpoints" | |
} | |
$breakpoints: map-keys($map); | |
$values: map-values($map); | |
// Initial value | |
$start-val: nth($values, 1); | |
@each $property in $properties { | |
@if $units == 'em' { | |
#{$property}: fs-em($start-val); | |
} | |
@else { | |
#{$property}: fs-rem($start-val); | |
} | |
} | |
// Scale up with calc() at each breakpoint | |
@for $i from 1 through ($length - 1) { | |
$prev-breakpoint: nth($breakpoints, $i); | |
$new-breakpoint: nth($breakpoints, $i + 1); | |
$prev-value: nth($values, $i); | |
$new-value: nth($values, $i + 1); | |
@include fs-min-width($new-breakpoint) { | |
@each $property in $properties { | |
#{$property}: fs-scale($prev-value, $new-value, $prev-breakpoint, $new-breakpoint, $units); | |
} | |
} | |
} | |
// Final value | |
$end-val: nth($values, $length); | |
$end-breakpoint: nth($breakpoints, $length); | |
@include fs-min-width($end-breakpoint) { | |
@each $property in $properties { | |
@if $units == 'em' { | |
#{$property}: fs-em($end-val); | |
} | |
@else { | |
#{$property}: fs-rem($end-val); | |
} | |
} | |
} | |
} | |
.foo { | |
@include fs-scale-poly(font-size, (576px: 22px, 768px: 24px, 992px: 34px)); | |
} | |
.bar { | |
@include fs-scale-poly(font-size, (576px: 22px, 768px: 24px, 992px: 34px), $units: em); | |
} |
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
.foo { | |
font-size: 1.375rem; | |
} | |
@media all and (min-width: 48em) { | |
.foo { | |
font-size: calc(1.0416666667vw + 1rem); | |
} | |
} | |
@media all and (min-width: 62em) { | |
.foo { | |
font-size: calc(4.4642857143vw + -0.6428571429rem); | |
} | |
} | |
@media all and (min-width: 62em) { | |
.foo { | |
font-size: 2.125rem; | |
} | |
} | |
.bar { | |
font-size: 1.375em; | |
} | |
@media all and (min-width: 48em) { | |
.bar { | |
font-size: calc(1.0416666667vw + 1em); | |
} | |
} | |
@media all and (min-width: 62em) { | |
.bar { | |
font-size: calc(4.4642857143vw + -0.6428571429em); | |
} | |
} | |
@media all and (min-width: 62em) { | |
.bar { | |
font-size: 2.125em; | |
} | |
} |
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
{ | |
"sass": { | |
"compiler": "Ruby Sass/3.7.4", | |
"extensions": {}, | |
"syntax": "SCSS", | |
"outputStyle": "expanded" | |
}, | |
"autoprefixer": false | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment