@@ -158,18 +158,33 @@ This implementation is inspired by [Tailwind CSS’s `css-functions.js`](https:/
158158You can also implement [ Fluid Typography] ( https://www.smashingmagazine.com/2022/01/modern-fluid-typography-css-clamp/ ) as a custom function.
159159
160160``` js
161+ const inputPattern = / ^ ([+-] ? [0-9 ] * \. ? [0-9 ] + )(px| rem)$ / ;
162+
163+ function parseAsRem (input ) {
164+ const match = input .match (inputPattern);
165+
166+ if (! match) {
167+ throw new Error (` ${ input} is an invalid input.` );
168+ }
169+
170+ const [, value , unit ] = match;
171+ const divider = unit === ' px' ? 16 : 1 ;
172+
173+ return Number (value) / divider;
174+ }
175+
161176function round (n ) {
162177 return Math .round ((n + Number .EPSILON ) * 10000 ) / 10000 ;
163178}
164179
165180function fluid (
166- min ,
167- max ,
168- minBreakpoint = ' 640 ' ,
169- maxBreakpoint = ' 1536 ' ,
181+ minSize ,
182+ maxSize ,
183+ minBreakpoint = ' 40rem ' ,
184+ maxBreakpoint = ' 96rem ' ,
170185 ... rest
171186) {
172- if (! min || ! max ) {
187+ if (! minSize || ! maxSize ) {
173188 throw new Error (
174189 ' The --fluid(…) function requires at least 2 arguments, but received insufficient arguments.' ,
175190 );
@@ -183,21 +198,18 @@ function fluid(
183198 );
184199 }
185200
186- min = Number (min );
187- max = Number (max );
188- minBreakpoint = Number (minBreakpoint);
189- maxBreakpoint = Number (maxBreakpoint);
201+ minSize = parseAsRem (minSize );
202+ maxSize = parseAsRem (maxSize );
203+ minBreakpoint = parseAsRem (minBreakpoint);
204+ maxBreakpoint = parseAsRem (maxBreakpoint);
190205
191- const divider = 16 ;
192- const slope =
193- (max / divider - min / divider) /
194- (maxBreakpoint / divider - minBreakpoint / divider);
195- const intersection = - 1 * (minBreakpoint / divider) * slope + min / divider;
206+ const slope = (maxSize - minSize) / (maxBreakpoint - minBreakpoint);
207+ const intersection = - 1 * minBreakpoint * slope + minSize;
196208
197209 return ` clamp(${ [
198- ` ${ (min > max ? max : min) / divider } rem` ,
210+ ` ${ minSize > maxSize ? maxSize : minSize } rem` ,
199211 ` ${ round (intersection)} rem + ${ round (slope * 100 )} svw` ,
200- ` ${ (min > max ? min : max) / divider } rem` ,
212+ ` ${ minSize > maxSize ? minSize : maxSize } rem` ,
201213 ].join (' , ' )} )` ;
202214}
203215
@@ -216,7 +228,7 @@ Use the custom function you have defined:
216228
217229``` css
218230h1 {
219- font-size : --fluid(32 , 64 );
231+ font-size : --fluid(2 rem , 4 rem );
220232}
221233```
222234
@@ -238,13 +250,13 @@ function toPx(length) {
238250}
239251
240252function fluid (
241- min ,
242- max ,
253+ minSize ,
254+ maxSize ,
243255 minBreakpoint = ' var(--breakpoint-sm)' ,
244256 maxBreakpoint = ' var(--breakpoint-2xl)' ,
245257 ... rest
246258) {
247- if (! min || ! max ) {
259+ if (! minSize || ! maxSize ) {
248260 throw new Error (
249261 ' The --fluid(…) function requires at least 2 arguments, but received insufficient arguments.' ,
250262 );
@@ -258,14 +270,14 @@ function fluid(
258270 );
259271 }
260272
261- const t = ` ( ${ toPx ( ' 100svw ' ) } - ${ toPx (minBreakpoint) } ) / ( ${ toPx (
262- maxBreakpoint,
263- )} - ${ toPx (minBreakpoint)} )` ;
273+ const t =
274+ ` ( ${ toPx ( ' 100svw ' ) } - ${ toPx (minBreakpoint) } ) ` +
275+ ` / ( ${ toPx (maxBreakpoint )} - ${ toPx (minBreakpoint)} )` ;
264276
265277 return ` clamp(${ [
266- ` min(${ min } , ${ max } )` ,
267- ` ${ min } + (${ max } - ${ min } ) * ${ t} ` ,
268- ` max(${ min } , ${ max } )` ,
278+ ` min(${ minSize } , ${ maxSize } )` ,
279+ ` ${ minSize } + (${ maxSize } - ${ minSize } ) * ${ t} ` ,
280+ ` max(${ minSize } , ${ maxSize } )` ,
269281 ].join (' , ' )} )` ;
270282}
271283
0 commit comments