If your text is hard to read on a phone, people leave. I’d keep it simple: start body text at 16px on mobile, move to 18px on desktop, use rem units, and control heading growth with two breakpoints – 768px and 1,024px – or clamp().
Here’s the short version:
- I set
html { font-size: 100%; }so type follows browser settings - I use
remfor body text, headings, buttons, and small text - I keep a small scale, like 1.2 to 1.25, for most small business pages
- I keep body line-height around 1.5 to 1.7
- I aim for 45 to 75 characters per line
- I test at 200% zoom because WCAG covers text resizing
- I check body text contrast at 4.5:1 or more
One quick stat matters here: users must be able to resize text up to 200% without losing use of the page. That alone is a good reason to skip fixed px systems for most page text.
In plain terms, I’d use a small mobile-first type system, let it grow with clear limits, and write the rules down so every page stays easy to read.

Responsive Typography System: 4-Step Setup Guide
Simple solutions to responsive typography
sbb-itb-fd64e4e
Step 1: Set a Mobile-First Base Size in rem
Set the root size once, and let every rem value scale from the browser default: html { font-size: 100%; }. That base becomes the reference point for headings, buttons, captions, and everything in between.
Use rem because it respects user font-size settings and zoom. That matters for accessibility. WCAG 1.4.4 requires text to stay readable and usable when resized up to 200%.
Pick a Base Size That Works on Real Phones
For many small business sites, 16px is a solid starting point. If your typeface has a small x-height, or if your audience includes older users or people with visual impairments, 17px or 18px can make text easier to read without forcing you to redo the rest of the scale.
Test on a real phone, not just a browser emulator. Screen quality, size, and viewing distance all affect legibility. Check the page at 200% zoom too, so you can see whether the layout still holds up and the text stays easy to read.
Keep Supporting Text Near Body Size
Secondary text – like form labels, captions, and fine print – should stay within one or two steps of your body size. A good floor is 12px (0.75rem), with 13px or 14px often working well for supporting content.
Keeping labels, captions, and fine print close to body text helps preserve a clear reading order on mobile. If that text gets too small, people start missing details. And on a phone, that happens fast.
| Element | Size | rem Value | Notes |
|---|---|---|---|
| Body text | 16px | 1rem | Primary reading content |
| Form labels | 14px | 0.875rem | One step down from body |
| Captions | 14px | 0.875rem | Keep legible on mobile |
| Fine print / disclosures | 12–13px | 0.75–0.8125rem | Minimum floor for readability |
With the base fixed, assign the rest of the scale by content priority.
Step 2: Build a Type Scale Around Content Priorities
A type scale uses one ratio so your text sizes stay related. Once you set that scale, give each element a clear job instead of choosing sizes on the fly. For most SMB sites, stick with restrained ratios: use 1.2 for dense content, 1.25 for most SMB sites, and 1.333 for bold marketing pages.
Assign Sizes to H1, H2, Body, Buttons, and Captions
With a 16px root base, here’s a mobile-first scale you can use as a starting point:
| Element | Size (rem) | Size (px) | Role/Priority |
|---|---|---|---|
| H1 | 2rem–3rem | 32px–48px | Primary page title |
| H2 | 1.5rem–2.25rem | 24px–36px | Major section heading |
| Body | 1rem–1.125rem | 16px–18px | Primary reading content |
| Button | 1rem | 16px | Call to action |
| Caption | 0.875rem | 14px | Ancillary text, labels, or small notes |
This setup keeps body text and buttons easy to read, while headings stand out enough to show hierarchy.
Match the Scale to Your Content Density
Use one ratio for each page type – not for the whole site. A blog post or service page usually works better with a gentler 1.2 scale. A marketing landing page or portfolio can push a bit more with 1.333.
Support Readability with Line Height and Line Length
Size alone won’t do the job. Spacing has to support it.
For body text, use a line height of 1.5 to 1.7 so each line has room to breathe. For large headings, tighten that to 1.1 to 1.3 so wrapped lines still feel connected.
Line length matters too. Aim for 45 to 75 characters per line, and use max-width: 65ch to keep paragraphs readable.
Next, apply the scale at breakpoints and use clamp() to keep growth controlled.
Step 3: Add Breakpoints and clamp() Without Overcomplicating CSS
Now take your mobile type scale and let it grow on larger screens – without changing the whole system. The idea is simple: use breakpoints to increase type only when the layout has more space. You don’t need a new scale for every screen width. Just bump it up at a few key points.
Scale Type Up at Tablet and Desktop Breakpoints
Apply type changes at 768px for tablet and 1,024px for desktop. At those widths, increase the root font size a bit. Keep line-height unitless so it grows with the font size instead of staying stuck at one value.
The easiest way to do that is by changing the html font size at each breakpoint. One small rule at the root level can scale the whole type system.
Use clamp() to Control Minimum, Fluid, and Maximum Sizes
clamp() uses three values: a minimum, a preferred value – often tied to the viewport – and a maximum. The browser uses the preferred value unless it goes below the minimum or above the maximum. For example, font-size: clamp(2rem, 5vw, 4rem) keeps an H1 between 32px and 64px while letting it scale smoothly in between.
A common pattern is to use rem for the minimum and maximum, then a viewport-based value for the middle, like clamp(2rem, calc(1rem + 1vw), 4rem).
Choose a Scaling Method
There isn’t one right answer here. It depends on how much control you want and how fluid you want the type to feel.
| Method | Best for | Trade-off |
|---|---|---|
| Breakpoints + rem | Predictable control at set widths | Sudden jumps between breakpoints |
| clamp() only | Smooth scaling with fewer media queries | More math; can scale too much on very wide screens |
| Hybrid | Fluid headings with steady body text | You have to manage two type rules |
Once you pick a method, test it on actual pages and write down the rules so the system stays easy to use.
Step 4: Test, Document, and Keep the System Consistent
Once your type scale is set, the last job is simple: make sure it holds up on actual devices and stays the same as the site grows.
Run a Short Accessibility and Device Check
Open browser DevTools and switch through common phone, tablet, and desktop viewports in both portrait and landscape. Look for awkward heading wraps, body text that feels too small, and lines that stretch too far across the screen. Paragraphs should still land in the 45-75 characters-per-line range. Zoom to 200% and run a Lighthouse accessibility audit to catch text-size and contrast issues. Also confirm that body text meets a 4.5:1 contrast ratio.
If the type passes those checks, write the rules down so the same sizes ship everywhere.
Write Down Base Sizes, Scale Rules, and Limits
Record the root font size, rem values, breakpoints, and clamp() limits in a short style guide. Add line-height rules for headings and body text. That helps stop one-off font choices when new pages get added and makes the scale easy to reuse across the site.
Conclusion: Keep It Simple, Readable, and Repeatable
Once the system is documented, you can use it across the site without making up new sizes page by page.
- Start mobile-first with a solid
rembase set to your chosen body size. - Build a small scale around content priorities, with each heading, button, and caption assigned a clear role.
- Control growth with breakpoints or
clamp()so type scales within set limits. - Write the rules down so the system stays consistent as the site grows.
FAQs
How do I choose between breakpoints and clamp()?
Use breakpoints when you need exact control at set device widths or when you have to match mockups that shift a lot across mobile, tablet, and desktop.
Use clamp() for fluid typography that scales smoothly across screen sizes. In many current layouts, teams use both: media queries with rem units for the base type scale, then clamp() for headings or display text.
When should I use 17px or 18px body text instead of 16px?
Use 17px or 18px body text instead of 16px when readability comes first – especially for senior audiences, people with mild vision issues, or mobile readers.
If you bump up body text size, adjust line height too. A good range is 26px to 36px. That extra space helps the content stay clear, easy to scan, and polished.
How can I tell if my type scale is too large or too small?
Test it under real conditions. On mobile, body text should be at least 16px. On desktop, aim for about 16-20px.
Users should also be able to resize text to 200% without breaking the layout or losing function.
If you use fluid units, set min and max limits. That keeps text from shrinking too much on narrow screens or getting oversized on wide ones.
A simple gut check helps here:
If you need to squint or zoom on a bright phone, it’s too small.