The core of EVA CSS

Fluid scales
where breakpoints jump.

One clamp() replaces three media queries. Designs flow. Layouts breathe. Drag the sliders below.

The clamp() reveal

Drag the slider. The viewport simulator narrows. The content inside scales smoothly — no breakpoints, no jumps.

1200px

Live preview

Responsive headline

Padding, gap, type and button — all driven by one clamp() formula. Smooth across every viewport.

h3 font-size 42px
p font-size 16px
gap 12px
padding 28px
button font-size 14px
button padding 12px

Breakpoint vs fluid

Same component, two strategies. One slider drives both. Watch the left jump. Watch the right glide.

@media breakpoints
900px

Breakpoint card

Jumps at 768 / 1024 / 1440

font-size 16px
clamp() fluid
900px

Fluid card

Continuous between 320 and 1920

font-size 16px

Four size modifiers

One token, four scaling behaviors. --220 standard. --220_ reduced. --220__ extreme. --220- extended.

1200px
var(--220) 220px
var(--220_) 220px
var(--220__) 220px
var(--220-) 220px

The canonical setup

One @use. The sizes you actually use. EVA generates the rest.

SCSS input
@use 'eva-css-fluid' with (
  $sizes: (4, 8, 16, 32, 64, 128),
  $font-sizes: (14, 16, 24, 36, 52),
  $build-class: true
);
Generated variables
--16:  clamp(...);
--16_: clamp(...); /* reduced */
--16__: clamp(...); /* extreme */
--16-: clamp(...); /* extended */
--fs-24, --fs-24_, --fs-24__
Use anywhere
.card {
  padding: var(--32);
  gap: var(--16);
  font-size: var(--fs-16);
}
New in v2.2.0

One stylesheet, two fluid modes

EVA tokens can now track the viewport (vw, default) or any container (cqi) — switch a subtree on the fly, no rebuild, no second file. The fluid curve itself is unchanged: same output as before by default.

Runtime fluid unit

Every token now runs through a switchable custom property instead of a unit baked in at build time.

.card {
  container-type: inline-size;
  --eva-fluid-unit: 1cqi;
}
/* this card's tokens now track its own width, not the viewport */
Opt-in container utilities

.eva-cqi and .eva-root set container-type plus the cqi override in one class, so you never forget one half.

<div class="eva-cqi">...</div>
<div class="eva-root">...</div>
Readability floor

$min-font-size (default 0 = off) stops fluid text from shrinking below a readable size in a small container or on mobile. This floor is the mobile size, not the desktop one — 13-14px is a sane default.

@use 'eva-css-fluid' with (
  $min-font-size: 14
);
Config, either way — SCSS or JSON
@use 'eva-css-fluid' with (
  $sizes: (4, 8, 16, 24, 48),
  $font-sizes: (16, 24, 48),
  $unit-fluid: 1vw,       // fluid unit + fallback: 1vw | 1cqi
  $reference-width: 1440, // width where tokens hit their max (default 1440)
  $min-font-size: 14      // a11y floor in px (default 0 = off)
);

100% backward compatible. No --eva-fluid-unit set falls back to 1vw — same computed value as before. fluidRuntime: false reproduces the previous output byte for byte.

vw vs cqi — who tracks what?

Same slider, same frame width. Watch which card moves: the cqi card tracks its own box, the vw card stays locked to your real browser window.

vw — tracks the viewport
900px

vw

clamp(1.125rem, 5vw, 4rem) — reads the real viewport, not this frame.

font-size 16px
cqi — tracks the container
900px

cqi

clamp(1.125rem, 5cqi, 4rem) — reads this frame's own width.

font-size 16px

Drag the slider — only the cqi card scales, because it's the frame that resizes, not your browser. Now resize your actual browser window: the vw card reacts instead. Real viewport right now: 1920px.

Why this exists

Twenty years of front-end design. I sit between designers and developers — and I see the same gap every time. Designers ship Figma values that developers translate into rigid breakpoints, and the design intent gets lost between two paradigms.

EVA CSS turns every fixed Figma value into a fluid, responsive variable. The maths happens once, the result holds across every viewport, and the original visual hierarchy survives the trip from canvas to code.

For your AI assistant

The full reference fits in one file.

Every variable, modifier, and formula lives in /llms.txt. Copy it into Claude, ChatGPT, or Cursor — your assistant now knows EVA CSS by heart.

Open /llms.txt →