DEV Community

Cover image for 3 Tricks to Make Your Fonts Responsive
Technophile
Technophile

Posted on • Edited on

3 Tricks to Make Your Fonts Responsive

Responsive fonts…

As text plays a big role in websites, you want to make sure that it looks great for everyone no matter what device they use. And, it gets tricky as there are so many screen sizes to worry about.

Let’s first take a look at some examples of UN-responsive fonts to understand why it matters. Some developers use desktop-first approach when building websites, while others use mobile-first.

Desktop vs mobile first approach

But, sometimes, when working with desktop-first approach, the text size is often ignored, because they look normal on computers. But, when you open it on your phone, it looks like this...

Unresponsive text

I will show you 3 methods of solving this issue. I divided them into 3 levels:

  1. Easy
  2. Medium
  3. Hardcore

1. Easy - change fonts based on viewport

Let’s start with easy one.

It’s not actually easy and can get tricky if you’re new to media queries. Basically, we first declare our variables in CSS, because we can use them later in our code. Next, let’s name our variables and set values.

:root {
  --font-sm: 0.875rem;
  --font-md: 1rem;
  --font-lg: 1.25rem;
  --font-xl: 1.75rem;
  --font-2xl: 2.5rem;
  --font-3xl: 4rem;
}
Enter fullscreen mode Exit fullscreen mode

And, yes, rem is better than px. You can read it here.

Okay, we finished with our base font sizes. Let’s see how it looks. Let me set it up real quick…

body {
  font-size: var(--font-md);
}

h1 {
  font-size: var(--font-3xl);
}

h2 {
  font-size: var(--font-2xl);
}

h3 {
  font-size: var(--font-xl);
}

h4 {
  font-size: var(--font-lg);
}
Enter fullscreen mode Exit fullscreen mode

Output in browser

It’s not responsive yet. I want the text size to change when it reaches a certain viewport. Let’s say 600px. Past the value, text looks too big on phones. Thus, we use media query to change the values of our variables we set up earlier.

@media (width < 600px) {
  :root {
    --font-sm: 0.875rem;
    --font-md: 1rem;
    --font-lg: 1.25rem;
    --font-xl: 1.5rem;
    --font-2xl: 2rem;
    --font-3xl: 3rem;
  }
}
Enter fullscreen mode Exit fullscreen mode

For this time, we want the values to be smaller than original because we are working on mobile device.

Result in browser

As you can see, it rather snaps to the different value, doesn’t flow smoothly, because we set it up that way.

You can use it as a foundation for your projects, so they don’t end up looking huge overflowing text.


2. Medium - use type scale calculators

Easy, but difficult to comprehend one. You can use type calculators, like Utopia.fyi to generate the best responsive font sizes for you.

We first set the minimum and maximum font size for our base font, like paragraph. And, we have to set the type scale ratio. The calculator generates the font sizes based on these values.

Utopia type calculator

/* @link https://utopia.fyi/type/calculator?c=320,16,1.2,1240,18,1.25,5,2,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l&g=s,l,xl,12 */

:root {
  --step--2: clamp(0.6944rem, 0.6856rem + 0.0444vw, 0.72rem);
  --step--1: clamp(0.8333rem, 0.8101rem + 0.1159vw, 0.9rem);
  --step-0: clamp(1rem, 0.9565rem + 0.2174vw, 1.125rem);
  --step-1: clamp(1.2rem, 1.1283rem + 0.3587vw, 1.4063rem);
  --step-2: clamp(1.44rem, 1.3295rem + 0.5527vw, 1.7578rem);
  --step-3: clamp(1.728rem, 1.5648rem + 0.8161vw, 2.1973rem);
  --step-4: clamp(2.0736rem, 1.8395rem + 1.1704vw, 2.7466rem);
  --step-5: clamp(2.4883rem, 2.1597rem + 1.6433vw, 3.4332rem);
}
Enter fullscreen mode Exit fullscreen mode

As you can see, it uses clamp() to generate responsive font sizes. Just copy the values, and paste them into your CSS. Change the names of variables. And, you are good to go.


3. Hardcore - write your own type scale calculator

If you really want to have full control of your responsive fonts, you can build your own type scale calculator. Although I usually use Utopia.fyi for most of my projects, here’s how I would implement it without these tools.

@use "sass:math";

$font-scale: 1.25;
$font-min: 0.875rem;
$font-base: 1rem;
$font-max: 1.125rem;

$font-sizes: (
  "xs": -2,
  "sm": -1,
  "md": 0,
  "lg": 1,
  "xl": 2,
  "2xl": 3,
  "3xl": 4
);

:root {
  @each $label, $value in $font-sizes {
    $min-size: $font-min * math.pow($font-scale, $value);
    $base-size: $font-base * math.pow($font-scale, $value);
    $max-size: $font-max * math.pow($font-scale, $value);

    --font-#{$label}: clamp(
      #{$min-size},
      calc((#{$base-size} * 0.5) + 2vw),
      #{$max-size}
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

I used Sass here to automate the process. Here's the link to Codepen if you want to view it. It’s not the cleanest code in the world. If you have your own approach, please let me know in the comment.


And, there you have it! Hope you learned something new. Let me know which approach you’re going with. As always, thanks for reading, and I’ll see you in the next one! 👋

Top comments (0)