@ventureweb/fluid-css
v1.2.0
Published
A tool for generating fluid CSS variables that scale smoothly between viewport breakpoints using CSS clamp()
Readme
fluid-css
A tool for generating fluid CSS variables that scale smoothly between viewport breakpoints using CSS clamp().
Features
- Generates responsive CSS custom properties that scale fluidly between mobile and desktop
- Supports spacing and typography value pairs
- Configurable breakpoints and CSS variable prefixes
- Vite plugin for seamless integration in Vite projects
- Standalone CLI for framework-agnostic usage (Next.js, etc.)
- Watches config file for changes during development
- Works with Tailwind CSS v4
@themesyntax or standard CSS
Installation
npm install fluid-cssUsage
Vite Plugin Setup
- Add the plugin to your
vite.config.js:
import fluidCSS from 'fluid-css';
export default {
plugins: [fluidCSS()],
};- Create a
fluid-variables.config.ts(or.js) in your project root:
import { defineConfig } from 'fluid-css';
export default defineConfig({
outputPath: 'src/css/fluid-variables.css',
spacingPairs: [
[16, 20], // --spacing-fl-16-20: 16px at mobile → 20px at desktop
[24, 32],
[40, 60],
],
typographyPairs: [
[14, 16], // --text-fl-14-16: 14px at mobile → 16px at desktop
[18, 24],
[32, 48],
],
});- Import the generated CSS in your stylesheet:
@import './fluid-variables.css';CLI Usage (Framework Agnostic)
For projects without Vite (e.g., Next.js with Turbopack), use the CLI:
Create a
fluid-variables.config.ts(or.js) in your project root (same as above)Add scripts to your
package.json:
{
"scripts": {
"generate:fluid": "fluid-css",
"generate:fluid:watch": "fluid-css --watch",
"dev": "npm run generate:fluid && next dev",
"build": "npm run generate:fluid && next build"
}
}- Run the CLI:
# Generate once
npx fluid-css
# Watch for config changes
npx fluid-css --watch
# Custom config file
npx fluid-css --config ./config/fluid.config.js
# Override output path
npx fluid-css --output ./src/styles/fluid.cssCLI Options
| Option | Alias | Description |
| ----------------- | ----- | ----------------------------------- |
| --config <file> | -c | Config file path |
| --output <file> | -o | Output file path (overrides config) |
| --watch | -w | Watch config file for changes |
| --help | -h | Show help message |
| --version | -v | Show version number |
Configuration Options
| Option | Type | Default | Description |
| ----------------- | -------------------- | ---------------------------------------------------- | ------------------------------------------------------------- |
| outputPath | string | 'src/css/fluid-variables.css' | Output path for generated CSS |
| configFile | string | 'fluid-variables.config.js' | Path to config file |
| watch | boolean | true | Watch config file for changes in dev mode |
| system | object | See below | Viewport breakpoints |
| spacingPairs | [number, number][] | [] | [mobile, desktop] pairs for spacing |
| typographyPairs | [number, number][] | [] | [mobile, desktop] pairs for typography |
| prefixes | object | { spacing: 'spacing-fl-', typography: 'text-fl-' } | CSS variable prefixes |
| cssWrapper | string \| null | '@theme' | CSS wrapper (e.g., @layer, @theme, or null for :root) |
Default System Breakpoints
{
minWidth: 390, // Mobile viewport (min)
designWidth: 1600, // Desktop design viewport
maxWidth: 1920, // Maximum viewport (for extrapolation)
}Generated Output
Given the configuration above, the plugin generates:
@theme {
--spacing-fl-16-20: clamp(1rem, 0.9194rem + 0.3306vw, 1.31611875rem);
--spacing-fl-24-32: clamp(1.5rem, 1.3389rem + 0.6612vw, 2.13223125rem);
--spacing-fl-40-60: clamp(2.5rem, 2.0971rem + 1.6529vw, 4.08058125rem);
--text-fl-14-16: clamp(0.875rem, 0.8347rem + 0.1653vw, 1.03305625rem);
--text-fl-18-24: clamp(1.125rem, 1.0041rem + 0.4959vw, 1.59917rem);
--text-fl-32-48: clamp(2rem, 1.6777rem + 1.3223vw, 3.2644625rem);
}How It Works
Values scale linearly between the configured breakpoints:
- Mobile (390px): Uses the first value in the pair (minimum)
- Desktop (1600px): Uses the second value in the pair (design)
- Max (1920px): Extrapolated using the slope between min and design
The clamp() function ensures values never go below minimum or above maximum.
Programmatic API
The package also exports utility functions for standalone use:
import { clampValue, extrapolateMax, generateFluidCSS } from 'fluid-css';
// Generate a single clamp value
const value = clampValue(16, 20, {
minWidth: 390,
designWidth: 1600,
maxWidth: 1920,
});
// => "clamp(1rem, 0.9194rem + 0.3306vw, 1.31611875rem)"
// Generate full CSS string
const css = generateFluidCSS({
spacingPairs: [[16, 20]],
typographyPairs: [[14, 16]],
});Development
Testing
This project uses Vitest for testing.
# Run tests once
npm test
# Run tests in watch mode
npm run test:watch
# Generate coverage report
npm run test:coverageBuilding
# Compile TypeScript to JavaScript
npm run buildLicense
MIT
