1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
////
/// 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);
}
|