I spent fifteen years working around the same problem. A piece of text, a margin, a grid: three values that should grow with the screen, and no tool to do it cleanly. We called it responsive. In reality, we were stacking steps, and we had ended up finding that normal.

The age of hacks

Making a size truly fluid was a matter of tinkering. Cascading media queries, one step every two hundred pixels, text that jumped from one stair to the next. JavaScript listening for resize events and recomputing everything on the fly, with all the fragility that implies. Hand-rolled tricks in rem and calc(), right on one page, wrong three screens further on. I practised all three, sometimes in the same project.

The problem was not the idea. We had dreamed of fluid for a long time. The problem was the tooling: CSS did not know how to interpolate.

What CSS eventually learned

clamp(), min(), max() landed everywhere. Then container queries and their cqw units, which make a component answer to its container rather than to the window. CSS can finally compute a continuous size, without JavaScript, without steps. clamp(min, ideal value, max) bounds a value between a floor and a ceiling, and lets the middle vary on its own.

The formula

Making a size fluid means drawing a straight line between two points: a minimum size at a given screen width, a maximum size at another. A line equation, y = ax + b:

slope     = (sizeMax − sizeMin) / (widthMax − widthMin)
intercept = sizeMin − slope × widthMin
size      = clamp(sizeMin, intercept + slope × 100vw, sizeMax)

At the minimum width, you get exactly sizeMin. At the maximum width, exactly sizeMax. Between the two, the interpolation is continuous. That is the basis of every modern fluid generator.

The curve of a size in clamp() A size plotted against screen width. On the left it stays flat at sizeMin, in the middle it rises in a straight line between widthMin and widthMax, on the right it stays flat at sizeMax. ONE DECLARATION, THREE REGIMES FLOOR THE SLOPE, IN VW CEILING sizeMin sizeMax widthMin widthMax
No steps: the size never jumps anywhere, it simply stops growing.

Why EVA does not stop there

Anyone can write that formula, and so much the better. The trap is elsewhere. By hand, you copy it for every size, every margin, every heading level. Twenty values, twenty clamp(), twenty chances to get it wrong. I have lived it: by the end of a project, the scale had drifted and nothing really agreed with anything else.

EVA CSS settles that point first: a single source of truth for all sizing. You declare the intent, a scale, a rhythm, bounds, and the framework generates the clamp(). The harmony holds from end to end, from the smallest screen to the largest.

There is a second point, quieter. The line in clamp() is linear: between the two bounds, the size grows at constant speed. It is mechanical. EVA introduces an easing curve into the resize. Instead of a straight ramp, the transition speeds up or slows down depending on the screen range, like a well-tuned animation. Going from small to large format no longer feels like a slider being pushed, but like a movement that breathes.

The straight ramp and the curve Two paths from the same point to the same point. The first is a straight line at constant slope. The second starts more gently, speeds up in the middle and slows down before arriving. SAME BOUNDS, TWO PATHS clamp(): the slope never changes EVA: the slope speeds up, then slows
Both pass through exactly the same bounds. Only the journey differs, and that is what you feel on resize.

That, I think, is the whole difference between artisanal fluid work and a fluid system.

Fluid, not responsive

The old dream was not to have three versions of a site. It was to have one, that adapts without ever breaking. CSS finally allows it. EVA turns it into a method, and fifteen years of workarounds quietly reach their conclusion.