Type Scale Playground
An interactive modular type scale playground: pick a ratio or drag the slider, and every level on the page recomputes and reflows in sync with a spring animation.
npx shadcn@latest add https://webberui.com/r/type-scale-playground.jsonPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<TypeScalePlayground />
Installation
npx shadcn@latest add https://webberui.com/r/type-scale-playground.jsonOr, once registries are configured in components.json, install it as @webberui/type-scale-playground.
Usage
import { TypeScalePlayground } from "@/components/ui/type-scale-playground";
<TypeScalePlayground defaultRatio={1.25} />Controlled mode
Providing ratio puts it in controlled mode, with onRatioChange receiving the user's input:
const [ratio, setRatio] = React.useState(1.333);
<TypeScalePlayground ratio={ratio} onRatioChange={setRatio} />Custom layout
Use levels to define the demo levels from largest to smallest; each level's font size is baseSize × ratio^step:
<TypeScalePlayground
baseSize={18}
levels={[
{ key: "h1", step: 4, text: "Product headline", weight: 700, label: "H1" },
{ key: "h2", step: 2, text: "Section subhead", weight: 600, label: "H2" },
{ key: "body", step: 0, text: "Body paragraph.", label: "Body" },
{ key: "note", step: -1, text: "Footnote.", muted: true, label: "Note" },
]}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
ratio | number | — | Controlled ratio value; providing it enables controlled mode |
defaultRatio | number | 1.25 | Initial ratio in uncontrolled mode |
onRatioChange | (ratio: number) => void | — | Callback when the ratio changes (already clamped and rounded to three decimal places) |
presets | ScalePreset[] | six named ratios | List of named ratio presets |
min | number | 1.1 | Minimum ratio the slider allows |
max | number | 1.8 | Maximum ratio the slider allows |
baseSize | number | 16 | Base font size (the pixel size at step 0) |
levels | TypeLevel[] | a five-level demo layout | Custom type levels |
showControls | boolean | true | Whether to show the preset and slider control bar |
ScalePreset
| Field | Type | Description |
|---|---|---|
label | string | Display name |
value | number | Ratio value |
TypeLevel
| Field | Type | Description |
|---|---|---|
key | string | Unique key |
step | number | Step relative to the base (font size = baseSize × ratio^step) |
text | string | Sample text |
label | string | Level label (badge on the right) |
weight | number | Font weight |
tracking | string | Tracking (the CSS value for letter-spacing) |
uppercase | boolean | Whether to upper-case it |
muted | boolean | Whether to display it in the secondary colour |
How it works
- Modular type scale: every level's font size is computed as
baseSize × ratio^step. Change the ratio and all levels recompute together — the big sizes grow fast and the small ones grow slowly, so the contrast opens and closes with it. - Spring synchronization: when the ratio changes, every level's size transitions with the same set of spring parameters and naturally re-wraps and reflows as it grows, demonstrating real layout breathing.
- Two modes: leaving out
ratiois uncontrolled (internal state); passingratiois controlled, syncing external state throughonRatioChange. - Presets and slider: six common ratios are built in (Minor Third through Golden), and the slider also allows stepless adjustment between
minandmax.
Accessibility
- The ratio slider is
role="slider"witharia-valuemin/aria-valuemax/aria-valuenow/aria-valuetext, and supports arrow keys (±0.01), PageUp/PageDown (±0.1), and Home/End keyboard operation. - The presets are real
<button>s, marking the currently selected ratio witharia-pressed. - The sample text is readable content; the pixel badges on the right are hidden from assistive technology (
aria-hidden). - When the user has "reduce motion" enabled at the system level, the font sizes jump straight to their target values, the thumb does not bounce, and there is no transition animation.
Lineup Poster Section
A festival-poster lineup layout — names are grouped into rows by tier with the size stepping down each level, and hovering or clicking one promotes it to a bigger row with a shared layout animation while the rest re-justify to fill the width.
Type Specimen Stage
A variable-font showcase in the style of a foundry specimen page — a giant glyph, a weight ladder, and a size ramp — where dragging an axis slider makes the whole specimen tween and reflow in sync with Motion.