//// /// Harmony. /// /// Contains functions to make a design appear more harmonic. /// /// @group Harmony /// /// @access public //// @use 'sass:math'; @use './functions'; @use './responsive'; /// /// Adjust a value to a modular scale. /// /// For a more sophisticated solution, check out [modularscale-sass](https://github.com/modularscale/modularscale-sass). /// /// @link http://alistapart.com/article/more-meaningful-typography An article about modular scales by Tim Brown /// /// @param {number} $times - Number of iterations. If positive, $base will be multiplied with $ratio. If negative, $base will be divided by $ratio. /// @param {number | list} $base - Single base value or, for a multi-stranded modular scale, a list of base values /// @param {number} $ratio - Ratio /// /// @return {number} /// @function modular-scale($times, $base, $ratio) { @if type-of($base) == number { @return $base * math.pow($ratio, $times); } $main-base: nth($base, 1); $norm-bases: (); @each $b in functions.list-slice($base, 2) { @if $b > $main-base { @while $b > $main-base { $b: math.div($b, $ratio); } $b: $b * $ratio; } @else if $b < $main-base { @while $b < $main-base { $b: $b * $ratio; } } $norm-bases: append($norm-bases, $b); } $all-bases: append($norm-bases, $main-base); $all-bases: functions.quicksort($all-bases); $base-index: $times % length($all-bases) + 1; $exp: math.floor(math.div($times, length($all-bases))); @return nth($all-bases, $base-index) * math.pow($ratio, $exp); } /// /// Combine responsive properties with modular scales to achieve responsive modular scales. /// /// @param {string | list} $props - Property or list of properties to set /// @param {number} $times - Number of iterations. See modular-scale for more information. /// @param {number} $responsive-map - A map with keys = viewports and values = modular scales /// @param {bool} $fluid [true] - If enabled, property values will smoothly transition from one viewport to the next /// /// @see {function} modular-scale /// /// @example scss - Responsive font sizes between 2 viewports based on modular scales /// $ms: ( /// 320px: (1rem 2rem, 1.1), /// 640px: (1rem 2rem, 1.2) /// ); /// /// h1 { /// @include responsive-modular-scale(font-size, 3, $ms); /// } /// /// h2 { /// @include responsive-modular-scale(font-size, 2, $ms); /// } /// /// h3 { /// @include responsive-modular-scale(font-size, 1, $ms); /// } /// @mixin responsive-modular-scale($props, $times, $responsive-map, $fluid: true) { $new-map: (); @each $key, $value in $responsive-map { $new-map: map-merge( $new-map, ( $key: modular-scale($times, $value...) ) ); } @include responsive.property($props, $new-map, $fluid); }