/* * https://www.smashingmagazine.com/2022/12/fabunit-smart-way-control-synchronize-typo-space/ * * Specify a minimum size and an optimum size (to be shown at the "target range") */ @use "sass:math"; /* Helper functions */ $rem-base: 16px; @function strip-units($number) { @if (math.is-unitless($number)) { @return $number; } @else { @return math.div($number, $number * 0 + 1); } } @function rem($size){ @if (math.compatible($size, 1rem) and not math.is-unitless($size)) { @return $size; } @else { @return math.div(strip-units($size), strip-units($rem-base)) * 1rem; } } /* Default values fab-unit 🪄 */ $screen-min: 320; $screen-opt-start: 960; $screen-opt-end: 1440; $screen-max: 2000; // $screen-opt-end | int > $screen-opt-end | false $aspect-ratio: math.div(16, 9); // smaller values for larger aspect ratios /* Magic function fab-unit 🪄 */ @function fab-unit( $size-min, $size-opt, $screen-min: $screen-min, $screen-opt-start: $screen-opt-start, $screen-opt-end: $screen-opt-end, $screen-max: $screen-max, $aspect-ratio: $aspect-ratio ) { $screen-factor: min(100vw, 100vh * $aspect-ratio); $steep-slope: math.div(($size-opt - $size-min), ($screen-opt-start - $screen-min)) * 100 > 1; $slope1: calc(rem($size-min) + ($size-opt - $size-min) * ($screen-factor - rem($screen-min)) / ($screen-opt-start - $screen-min)); $slope2: calc($screen-factor / $screen-opt-end * $size-opt); @if $screen-max { $size-max: math.div(rem($screen-max), $screen-opt-end) * $size-opt; @if $steep-slope { @return clamp(rem($size-min), $slope1, clamp(rem($size-opt), $slope2, $size-max)); } @else { @return clamp(clamp(rem($size-min), $slope1, rem($size-opt)), $slope2, $size-max); } } @else { @if $steep-slope { @return clamp(rem($size-min), $slope1, max(rem($size-opt), $slope2)); } @else { @return max(clamp(rem($size-min), $slope1, rem($size-opt)), $slope2); } } }