Why Another Fluid Sizing Tool?
Designers often hand over two templates: one for mobile and one for desktop. The gap between those two views — tablets, large screens, unusual aspect ratios — usually ends up being filled with a patchwork of media queries and breakpoints. That approach works, but it brings maintenance overhead and visible design jumps between breakpoints.
Fluid sizing calculators like Utopia or Min-Max-Calculator address the problem but fall short when a project needs more nuanced control. The typical setup doesn't handle smaller tablet views gracefully, doesn't react to very wide viewports, and has no way to respond to aspect ratio. What's missing is a single, reusable function that takes two pixel values and returns a fully responsive CSS value — a function that can synchronize type, spacing, and layout scales across an entire project.
Defining the Anchor Points
The solution starts with a clear specification of how sizes should behave across viewport widths. In a typical example:
- The body font size is
16pxat the mobile base of375px. - It grows continuously to
22pxat1024px. - It stays at
22pxup to1440px. - It then scales linearly again until
2000px. - Above
2000px, a max wrapper freezes the size.
Those viewport definitions become project-wide constants. The designer's two pixel values — minimum and optimum, in this case 16 and 22 — are the only per-property arguments needed.
The Underlying Math
Two separate clamp() ranges cover the two growth phases: a steep slope from the mobile minimum up to the first plateau, and a linear slope (m = 1) from the plateau up to the maximum wrapper point. The tricky part is combining those clamps without conflicts.
The correct combination depends on how steep the first slope is relative to the second. The Sass function checks whether slope1 is above 1. If the first slope is steeper, a nested clamp works. If it's flatter, a max() wrapper is the safer choice. That conditional branch is the core of the FabUnit logic.
When no maximum wrapper is needed — the design should scale elastically upward indefinitely — the same branching logic applies, but the upper limit becomes a formula that computes the value at the final viewport edge.
Scaling With Aspect Ratio
Mobile devices in landscape orientation present a special problem. A phone held sideways is wider than 16:9, and text that feels comfortable in portrait can feel oversized. The FabUnit handles this by swapping 100vw in the slope interpolations with a viewport factor that accounts for the aspect ratio. When the screen exceeds a 16:9 ratio, sizes scale down again instead of continuing to grow.
The Sass Implementation
The formula is packaged as a Sass function with helper utilities for rem output. Anchor points (the screen widths) and the aspect ratio are defined once as variables. The function itself takes the minimum and optimum pixel values, then internally calculates the slopes, the plateau, and the optional wrapper values before composing the final CSS expression.
Usage is intentionally simple. For the style guide example, implementing the body font size is just:
font-size: fab-unit(16, 22);
The same call serves font sizes, paddings, margins, gaps, heights, widths, and even grid column definitions. The predefined anchor points can also be overridden locally if a component needs a different responsive curve.
Practical Considerations
Testing for accessibility is still necessary. The author recommends verifying zoom behavior per case, particularly when the passed arguments differ by a large margin. For further reading on responsive type and zoom, Adrian Roselli's article on the subject is a useful reference.
The full formula and implementation are available as an npm package, with a GitHub repository, a CodeSandbox example, and a visualizer for testing values interactively.



