@use "sass:math"; $min-fluid-size: 25rem !default; // 400px at 16px rem size $max-fluid-size: 60rem !default; // 960px at 16px rem size $fluid-base: 1vw !default; /// Return a CSS clamp() call that interpolates between the two given values /// when the viewport width changes. This can be used for fluid type and spacing /// scales. /// /// When the current viewport has a width less than or equal to the /// (configurable) $min-fluid-size variable, the expression returned by this /// function will evaluate to $from. Similarly, sizes equal to or greater than /// $max-fluid-size will yield $to. Eveything in between will be calculated /// using linear interpolation. /// /// Set the $fluid-base variable to `1vh` to use the viewport height instead of /// its width. /// /// $from and $to must have the same unit or both be unitless. @function fluid-value($from, $to) { // Solve the following system of equations: // a * 0.01 * $min-fluid-size + b = $from // a * 0.01 * $max-fluid-size + b = $to // The constant 0.01 is for converting the vw unit to an actual percentage // factor. $fluid-factor: math.div( $from - $to, 0.01 * ($min-fluid-size - $max-fluid-size) ); // a $static-value: $from - $fluid-factor * 0.01 * $min-fluid-size; // b @return clamp(#{$from}, #{$fluid-factor}vw + #{$static-value}, #{$to}); } $lower-harmonic-ratio: 1.125 !default; $upper-harmonic-ratio: 1.25 !default; /// Calculate the value on a modular harmonic scale at a specific index /// (exponent). The result will be a fluid CSS calc() expression. /// /// Use this to quickly create an entire scale of harmonic values. Using an /// $exponent of 0 will return a fluid value that evalutes to $lower-base on /// small viewports and $upper-base on large viewports. Positive exponents make /// the fluid value larger, negative values decrease it. The module-level /// configuration variables $lower-harmonic-ratio and $upper-harmonic-ratio /// define curvature of that function (over the $exponent). /// /// Other notes from fluid-value() apply here as well. In particular, /// $lower-base and $upper-base must have the same unit. $exponent must be /// unitless. @function harmonic-value($exponent, $lower-base, $upper-base) { @return fluid-value( $lower-base * math.pow($lower-harmonic-ratio, $exponent), $upper-base * math.pow($upper-harmonic-ratio, $exponent) ); }