Modern approach to typography

Renato Corluka
March 26, 2024

Please read end of the article before implementing any of code on your website. In the first part of the article px will be used so it is easier to follow up, final solution for font-size is based on rem units. Final solution is under Accessibility strategy and uses rem for font-size.

Typography that resonates

There are patterns that are surrounding us all the time and that are resonating with humans by law of the nature. While nature is not built on math, over the years many great scientists found the ways to describe patterns in form of mathematical expressions. And if you have ever researched any of field like music, electricity, structural engineering you would hear about term of frequency.

While I am coming from electrical engineering background, I guess more common example for people is music because you have seen someone playing musical instrument, or maybe even you have played some instrument. When we are playing instrument we are going to create multiple way series of sound waves at different frequency and if do it right (in harmony) it will sound pleasant.

Creating harmony – modular scale

We have identified need to create harmony, now we are going to do some simple math to make our waves in harmony. In creating series of number we often use some arithmetic series, but they are not the best for creating harmony.

Problem – arithmetic series

In example below we are starting with 16 and in creating each step we add 8. This will eventually lead to having too big jumps in early steps, and later jumps will become too small as

16 //step 1
24 //step 2 (16 + 8)
32 //step 3 (16 + 8 + 8)
40 //step 4 (16 + 8 + 8 + 8)
48 //step 5 (16 + 8 + 8 + 8 + 8)

//result
16, 24, 32, 40, 48,  ...

Solution – harmonic series

Instead of doing addition to each step, we could do it in much better fashion if we define ratio between out steps so all our steps will be X times bigger than last step.

For our ratio we could pick up some popular ratio in design called golden ratio to establish our harmonic series. For sake of simplicity of reading, number are rounded and golden ration is rounded to 1.62.

16 //step 1
26 //step 2 (16 * 1.6)
42 //step 3 (16 * 1.6 * 1.6)
68 //step 4 (16 * 1.6 * 1.6 * 1.6)
110 //step 5 (16 * 1.6 * 1.6 * 1.6 * 1.6)

//result
16, 26, 42, 68, 110, ...

Typography lock

We have solved problem with establishing way of creating typographic hierarchy, but we have problem because golden ration is pretty big ratio, if we start at text font-size and go h6, h5, h4, h3, h2, h1 we are going to have h2 of font-size 177px and h1 of font-size 277px. That is obviously too big and won’t work. We need to come with better plan, and there are two solutions for doing this:

Solution 1: Using smaller scale

We could use some smaller scale like Major Third – 1.250 and that would give use some nice values, but we may hierarchy distinction that we want

Solution 2: Introducing typography locks

But let’s ask ourselves question do we really use h5, and h4 often? I guess we usually don’t go this deep with heading and in case that we go, we could make them just bold which will make some distinction between headings and text. So we let’s see we are going to use lock on h6, h5 and start at h4. With this approach our h1 will be around 110px and h2 will be around 68px. That is perfect for our project and looks great on desktop-ish screens.

Responsive strategy

We have established clear typographic hierarchy, and all of them are in harmony because we are using mathematical principle and embracing modular scale. But as making website we know that what looks great on desktop will need some tweaks on smaller screens in order to look good.

Fluid Typography

We want that out typography looks good on smaller screen, we could make another set of values for tablet screens and another set of screens for mobiles and use media queries to fix our issues. While this approach may work, it is not the best way to handle this as things are getting complex. Luckily there are some CSS techniques that could help us overcome this issue like CSS locks tricks (Tim Brown reference) or we could use modern CSS approach using CSS clamp() function. Later has decent browser support in all modern browsers, so we are going to us CSS clamp() function and define our typography how it should look on dekstop-ish screen and how it should look on mobile-ish screen. For desktop-ish we have agreed on golden ration, and for mobile-ish we are going to use Major Third – 1.250.

Now we have ended up with using two scale:

MobileDesktop
1616
2026
2542
3168
39110

Making our clamps

Now we are going to need to take steps from each scale, and write them in clamp function. Note that the first is same of both, we can skip it and start at second step:

The CSS clamp() function takes three parameters: a minimum value, a preferred value, and a maximum allowed value:

Now we need to find desired value and use something like vw (CSS viewport width unit) that will scale proportionally our font-size between mobile and desktop. We are going to assume that we want stop scaling at 400px on mobile (everything below will be 20px) and at 1200px at desktop (everything above will be 26px).

h4  {  font-size: clamp(<min>,<desired>,<max>)  }

//we know min and max so we have this
h4  {  font-size: clamp(20,<desired>,26)  }

And we are ending up with something like:

h4  {  font-size:  clamp(20px, 17.913px + 0.6522vw, 26px);  }
h3  {  ...  }
h2  {  ...  }
h1  {  ...  }

Intrinsic architecture

With raising support of the container queries, modern approach to typography would be intrinsically fluid typography. Which is much smarter than regular fluid typography, because sometimes our components are limiting text width and text inside them doesn’t take full screen size. In this scenario we would like to have system in the place which will take that in account and we can enable.

@supports (font-size: 1cqi) {
  h4  {  font-size:  clamp(20px, 17.913px + 0.6522cqi, 26px); }
  h3  {  ...  }
  h2  {  ...  }
  h1  {  ...  }
}

Note that we use cqi unit instead of vw this time. So this code will run if our browser supports cqi unit. This will act like vw unit until we define container on our element. The most common case for this are going to be card layouts because they are often much smaller than screen size, and they are coming in many different sizes on our sites. Cards like own sites on our sites.

@supports (font-size: 1cqi) {
  .my_card  {
    container-type: inline-size;
  }
}

Now in every card with class of .my_card when we put some text it will adjust it’s size according to the size of that card. CSS is awesome.

Fallback strategy

We are going to make regular responsive typography as base, and if browser supports container queries we’ll override it with new values.

  h4  {  font-size:  clamp(20px, 17.913px + 0.6522vw, 26px);  }
  h3  {  ...  }
  h2  {  ...  }
  h1  {  ...  }
  
  /*If browser supports override with container query ready rules*/
@supports (font-size: 1cqi) {
  h4  {  font-size:  clamp(20px, 17.913px + 0.6522cqi, 26px);  }
  h3  {  ...  }
  h2  {  ...  }
  h1  {  ...  }
}

Re-usability strategy

Until this point we were talking about global styles for headings, but we could tokenize these values using CSS variables instead applying them directly. This way we could use these values in many places across project and control them in one place.

:root{
  --hfs-h4:  clamp(20px, 17.913px + 0.6522vw, 26px);
  --hfs-h3: clamp(25px, 19.087px + 1.8478vw, 42px);
  --hfs-h2: clamp(31px, 18.1304px + 4.0217vw, 68px);
  --hfs-h1: clamp(39px, 14.3043px + 7.7174vw, 110px);
}
  
/*If browser supports override with container query ready rules*/
@supports (font-size: 1cqi) {
  :root{
    --hfs-h4:  clamp(20px, 17.913px + 0.6522cqi, 26px);
    --hfs-h3: clamp(25px, 19.087px + 1.8478cqi, 42px);
    --hfs-h2: clamp(31px, 18.1304px + 4.0217cqi, 68px);
    --hfs-h1: clamp(39px, 14.3043px + 7.7174cqi, 110px);
  }
}

/*Set global styles*/
  h4  {  font-size: var(--hfs-h4);  }
  h3  {  font-size: var(--hfs-h3);  }
  h2  {  font-size: var(--hfs-h2);  }
  h1  {  font-size: var(--hfs-h1);  }

Accessibility strategy

Please note that we have used px units for font-size up to this point. Using pixel values for typography is BIG NO. You should use rem unit. Unlike pixel units rem units are relative to root font-size. If you are not familiar with root font size, each site has html (root) element, and font-size defined here will be used to calculate sizes later. Usually 1rem will be around 16px (font-size: 100%) in most of browser, and if some browser has small variation it is fine because browser understands own folks and device used to open so you get all of these benefits for free.

Fluid typography accessibility implications

When using fluid typography, if done right it could make your life easier. But if you are doing it wrong you will end up with making inaccessible website so please keep in mind this while applying fluid typography. Also desired (middle) part of clamp should contain rem value to ensure that user can zoom text 200% and pass WCAG criteria.

More about these problems you could find out here.

Fluid typography solution

Here below is fluid typography example done in non-destructive fashion so it won’t harm accessibility and you will get all the befits of using it.

:root{
  --hfs-h4: clamp(1.25rem, 1.119rem + 0.655vw, 1.625rem);
  --hfs-h3: clamp(1.5625rem, 1.1913rem + 1.8559vw, 2.625rem);
  --hfs-h2: clamp(1.9375rem, 1.1296rem + 4.0393vw, 4.25rem);
  --hfs-h1: clamp(2.4375rem, 0.8873rem + 7.7511vw, 6.875rem);
}
  
/*If browser supports override with container query ready rules*/
@supports (font-size: 1cqi) {
  :root{
    --hfs-h4: clamp(1.25rem, 1.119rem + 0.655cqi, 1.625rem);
    --hfs-h3: clamp(1.5625rem, 1.1913rem + 1.8559cqi, 2.625rem);
    --hfs-h2: clamp(1.9375rem, 1.1296rem + 4.0393cqi, 4.25rem);
    --hfs-h1: clamp(2.4375rem, 0.8873rem + 7.7511cqi, 6.875rem);
  }
}

/*Set global styles*/
  h4  {  font-size: var(--hfs-h4);  }
  h3  {  font-size: var(--hfs-h3);  }
  h2  {  font-size: var(--hfs-h2);  }
  h1  {  font-size: var(--hfs-h1);  }

Typography and accessibility overlay

Many people tend to make sh*t and later install some accessibility overlay on website, and we are all good? These things are not needed, as user already has keyboard shortcuts to zoom in/out. Also every browser has font settings where user could set desired font-size and if site is well made his settings will be respected on the all sites. There is no point for user to adjust font-size on each site, most of users want to consume content and not configure each site they visit.

62.5% and 6.25% tricks

While I understand why some developers are using these tricks, using it inside WordPress is in my opinion stupid because we are going to use code solutions from many authors and they will expect 1rem to be around 16px. By hijacking root font-size we are creating problems in long run in interconnected system from many authors and this could even lead to authors using px value because of the potential problems with these scenarios.

Verdict

As everything goes in development, there isn’t really ultimate way, some developers could like one way, some could like another. This article tries to explain how to pull off fluid typography, put it in context of intrinsic design because by deploying strategic base for our website we can greatly reduce need for tweaking at certain breakpoint and make sites much easier to maintain.

Resources

    Headspin Logo
    1.1.1
    Built with
    and
    Headspinui
    @ 2024 HeadspinUI. All rights reserved.