Skip to content

Responsive typography

There are two approaches we can take to responsive typography:

  • The media query approach
  • An intrinsic approach

There isn’t a right or wrong answer, though I do lean toward the intrinsic approach, but both are quite popular.

We’ll start with this approach because it’s a little simpler.

h1 {
font-size: 2rem;
}
@media (width > 700px) {
h1 {
font-size: 3rem;
}
}

Custom properties can be updated in custom properties, so they make this very easy to do site-wide.

:root {
--fs-400: 1.125rem;
--fs-500: 1.25rem;
--fs-600: 1.325rem;
--fs-700: 1.75rem;
--fs-800: 2.5rem;
--fs-900: 3.25rem;
@media (width > 800px) {
--fs-600: 1.5rem;
--fs-700: 2.125rem;
--fs-800: 3.25rem;
--fs-900: 5rem;
}
}

See the Pen css starter by Kevin (@kevinpowell) on CodePen.

We can use viewport units to create responsive typography.

.responsive-text {
font-size: 5vi;
}

Never do this.

It seems magical, but there are several problems:

  • The font will either get way too big on large screens, or too small on small screens.
  • More importantly, users can’t zoom in or out to adjust the size of the text.

That said, there are ways that we can use them, we simply need to add an extra layer. To do that, we can use a feature we haven’t looked at yet, which is clamp().

It allows us to declare an minimum size, an ideal size, and a maximum size.

.improved-responsive-text {
font-size: clamp(1.25rem, 5vi, 2.5rem);
}

The font wants to be 5vi, but it will never be able to get smaller than 1.25rem, or larger than 2.5rem.

In that middle zone, users still can’t zoom the text in or out though, so we can add a small amount of a fixed size as well.

.better-responsive-text {
font-size: clamp(1.25rem, 5vi + .5rem, 2.5rem);
}

Doing this for a full range of typography is hard to get right.

Some options:

  • Use this for large text that has a better chance of causing overflow issues if it stays too big, and use media queries for your smaller text.
  • Use a generator like Utopia.