fluidScale()
Generate a CSS clamp() expression that scales linearly between two pixel sizes.
fluidScale() creates a CSS clamp() expression that interpolates linearly between a minimum and maximum pixel value across a viewport range.
Despite its typography-focused source description, the returned expression can be used anywhere a CSS length is appropriate.
Import
import { fluidScale } from "@genomejs/core";Signature
fluidScale(
minPx: number,
maxPx: number,
minVw?: number,
maxVw?: number,
): stringParameters
| Parameter | Type | Default | Description |
|---|---|---|---|
minPx | number | — | Minimum output size in pixels |
maxPx | number | — | Maximum output size in pixels |
minVw | number | 320 | Viewport width where interpolation begins |
maxVw | number | 1440 | Viewport width where interpolation ends |
Return value
string;The returned value is a CSS clamp() expression.
Basic example
import { fluidScale } from "@genomejs/core";
const headingSize = fluidScale(32, 64);
console.log(headingSize);The result has this shape:
clamp(
32px,
<intercept>px + <slope>vw,
64px
)Use it in CSS:
document.documentElement.style.setProperty("--heading-size", headingSize);h1 {
font-size: var(--heading-size);
}Exact custom-range example
fluidScale(16, 32, 400, 1200);Returns:
clamp(
16px,
8.0000px + 2.0000vw,
32px
)This exact output is covered by the Core tests.
Use in a Genome token
import { fluidScale, Genome } from "@genomejs/core";
const genome = new Genome({
primitives: {
headingMin: 32,
headingMax: 64,
},
tokens: {
headingSize: (dna) =>
fluidScale(Number(dna.headingMin), Number(dna.headingMax)),
},
});GenomeJS expresses:
--g-heading-size: clamp(32px, ...px + ...vw, 64px);Consume it normally:
.page-title {
font-size: var(--g-heading-size);
}Responsive spacing
The function can also create fluid spacing values:
const tokens = {
pagePadding: () => fluidScale(16, 48, 320, 1280),
};.page {
padding-inline: var(--g-page-padding);
}Responsive radius
const tokens = {
panelRadius: () => fluidScale(12, 24, 320, 1440),
};.panel {
border-radius: var(--g-panel-radius);
}Use fluid values only where continuous interpolation benefits the interface. Not every token needs to change with viewport width.
How the expression is calculated
The utility calculates a straight line:
value = slope × viewport + interceptWhere:
const slope = (maxPx - minPx) / (maxVw - minVw);And:
const intercept = minPx - slope * minVw;It then returns:
clamp(
minPx,
intercept + slope-in-vw,
maxPx
)The middle expression equals minPx at minVw and maxPx at maxVw, subject to the four-decimal string rounding used in the generated expression.
Defaults
These calls are equivalent:
fluidScale(16, 32);fluidScale(16, 32, 320, 1440);Input requirements
Use a viewport range where:
maxVw > minVwAnd, for ordinary increasing scales:
maxPx >= minPxThe current implementation does not validate these relationships.
Equal viewport bounds
Avoid:
fluidScale(16, 32, 640, 640);The calculation divides by:
maxVw - minVw;Equal viewport bounds produce invalid numeric output.
Reversed ranges
This is accepted by JavaScript:
fluidScale(32, 16, 320, 1440);But the resulting clamp() bounds may not behave as intended because CSS expects the first argument to act as the lower bound and the last as the upper bound.
Validate configuration before generation.
function createFluidScale(
minPx: number,
maxPx: number,
minVw: number,
maxVw: number,
): string {
if (maxPx < minPx) {
throw new Error("maxPx must be at least minPx.");
}
if (maxVw <= minVw) {
throw new Error("maxVw must be greater than minVw.");
}
return fluidScale(minPx, maxPx, minVw, maxVw);
}Pixel-only output
The utility accepts numeric pixel values and generates px and vw units.
It does not currently generate:
remem- Container-query units
- Percentages
- Custom unit combinations
For rem-based systems, either convert values before calling the function or implement a project-specific helper.
Error behavior
fluidScale() does not currently throw dedicated errors for:
- Equal viewport bounds
- Reversed viewport bounds
- Reversed size bounds
- Non-finite values
- Negative values
Validate dynamic or user-provided input before calling it.
Notes
- The default viewport range is
320pxto1440px. - The return value is a CSS
clamp()string. - The preferred expression uses
px + vw. - Numeric coefficients are formatted to four decimal places.
- It can generate typography, spacing, or other CSS lengths.
- Input relationships are not validated automatically.
- It does not require a Genome instance.