/All articles

Fonts and headlines in design, creating the perfect website

Apr 30, 2024 · 13 minutes

Close-up of the letter "A" on a piece of paper. The smaller letters "A" are visible in the background. At the bottom of the image are the words "DESIGN HANDOFF" and "DECODED".

Authors

  • Izabela Łaszczuk
Choosing a font for a website may seem easy: just pick one you like and that’s it, you’re done. End of an article.

In some cases, sure, if you’re satisfied with Arial, and don’t need anything fancy. But let’s be honest, for most projects that is not the case.

Fonts, although seemingly simple, can pose challenges for designers and developers. It is essential to consider several important aspects related to font management in a project, such as:

1. Using multiple different fonts, especially employing one font for each header, can negatively impact page performance.

2. Adjusting font sizes for various resolutions and devices is crucial to ensure a consistent appearance across all platforms. The choice of appropriate fonts also plays a significant role in SEO and accessibility.

3. Differences in font formats. Variances in how fonts are interpreted by different systems and browsers affect text appearance and project consistency. Thankfully we don’t have to add different fonts for IE 11 anymore, because: 

An illustration of a tombstone with the caption "IE 11 is dead." The image makes a humorous reference to the end of support for Internet Explorer 11

And never coming back. 
4. Providing developers with a package containing all the fonts used in the project is crucial, particularly for fonts not available on platforms like Google Fonts or Fontsource.

Font family package weight

When deciding which fonts to use in a project, it's crucial to keep in mind that each font family package comes with a "weight." Typically, a project requires 2-3 fonts. It's not advisable to incorporate 20 different font families, as it significantly extends the time needed to load the application. So if you got the design with many different fonts you should go back to the design team and establish how many of them do you really need.

Determine the necessary font weights

For the same reason as above, if we know that a particular font family will be needed in the project exclusively for headers, it's advisable to specify this, so that developers don't download the entire typeface, but only a specific variant, such as bold.

If a font family is used for just one header, only once in the whole project, the developer and designer should discuss whether it is intentional and justified, perhaps for business reasons. If yes, maybe it’s better to add a picture instead?  As a general rule, we should avoid adding font weights to the project that are not used. In this case, the primary goal should be to limit the data transmitted to the user. Each font variant represents additional kilobytes sent during the application loading process. Of course if the client doesn’t mind, you can add all the fonts they want but it doesn’t bode well.
A screenshot from a web performance analysis tool showing a list of requests, their status, type, initiator, size, time, and a chart of time dependencies. The screenshot displays information about the size in kB occupied by various fonts: Lato 100 - 13.3 kB, Lato 400 - 14 kB, Lato 900 - 13.8 kB, Oswald 200 - 12.3 kB, Crossiant One 400 - 9.2 kB.
A screenshot from a web performance analysis tool showing a list of requests, their status, type, initiator, size, time, and a chart of time dependencies. The screenshot displays information about the size in kB occupied by various fonts: Lato 400 - 14 kB, Lato 900 - 13.8 kB, Oswald 200 - 12.3 kB.

The default font size scale in Tailwind

Similar to other CSS properties, font-size values should be assigned to variables to maintain project consistency. Tailwind has predefined font-size values, and in most projects, these are sufficient. However, if custom values are needed, they should be incorporated into the design system and utilized as variables.
It's worth noting that each variable is assigned both a font-size and a line height value.

The image shows Tailwind class names and their properties (font size and line height). We can see 13 sizes, ranging from text-xs to text-9xl. For the text-xs size, the font size is 12px (0.75 rem), and the line height is 16px (1 rem). We have access to 13 default variable names for font size, ranging from xs to 9xl. If necessary, default values can be altered. For example, we want all the headers on the website to be: font-size: 26px; line-height: 34px; but there is no such variable. No problem, we can assign these values to the variable text-2xl instead of the default values.
In justified cases, we can also extend our values with additional variables. However, it is essential to ensure appropriate variable names, so for example, if you need font-size: 10px; line-height: 16px;  you could name the variable text-2xs. Screenshot of JavaScript code defining the fontSizesPx variable. This variable contains an object that maps font size names (e.g. 2xs) to objects with size (10) and lineHeight (16) values.
Be careful though. It is not a good practice to have 20 font sizes in one project. Usually if you (as a developer) see more than 8 font sizes on the mockups you should go back to the designer and make sure which ones are really needed.. Please, don’t add them all to the project, especially if most of them would be used once in the entire application.
Why?
The image shows a piece of source code in JavaScript. The code defines a variable called fontSizesPx, which contains a list of font sizes in pixels. Font sizes are defined for various values, including xxxxs, xxxs, xxs, xs, sm, base, lg, xl, 1.5xl, 2xl, 3xl, 4xl, 5xl, 6xl, 7xl, 8xl. Two parameters are defined for each font size value: size and lineHeight. The size parameter specifies the font size in pixels. The lineHeight parameter specifies the line height in pixels.
This is an example from a real-life project. Few of them were used just once… Don’t do that. Please, just don’t. If I have to guess how it happened I would say that few designers were working simultaneously on the same project and didn’t prepare variables ahead of time. So everyone just kept adding new font sizes and nobody checked it afterwards. Rookie mistake. If you have a font size on a mockup that will be used once, and design insists that it has to stay, it is better to write it manually.

Line height

In an ideal world and an ideal project, line-height is NOT separated from font size. Line-height values are assigned to specific variables determining font size. For example: text-2xl: font-size: 24px; line-height: 32px;
By using variables that define font size, the developer automatically handles line-height values. You declare them once, together with font size and you can forget about it. There is no need to check it every time later on. 

In less-than-ideal scenarios, we aim to limit changes to line-height only when necessary due to design specifics.

Tailwind has predefined line-height values that cover most cases. If it's not necessary, it's advisable to avoid defining new variables or adding additional values.

"List of Tailwind class names for line heights with their values: leading-3: line height: 0.75rem; /* 12px */ leading-4: line height: 1rem; /* 16px */ leading-5: line height: 1.25rem; /* 20px */ leading-6: line height: 1.5rem; /* 24px */ leading-7: line height: 1.75rem; /* 28px */ leading-8: line height: 2rem; /* 32px */ leading-9: line height: 2.25rem; /* 36px */ leading-10: line height: 2.5rem; /* 40px */ The background of the image is dark blue. The text on the image is light blue in various

To enhance accessibility, use a minimum value of 1.5.

Web Content Accessibility Guidelines (WCAG) 2.1

Font weight

Font-weight values can also be assigned to variables to maintain project consistency. To be honest with you, we don’t use it that much, because Tailwind already has predefined font-weight values that cover all most popular cases:
The image shows a list of Tailwind class names for font weights along with their values. Thin (font-thin): font-weight: 100; Very light (font-extralight): font-weight: 200; Light (font-light): font-weight: 300; Normal (font-normal): font-weight: 400; Medium (font-medium): font-weight: 500; Semi-thick (font-semibold): font-weight: 600; Thick (font-bold): font-weight: 700; Very thick (font-extrabold): font-weight: 800; Black (font-black): font-weight: 900;
If both design and developers use these names, there should be no problems. Because font-bold will always mean weight 700. And there is no confusion. Problems start when you have more than one font used in the application and they have different weights under the same name. You must ensure that the same names represent the same weight. In other words, font-bold should indicate a weight of 700 in all available fonts in the project. So you can avoid situations like this: The image shows JavaScript code defined in two variables: fontWeightArial and fontWeightPoppins. The fontWeightArial variable contains three font weights for the Arial font: normal (400), semi-bold (600), bold (700). The fontWeightPoppins variable contains four font weights for the Poppins font: thin (100), normal (300), medium (500), bold (600).

That is why it is better to meet with designers and ask them to use consistent font weight names in all fonts. Believe me, it will save you a ton of time.

Headings - maintaining hierarchy

Screenshot of HTML code with h1, h2, h3 and h4 headers. Header h1: The main title of the page Header h2: Subheading of the page Header h3: Subheading subheading of the page Header h4: Sub-heading of the page sub-heading.

As a rule, we strive for maximum reusability, meaning that h1 always has the same styles on every page, h2 always has the same styles on every page, and so on.

Unfortunately, it is often the case that what is presented in mockups and style guides makes little to no sense from the perspective of best practices and SEO.

Let's assume you have a website that starts with a heading that looks like an h3, but it should be an h1 (as it constitutes the main title of the page). Always put hierarchy first, you don’t want to have h3 before h1 on your page. For bots scanning the website, the appearance of these headings doesn't matter (only the tag counts), but if you start skipping h1, you automatically worsen your SEO, WCAG accessibility standards and disrupt the hierarchy of heading grouping for screen readers. 

What should we do in such a situation?

The styles for each header can be assigned to a utility class that you can refer to when needed. Check out the example below.
White photo.Text on photo: Headline written in green: Hi World!  Main text: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Under the photo 3 green stars. Under the stars the caption written in the same size as a headline: What are we doing here? And then the text: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. You receive a design with a header (“Hello World!) that should be h1 on top and another header (“What are we doing here?”) that looks like an h1, but you need to use h2 in that context.

No problem. We can add the class .heading-1 to the h2 to make it look like an h1. This way, we maintain the hierarchy while preserving the appearance from the mockups.
Source code written in CSS. Header 1 (H2) with the text "What are we doing here?" CSS class "heading-1" applied to the header CSS style for the "heading-1" class: Font size: Tailwind class “text-3xl” Margins: 5 pixels left and right, 3 pixels top and bottom

What should the styles for h1-h6 tags and utility classes include?

Here's how the standardization of header styles could look like: The image shows a snippet of CSS code that defines styles for headings h1 through h5. The code contains CSS selectors for each header, as well as style declarations for properties such as font size and bold.

Of course, adding such custom classes should be a last resort. We always strive to ensure that h1, h2, h3, etc., look the same on every page. This means that if h2 has a font size of 24px on one page, it should also have 24px on another.

However, I understand that with modern designs, this isn't always possible, which is why I wrote earlier how to handle it appropriately. In summary, maintaining hierarchy should be our priority. If we can't achieve this while keeping a consistent appearance for tags (h1, h2, h3), then we add a custom class.

Conclusion

Font selection and management play a crucial role in web design, impacting both aesthetics and performance. Ultimately, the key is to strike a balance between design flexibility and maintaining a standardized appearance for optimal user experience.
Happy coding/ happy designing!
To provide services at the highest level, we use cookies as described in our cookie policy. By using our website, cookies will be placed on your device. You can change your browser settings at any time. Check our cookie policy.