-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathresponsive-value.scss
127 lines (115 loc) · 5.36 KB
/
responsive-value.scss
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
@use "sass:meta";
@use "sass:map";
@use "sass:list";
@use "sass:math";
$default-unit: px;
$behavior-values: (
unfixed: "not-fixed",
both: "fixed-both",
start: "fixed-start-value",
end: "fixed-end-value"
);
/**
* SCSS function responsive-value.
* It is intended to handle responsive CSS property values without using media queries
*
* @access public
* @author Javid Gulmaliyev
*
* @param {number} $start-value - The initial value of the property. Accepts only numeric values without units. Cannot be equal to $end-value.
* @param {number} $end-value - The final value of the property. Accepts only numeric values without units. Cannot be equal to $start-value.
* @param {number} $start-breakpoint - The initial breakpoint. At this breakpoint, the property value will be equal to $start-value. Accepts only positive numeric values without units. Cannot be less than or equal to $end-breakpoint.
* @param {number} $end-breakpoint - The final breakpoint. At this breakpoint, the property value will be equal to $end-value. Accepts only positive numeric values or 0 (zero) without units. Cannot be greater than or equal to $start-breakpoint.
* @param {string} $behavior - Accepts 4 values:
* - "not-fixed": The $start-value and $end-value properties are not fixed before and after breakpoints.
* - "fixed-both": The $start-value and $end-value properties are strictly fixed before and after breakpoints.
* - "fixed-start-value": At this value, $start-value is strictly fixed before $start-breakpoint. Default value.
* - "fixed-end-value": At this value, $end-value is strictly fixed after $end-breakpoint.
* @param {string} $unit - CSS unit for numeric values. Default is "px". When changing the unit, $start-value, $end-value, $start-breakpoint, and $end-breakpoint should be written in the format of the specified unit.
*
* @return {string} One of the CSS mathematical functions: min(), max(), clamp().
*
* @example
* .element {
* font-size: responsive-value(2, 1, 48, 23.4375, "fixed-both", "rem");
* padding: responsive-value(20, 10, 768, 375, "fixed-end-value", "px");
* margin-bottom: responsive-value(30, 15, 1440, 280);
* }
*
* @throw {error} If $start-value, $end-value, $start-breakpoint, or $end-breakpoint are not numeric or have units.
* @throw {error} If $start-value and $end-value are equal.
* @throw {error} If $start-breakpoint is less than or equal to zero.
* @throw {error} If $end-breakpoint is a negative number.
* @throw {error} If $start-breakpoint is less than $end-breakpoint.
* @throw {error} If $start-breakpoint is equal to $end-breakpoint.
* @throw {error} If the value of $behavior is incorrect.
*/
@function responsive-value(
$start-value,
$end-value,
$start-breakpoint,
$end-breakpoint,
$behavior: map.get($behavior-values, start),
$unit: $default-unit
) {
@each $key,
$value
in (
start-value: $start-value,
end-value: $end-value,
start-breakpoint: $start-breakpoint,
end-breakpoint: $end-breakpoint
)
{
@if meta.type-of($value) != number or math.is-unitless($value) == false {
@error "The value of $#{$key} (#{$value}) should be of type number without units";
}
}
@if $start-value == $end-value {
@error "$start-value (#{$start-value}) and $end-value (#{$end-value}) cannot be equal";
}
@if not($start-breakpoint > 0) {
@error "$start-breakpoint (#{$start-breakpoint}) cannot be equal to or less than zero";
}
@if $end-breakpoint < 0 {
@error "$end-breakpoint (#{$end-breakpoint}) cannot less than zero";
}
@if $start-breakpoint < $end-breakpoint {
@error "$end-breakpoint (#{$end-breakpoint}) cannot be greater than $start-breakpoint (#{$start-breakpoint})";
}
@if $start-breakpoint == $end-breakpoint {
@error "$end-breakpoint (#{$end-breakpoint}) cannot be equal to $start-breakpoint (#{$start-breakpoint})";
}
@if list.index(map.values($behavior-values), $behavior) == null {
@error "The value of $behavior (#{$behavior}) is incorrect. It can be \"not-fixed\", \"fixed-both\", \"fixed-start-value\", or \"fixed-end-value\"";
}
$start-value-unit: $start-value + $unit;
$end-value-unit: $end-value + $unit;
$end-breakpoint-unit: $end-breakpoint + $unit;
$value-difference: $start-value - $end-value;
$breakpoint-difference: $start-breakpoint - $end-breakpoint;
$calc: "#{$end-value-unit} + #{$value-difference} * ((100vw - #{$end-breakpoint-unit}) / #{$breakpoint-difference})";
$value: "";
@if $behavior == map.get($behavior-values, unfixed) {
$value: calc(#{$calc});
} @else {
@if $start-value > $end-value {
@if $behavior == map.get($behavior-values, both) {
$value: clamp(#{$end-value-unit}, #{$calc}, #{$start-value-unit});
} @else if $behavior == map.get($behavior-values, start) {
$value: min(#{$start-value-unit}, #{$calc});
} @else if $behavior == map.get($behavior-values, end) {
$value: max(#{$end-value-unit}, #{$calc});
}
} @else if $start-value < $end-value {
@if $behavior == map.get($behavior-values, both) {
$value: min(#{$end-value-unit}, max(#{$calc}, #{$start-value-unit}));
} @else if $behavior == map.get($behavior-values, start) {
$value: max(#{$start-value-unit}, #{$calc});
} @else if $behavior == map.get($behavior-values, end) {
$value: min(#{$end-value-unit}, #{$calc});
}
}
}
@return $value;
}