Generate mathematical, fluid CSS typography and spacing tokens. No breakpoints, just rhythm.
cssdesign-systemtypographyfluid-design
typescript 2 0 2 4 files
README.md
fluid-tokens 💧
Fluid typography and spacing for the modern web. Linear interpolation made easy.
Stop using breakpoints for font-size. Start using math.
Features
- Linear Interpolation: Smoothly scales between min and max viewport sizes.
- Accessibility First: Defaults to
remunits. - Scale Generator: Create modular scales (Major Third, Perfect Fourth, etc.) that fluidly adapt.
- CSS Generator: Export directly to CSS variables.
- TypeScript Generator: Export type-safe token objects and definitions.
Usage
Basic clamp()
import { fluid } from 'fluid-tokens';
// "I want 16px at 320px view, and 24px at 1200px view"
const fontSize = fluid({
minSize: 16,
maxSize: 24,
minView: 320, // optional, default
maxView: 1200 // optional, default
});
// Output: clamp(1rem, 0.8182rem + 0.9091vw, 1.5rem)
Fluid Modular Scales
Why settle for one size when you can have a whole harmony?
import { generateFluidScale, toCssVariables } from 'fluid-tokens';
const typeScale = generateFluidScale({
baseMin: 16,
baseMax: 18,
ratioMin: 1.2, // Minor Third on mobile
ratioMax: 1.25, // Major Third on desktop
steps: [-1, 0, 1, 2, 3, 4]
});
const css = toCssVariables(typeScale, 'font');
console.log(css);
Output:
:root {
--font-down-1: clamp(0.8333rem, ...);
--font-base: clamp(1rem, ...);
--font-up-1: clamp(1.2rem, ...);
--font-up-2: clamp(1.44rem, ...);
...
}
Type-Safe Tokens 🛡️
Don't use magic strings. Generate TypeScript definitions from your tokens.
import { toTypeScript } from 'fluid-tokens';
const ts = toTypeScript(typeScale, 'FontSize');
console.log(ts);
Output:
export const FontSize = {
Down1: "var(--font-down-1)",
Base: "var(--font-base)",
Up1: "var(--font-up-1)",
// ...
} as const;
export type FontSize = typeof FontSize[keyof typeof FontSize];
Now you can use FontSize.Base in your CSS-in-JS or style objects, and it's fully typed.
Philosophy
Design isn't static. Your tokens shouldn't be either.