responsive-scale-mixins 2.1.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +54 -3
  2. package/index.scss +94 -102
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -50,7 +50,7 @@ Imagine building a beautiful UI in Figma, then seeing it perfectly scale on **ev
50
50
 
51
51
  Works with React, Vue, Angular, Svelte, Next.js, Nuxt, Astro, and vanilla CSS. Your favorite framework + perfect responsive design = ❤️
52
52
 
53
- ## 🚀 v2.1.0 - Universal Browser Compatibility (No Breaking Changes)
53
+ ## 🚀 v2.2.1 - Universal Browser Compatibility (No Breaking Changes)
54
54
 
55
55
  **Automatic fallback generation for browsers without CSS variable support!**
56
56
 
@@ -86,10 +86,15 @@ Works with React, Vue, Angular, Svelte, Next.js, Nuxt, Astro, and vanilla CSS. Y
86
86
  font-size: calc(100vw / 1920 * 48px);
87
87
  }
88
88
 
89
- // v2.1.0 output (works everywhere!)
89
+ // v2.2.1 output (works everywhere!)
90
90
  .hero-title {
91
91
  font-size: 48px; /* Fallback for old browsers */
92
- font-size: calc(100vw / 1920 * 48px); /* Modern responsive scaling */
92
+ }
93
+
94
+ @supports (font-size: calc(100vw / 1920px * 48px)) {
95
+ .hero-title {
96
+ font-size: calc(100vw / 1920px * 48px); /* Modern responsive scaling */
97
+ }
93
98
  }
94
99
  ```
95
100
 
@@ -122,6 +127,8 @@ Works with React, Vue, Angular, Svelte, Next.js, Nuxt, Astro, and vanilla CSS. Y
122
127
  }
123
128
  ```
124
129
 
130
+ > Note: Setting the last argument to `false` disables fallback output globally for all `rsm.responsive-scale()` calls. Individual declarations can still override this behavior by passing the `$enable-fallback` parameter explicitly.
131
+
125
132
  ### **📊 Performance Impact**
126
133
 
127
134
  - **CSS size increase**: <1 KB (after GZip) on typical sites
@@ -186,6 +193,9 @@ npm update responsive-scale-mixins
186
193
  /* OLD (v1.x) */
187
194
  font-size: calc(var(--computed-scale-factor-px) * 40);
188
195
 
196
+ /* NEW (v2.0+) */
197
+ font-size: calc(var(--computed-scale-factor) * 40px);
198
+
189
199
  @include rsm.responsive-scale(font-size, 24, 16);
190
200
  ```
191
201
 
@@ -272,6 +282,38 @@ pnpm add responsive-scale-mixins
272
282
  // Import in app/layout.tsx: import './globals.scss'
273
283
  ```
274
284
 
285
+ ### Regression Test
286
+
287
+ To confirm the fix before publishing, run the local regression case included in `test/regression.scss`.
288
+
289
+ ```bash
290
+ cd test
291
+ ./test.sh
292
+ ```
293
+
294
+ If the build succeeds, verify that `test/regression.css` was generated and contains valid modern expressions such as:
295
+
296
+ ```css
297
+ padding: calc(
298
+ var(--computed-tablet-scale-factor) *
299
+ (5px + var(--tablet-proportion-scale-factor) * (10px - 5px))
300
+ )
301
+ calc(
302
+ var(--computed-tablet-scale-factor) *
303
+ (10px + var(--tablet-proportion-scale-factor) * (20px - 10px))
304
+ );
305
+ ```
306
+
307
+ Then verify the `@supports` output for the single-value case in `test.css` matches the corrected form:
308
+
309
+ ```css
310
+ @supports (margin: calc(100vw / 1920px * 10px)) {
311
+ .bar {
312
+ margin: calc(100vw / 1920px * 10px);
313
+ }
314
+ }
315
+ ```
316
+
275
317
  #### Next.js (Pages Router)
276
318
 
277
319
  ```scss
@@ -1042,6 +1084,15 @@ The library includes a comprehensive test suite located in the `test/` directory
1042
1084
  cd test && ./test.sh
1043
1085
  ```
1044
1086
 
1087
+ If `./test.sh` fails because `sass` is not installed globally, run this instead from the repository root:
1088
+
1089
+ ```bash
1090
+ npx --yes sass test/test.scss test/test.css
1091
+ start test/test.html
1092
+ ```
1093
+
1094
+ On Windows, you can also open `test/test.html` manually after compiling.
1095
+
1045
1096
  See [`test/TEST_README.md`](test/TEST_README.md) for detailed testing instructions.
1046
1097
 
1047
1098
  <!-- ## � Linking NPM Package to GitHub Packages
package/index.scss CHANGED
@@ -1,17 +1,23 @@
1
- // Responsive Scale Mixins v2.1.0
1
+ // Responsive Scale Mixins v2.2.1
2
2
  // A powerful SCSS mixin system for creating perfectly responsive designs
3
3
  // with universal browser compatibility and static fallbacks
4
4
  // Single-file distribution for maximum compatibility
5
5
 
6
+ @use "sass:math";
6
7
  @use "sass:string";
7
8
  @use "sass:meta";
8
9
  @use "sass:list";
9
10
 
11
+ $rsm-fallback-enabled: true !default;
12
+ $rsm-desktop-width: 1920px !default;
13
+ $rsm-tablet-width: 768px !default;
14
+ $rsm-mobile-width: 390px !default;
15
+
10
16
  /* Responsive Scale Variables Mixin
11
17
  * Include this mixin in your root element to define the scaling factors.
12
18
  * Adjust the design widths to match your design system breakpoints.
13
19
  *
14
- * v2.1.0: Now includes fallback generation for browsers without CSS variable support
20
+ * v2.2.0: Now includes fallback generation for browsers without CSS variable support
15
21
  */
16
22
 
17
23
  @mixin responsive-scale-variables(
@@ -20,94 +26,81 @@
20
26
  $mobile-width: 390px,
21
27
  $enable-fallback: true
22
28
  ) {
29
+ $rsm-fallback-enabled: $enable-fallback !global;
30
+ $rsm-desktop-width: $desktop-width !global;
31
+ $rsm-tablet-width: $tablet-width !global;
32
+ $rsm-mobile-width: $mobile-width !global;
23
33
  // Design widths for direct calc expressions
24
34
  --desktop-width: #{$desktop-width};
25
35
  --tablet-width: #{$tablet-width};
26
36
  --mobile-width: #{$mobile-width};
27
37
 
28
38
  // Desktop scale factor (generic - unit is appended in calc expressions)
29
- --computed-scale-factor: calc(100vw / #{$desktop-width});
39
+ --computed-scale-factor: (100vw / #{$desktop-width});
30
40
 
31
41
  // Tablet scale factor (generic - unit is appended in calc expressions)
32
- --computed-tablet-scale-factor: calc(100vw / #{$tablet-width});
42
+ --computed-tablet-scale-factor: (100vw / #{$tablet-width});
33
43
 
34
44
  // Mobile scale factor (generic - unit is appended in calc expressions)
35
- --computed-mobile-scale-factor: calc(100vw / #{$mobile-width});
45
+ --computed-mobile-scale-factor: (100vw / #{$mobile-width});
36
46
 
37
47
  // Tablet proportion scale factor for interpolation between mobile and desktop values
38
- --tablet-proportion-scale-factor: calc(
48
+ --tablet-proportion-scale-factor: (
39
49
  (100vw - #{$mobile-width}) / (#{$desktop-width} - #{$mobile-width})
40
50
  );
41
51
 
42
- // v2.1.0: Store original design widths as strings for fallback calculation
52
+ // v2.2.0: Store original design widths as strings for fallback calculation
43
53
  --rsm-desktop-width-value: #{strip-units($desktop-width)};
44
54
  --rsm-tablet-width-value: #{strip-units($tablet-width)};
45
55
  --rsm-mobile-width-value: #{strip-units($mobile-width)};
46
- --rsm-fallback-enabled: 1;
56
+ --rsm-fallback-enabled: #{if(sass($enable-fallback): 1; else: 0)};
47
57
  }
48
58
 
49
59
  /* Utility function to strip units from values */
50
60
  @function strip-units($value) {
51
- @return $value / ($value * 0 + 1);
61
+ @return math.div($value, $value * 0 + 1);
52
62
  }
53
63
 
54
64
  /* Responsive Scale Mixins
55
65
  * Core scaling functionality with support for all CSS units
56
- * v2.1.0: Generates both modern calc() AND static fallback values
66
+ * v2.2.0: Generates both modern calc() AND static fallback values
57
67
  */
58
68
 
59
- @function scaled-value($val, $scale-var, $unit: px) {
60
- @if $scale-var == "--computed-scale-factor" {
61
- @return calc(100vw / var(--desktop-width) * #{$val}#{$unit});
62
- } @else if $scale-var == "--computed-tablet-scale-factor" {
63
- @return calc(100vw / var(--tablet-width) * #{$val}#{$unit});
64
- } @else if $scale-var == "--computed-mobile-scale-factor" {
65
- @return calc(100vw / var(--mobile-width) * #{$val}#{$unit});
66
- } @else {
67
- @return calc(var(#{$scale-var}) * #{$val}#{$unit});
68
- }
69
+ @function scaled-value($val, $width, $unit: px) {
70
+ @return calc((100vw / #{$width}) * #{$val}#{$unit});
69
71
  }
70
72
 
71
- /* v2.1.0: Calculate static fallback values for unsupported browsers
72
- * These values are computed at compile time, not runtime
73
- */
74
- @function fallback-value($val, $breakpoint: "desktop", $unit: px) {
75
- // Default device widths for fallback calculation
76
- $default-desktop: 1920;
77
- $default-tablet: 768;
78
- $default-mobile: 390;
79
-
80
- @if $breakpoint == "desktop" {
81
- $fallback: calc($val);
82
- @return $fallback#{$unit};
83
- } @else if $breakpoint == "tablet" {
84
- // Use middle breakpoint for tablet fallback
85
- $fallback: calc($val);
86
- @return $fallback#{$unit};
87
- } @else if $breakpoint == "mobile" {
88
- $fallback: calc($val);
89
- @return $fallback#{$unit};
90
- }
73
+ @function tablet-interpolation($desktop-value, $mobile-value, $unit) {
74
+ @return calc(
75
+ (100vw / #{$rsm-tablet-width}) *
76
+ (
77
+ #{$mobile-value}#{$unit} +
78
+ (
79
+ (100vw - #{$rsm-mobile-width}) /
80
+ (#{$rsm-desktop-width} - #{$rsm-mobile-width})
81
+ ) *
82
+ (#{$desktop-value}#{$unit} - #{$mobile-value}#{$unit})
83
+ )
84
+ );
85
+ }
91
86
 
92
- @return $val#{$unit};
87
+ @function mobile-scale-expression($mobile-value, $unit) {
88
+ @return calc((100vw / #{$rsm-mobile-width}) * #{$mobile-value}#{$unit});
93
89
  }
94
90
 
95
91
  @function get-scale-factor($unit) {
96
- // Use generic scale factor - unit is appended in calc expressions
97
92
  @return string.unquote("--computed-scale-factor");
98
93
  }
99
94
 
100
95
  @function get-tablet-scale-factor($unit) {
101
- // Use generic scale factor - unit is appended in calc expressions
102
96
  @return string.unquote("--computed-tablet-scale-factor");
103
97
  }
104
98
 
105
99
  @function get-mobile-scale-factor($unit) {
106
- // Use generic scale factor - unit is appended in calc expressions
107
100
  @return string.unquote("--computed-mobile-scale-factor");
108
101
  }
109
102
 
110
- /* v2.1.0: Main responsive scale mixin with fallback support
103
+ /* v2.2.0: Main responsive scale mixin with fallback support
111
104
  * Generates two CSS declarations:
112
105
  * 1. Static fallback value for unsupported browsers
113
106
  * 2. Modern calc() expression for modern browsers
@@ -121,34 +114,32 @@
121
114
  $desktop-relative: null,
122
115
  $mobile-relative: null,
123
116
  $important: null,
124
- $enable-fallback: true
117
+ $enable-fallback: null
125
118
  ) {
126
- $scale-factor: get-scale-factor($unit);
119
+ @if $enable-fallback == null {
120
+ $enable-fallback: $rsm-fallback-enabled;
121
+ }
127
122
 
128
123
  // If it's a percentage-based value (like letter-spacing), scale it based on the relative property
129
124
  @if $is-percentage == true {
130
125
  @if $desktop-relative != null {
131
- // v2.1.0: Output fallback value first
132
126
  @if $enable-fallback {
133
- $fallback-calc: calc(#{$desktop-value} / 100 * #{$desktop-relative});
134
- #{$property}: #{$fallback-calc}#{$unit}#{$important};
127
+ $desktop-fallback: calc(#{$desktop-value} / 100 * #{$desktop-relative});
128
+ #{$property}: #{$desktop-fallback}#{$unit}#{$important};
135
129
  }
136
130
 
137
- // Modern calc expression (overrides fallback in modern browsers)
138
- $calc-value: calc(
139
- #{$desktop-value} /
140
- 100 *
141
- (var(#{$scale-factor}) * #{$desktop-relative}#{$unit})
131
+ $modern-desktop: calc(
132
+ #{$desktop-value} / 100 * #{$desktop-relative}#{$unit}
142
133
  );
143
- #{$property}: #{$calc-value}#{$important};
134
+ @supports (#{$property}: #{$modern-desktop}) {
135
+ #{$property}: #{$modern-desktop}#{$important};
136
+ }
144
137
  }
145
138
 
146
139
  @media screen and (min-width: 768px) and (max-width: 991px) {
147
- $tablet-scale-factor: get-tablet-scale-factor($unit);
148
140
  @if $desktop-relative != null and $mobile-relative != null {
149
- // v2.1.0: Fallback for tablet
150
141
  @if $enable-fallback {
151
- $fallback-tablet: calc(
142
+ $tablet-fallback: calc(
152
143
  #{$mobile-value} /
153
144
  100 *
154
145
  (
@@ -157,48 +148,46 @@
157
148
  (#{$desktop-relative}#{$unit} - #{$mobile-relative}#{$unit})
158
149
  )
159
150
  );
160
- #{$property}: #{$fallback-tablet}#{$important};
151
+ #{$property}: #{$tablet-fallback}#{$important};
161
152
  }
162
153
 
163
- // Modern expression
164
- $calc-value: calc(
154
+ $modern-tablet: calc(
165
155
  #{$mobile-value} /
166
156
  100 *
167
157
  (
168
- var(#{$tablet-scale-factor}) *
158
+ #{$mobile-relative}#{$unit} +
169
159
  (
170
- #{$mobile-relative}#{$unit} +
171
- var(--tablet-proportion-scale-factor) *
172
- (#{$desktop-relative}#{$unit} - #{$mobile-relative}#{$unit})
173
- )
160
+ (100vw - #{$rsm-mobile-width}) /
161
+ (#{$rsm-desktop-width} - #{$rsm-mobile-width})
162
+ ) *
163
+ (#{$desktop-relative}#{$unit} - #{$mobile-relative}#{$unit})
174
164
  )
175
165
  );
176
- #{$property}: #{$calc-value}#{$important};
166
+ @supports (#{$property}: #{$modern-tablet}) {
167
+ #{$property}: #{$modern-tablet}#{$important};
168
+ }
177
169
  }
178
170
  }
179
171
 
180
172
  @media screen and (max-width: 767px) {
181
- $mobile-scale-factor: get-mobile-scale-factor($unit);
182
173
  @if $mobile-relative != null {
183
- // v2.1.0: Fallback for mobile
184
174
  @if $enable-fallback {
185
- $fallback-mobile: calc(#{$mobile-value} / 100 * #{$mobile-relative});
186
- #{$property}: #{$fallback-mobile}#{$unit}#{$important};
175
+ $mobile-fallback: calc(#{$mobile-value} / 100 * #{$mobile-relative});
176
+ #{$property}: #{$mobile-fallback}#{$unit}#{$important};
187
177
  }
188
178
 
189
- // Modern expression
190
- $calc-value: calc(
191
- #{$mobile-value} /
192
- 100 *
193
- (var(#{$mobile-scale-factor}) * #{$mobile-relative}#{$unit})
179
+ $modern-mobile: calc(
180
+ #{$mobile-value} / 100 * #{$mobile-relative}#{$unit}
194
181
  );
195
- #{$property}: #{$calc-value}#{$important};
182
+ @supports (#{$property}: #{$modern-mobile}) {
183
+ #{$property}: #{$modern-mobile}#{$important};
184
+ }
196
185
  }
197
186
  }
198
187
  } @else {
199
188
  // Regular absolute scaling
200
189
  @if meta.type-of($desktop-value) == list {
201
- // v2.1.0: Fallback for list values (padding: 20 40)
190
+ // v2.2.0: Fallback for list values (padding: 20 40)
202
191
  @if $enable-fallback {
203
192
  $desktop-fallback: ();
204
193
  @each $val in $desktop-value {
@@ -212,25 +201,27 @@
212
201
  @each $val in $desktop-value {
213
202
  $desktop-scaled: list.append(
214
203
  $desktop-scaled,
215
- scaled-value($val, $scale-factor, $unit)
204
+ scaled-value($val, $rsm-desktop-width, $unit)
216
205
  );
217
206
  }
218
207
  #{$property}: #{$desktop-scaled}#{$important};
219
208
  } @else {
220
- // v2.1.0: Fallback for single values
209
+ // v2.2.0: Fallback for single values
221
210
  @if $enable-fallback {
222
211
  #{$property}: #{$desktop-value}#{$unit}#{$important};
223
212
  }
224
213
 
225
- // Modern calc expression
226
- $scaled-value: scaled-value($desktop-value, $scale-factor, $unit);
227
- #{$property}: #{$scaled-value}#{$important};
214
+ // Modern calc expression (wrapped in @supports so Firefox will fallback)
215
+ $modern-desktop: scaled-value($desktop-value, $rsm-desktop-width, $unit);
216
+ @supports (#{$property}: #{$modern-desktop}) {
217
+ #{$property}: #{$modern-desktop}#{$important};
218
+ }
228
219
  }
229
220
 
230
221
  @media screen and (min-width: 768px) and (max-width: 991px) {
231
222
  $tablet-scale-factor: get-tablet-scale-factor($unit);
232
223
  @if meta.type-of($desktop-value) == list {
233
- // v2.1.0: Fallback for tablet list
224
+ // v2.2.0: Fallback for tablet list
234
225
  @if $enable-fallback {
235
226
  $tablet-fallback: ();
236
227
  @for $i from 1 through list.length($desktop-value) {
@@ -259,28 +250,27 @@
259
250
  }
260
251
  #{$property}: #{$tablet-scaled}#{$important};
261
252
  } @else {
262
- // v2.1.0: Fallback for tablet single value
253
+ // v2.2.0: Fallback for tablet single value
263
254
  @if $enable-fallback {
264
255
  #{$property}: #{$mobile-value}#{$unit}#{$important};
265
256
  }
266
257
 
267
- // Modern expression
268
- $calc-value: calc(
269
- var(#{$tablet-scale-factor}) *
270
- (
271
- #{$mobile-value}#{$unit} +
272
- var(--tablet-proportion-scale-factor) *
273
- (#{$desktop-value}#{$unit} - #{$mobile-value}#{$unit})
274
- )
258
+ // Modern expression (wrapped in @supports so Firefox will fallback)
259
+ $modern-tablet: tablet-interpolation(
260
+ $desktop-value,
261
+ $mobile-value,
262
+ $unit
275
263
  );
276
- #{$property}: #{$calc-value}#{$important};
264
+ @supports (#{$property}: #{$modern-tablet}) {
265
+ #{$property}: #{$modern-tablet}#{$important};
266
+ }
277
267
  }
278
268
  }
279
269
 
280
270
  @media screen and (max-width: 767px) {
281
271
  $mobile-scale-factor: get-mobile-scale-factor($unit);
282
272
  @if meta.type-of($mobile-value) == list {
283
- // v2.1.0: Fallback for mobile list
273
+ // v2.2.0: Fallback for mobile list
284
274
  @if $enable-fallback {
285
275
  $mobile-fallback: ();
286
276
  @each $val in $mobile-value {
@@ -294,25 +284,27 @@
294
284
  @each $val in $mobile-value {
295
285
  $mobile-scaled: list.append(
296
286
  $mobile-scaled,
297
- scaled-value($val, $mobile-scale-factor, $unit)
287
+ scaled-value($val, $rsm-mobile-width, $unit)
298
288
  );
299
289
  }
300
290
  #{$property}: #{$mobile-scaled}#{$important};
301
291
  } @else {
302
- // v2.1.0: Fallback for mobile single value
292
+ // v2.2.0: Fallback for mobile single value
303
293
  @if $enable-fallback {
304
294
  #{$property}: #{$mobile-value}#{$unit}#{$important};
305
295
  }
306
296
 
307
- // Modern expression
308
- $scaled-value: scaled-value($mobile-value, $mobile-scale-factor, $unit);
309
- #{$property}: #{$scaled-value}#{$important};
297
+ // Modern expression (wrapped in @supports so Firefox will fallback)
298
+ $modern-mobile: mobile-scale-expression($mobile-value, $unit);
299
+ @supports (#{$property}: #{$modern-mobile}) {
300
+ #{$property}: #{$modern-mobile}#{$important};
301
+ }
310
302
  }
311
303
  }
312
304
  }
313
305
  }
314
306
 
315
- /* v2.1.0: New mixin to disable fallback for specific declarations
307
+ /* v2.2.0: New mixin to disable fallback for specific declarations
316
308
  * Useful when you want only modern browsers to receive a style
317
309
  */
318
310
  @mixin responsive-scale-no-fallback(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "responsive-scale-mixins",
3
- "version": "2.1.0",
3
+ "version": "2.2.1",
4
4
  "description": "🎨 Revolutionary SCSS mixins for perfect responsive design with universal browser compatibility. Supports ALL CSS units (px, rem, em, vw, vh, %, etc.) with pixel-perfect scaling and automatic fallbacks for browsers without CSS variable support. Zero manual calculations - just flawless responsive typography, spacing, and dimensions across desktop, tablet, and mobile. Single-file distribution for maximum compatibility. Framework-agnostic, works everywhere including Firefox Mobile and old Android browsers.",
5
5
  "main": "index.scss",
6
6
  "style": "index.scss",