Typography Scale Generator
Build a modular type scale that flexes with the viewport, and export it as fluid
CSS clamp() rules, SCSS, a Tailwind config or JSON. Set a different
ratio for phone and desktop so headings stay usable at both ends.
Sizes below are live – they are set with the generated clamp(),
so resizing this window shows exactly what the scale does between
320px → 1280px.
How to use this tool
- Set the base size at each end. 16px on a phone and 18px on a desktop is a sane starting point for body text.
- Pick a ratio for each end. Use a smaller ratio for the small screen – that is the whole point of the two fields.
- Set the viewport range the scale should interpolate across. 320–1280 covers most sites.
- Judge it by eye. The preview is set with the real generated rules, so resize this window and watch it move.
- Copy the output in the format your project uses.
Why two ratios instead of one
A modular scale multiplies the base size by a ratio for each step up. With one ratio, the step that gives you a comfortable 42px h1 on a laptop gives you the same 42px on a 360px phone, where it eats half the screen. The usual fix is a stack of media queries overriding the scale you just built.
Setting a ratio at each end fixes it properly. A gentle 1.2 on the phone keeps headings close to body size where space is short; a 1.333 on the desktop opens the hierarchy up where there is room. Every step in between is interpolated, so there are no breakpoints to maintain.
Why the output is in rem, not px
A clamp() written entirely in pixels ignores the reader's browser font
size setting. Someone who has set their default to 20px because they need it gets
your 16px anyway. Expressing the bounds in rem keeps that setting
working, and it costs nothing – the arithmetic is identical.
The middle term still carries a vw component, because that is what makes
it fluid. The combination of a rem intercept and a vw slope is what lets one rule
replace a media query.
Reading the generated rule
Each line looks like clamp(2.488rem, 1.739rem + 3.744vw, 4.735rem). The
first value is the floor, reached at your small viewport. The last is the ceiling,
reached at your large one. The middle is the line between them: at any width in
between, the browser computes the intercept plus the slope and uses that.
One detail worth knowing: for steps below body size, a larger desktop ratio
makes the text shrink as the viewport grows, so the slope goes negative and the
bounds swap over. The generator orders them correctly — a
clamp() whose floor is above its ceiling silently returns the floor and
never moves at all.
Setting up web fonts to go with the scale? The @font-face generator writes the loading CSS, TTF to WOFF2 gets the files web-ready, and the font analyzer reports the metrics – cap height and x-height – that decide whether two fonts can share one scale.