Tutorial: How to Add Custom Fonts to a WordPress Site

Nowadays there are loads of beautiful fonts available for websites and blogs. But how do you go about the technical nitty gritty of adding them? And once they’re added, how do you make sure that the right parts of your website use the right fonts?

This step-by-step guide is aimed primarily at WordPress users. However, you can use a similar approach for other types of website.

The text 'How to use custom fonts on you WordPress website' in a four very different fonts, ranging from curly to script.

Step 1: Add the new font to your website

How to do this depends on the font you’ve chosen. If you’re using a font library like Google Fonts or Adobe Typekit, this is very straightforward. But even if you’ve bought or downloaded a font from some other source, it needn’t be daunting.

Just follow the instructions below for Google Fonts, Typekit or other fonts.

Adding Google Fonts

Google Fonts has more than 700 different fonts which you can use – free – on your website. If you’re using WordPress, the simplest way to add these is to use one of the many Google Fonts plugins. Alternatively, you can copy the code snippet provided by Google Fonts into the ‘head’ section of your website.

There are already loads of great tutorials about how to do this, so I’m not going to reinvent the wheel. Try this tutorial or follow the Google Fonts documentation.

Adding Adobe Typekit fonts

Similarly, Adobe Typekit contains over a thousand fonts, including a limited selection (over 100 fonts) that are available free. As with Google Fonts, there are plenty of Typekit plugins to make this simpler for WordPress users.

Alternatively, see Adobe’s instructions for how to do it.

Adding other fonts (e.g. bought or downloaded fonts)

But what if the font you like isn’t in Google Fonts or Adobe Typekit? Perhaps you’ve bought a font, or have downloaded a free one. Now you’ve got a zip file full of files with weird names like mynewfont.woff, and no idea how to use them!

There are just two things you need to do: upload your font files, and create a font-face instruction which tells your style sheet where to find these files.

Upload your font files

It’s best to use an FTP programme like Filezilla (PC) or Cyberduck  (Mac) to do this. Or you can use the file manager in your web hosting control panel.

Create a directory called ‘fonts’ within your theme directory. e.g. www.example.com/wp-content/themes/my-theme/fonts. (Strictly speaking, this isn’t essential, but I like to keep things tidy!)

Upload all your custom font files to this directory.

Screenshot showing font files within a directory structure. The files are in the /public_html/wp-content/themes/my-theme/fonts directory.
Font files uploaded via FTP

Use the @font-face command to import the fonts to your stylesheet.

In most cases you’ll have a number of different files for your font. This is to make sure it works on as many different browsers as possible.

You need to tell your stylesheet where to find the fonts, and which file types are available.

In WordPress, your stylesheet will be called style.css and can be found in the /wp-content/your-theme/ folder. If you’re using different web software, check your theme or template files for a file ending with ‘.css’.

Then add code like this to the stylesheet file:

@font-face {
 font-family: 'My New Font';
 src: url('fonts/mynewfont-regular-webfont.eot');
 src: url('fonts/mynewfont-regular-webfont.eot?#iefix') format('embedded-opentype'),
 url('fonts/mynewfont-regular-webfont.woff') format('woff'),
 url('fonts/mynewfont-regular-webfont.woff2') format('woff2'),
 url('fonts/mynewfont-regular-webfont.ttf') format('truetype'),
 url('fonts/mynewfont-regular-webfont.svg') format('svg');
 font-weight: normal; font-style: normal; }

You will need to replace ‘My New Font’ with the name of your font, and make sure that the URLs match your actual filenames. If you don’t have all these different file types, just delete the relevant line.

Make sure you check the URL for each font file carefully: it should give the URL relative to the style sheet. In this case, the font files are in a sub-directory called ‘fonts’ of the folder containing the style sheet, so each URL starts with ‘fonts/…’

If that seems a little alarming, don’t panic! Font Squirrel has a lovely tool which will generate this code for you.

If you’re copy-and-pasting your font-face code, make sure that your straight quote marks don’t get converted to curly quotes, otherwise it may not work.

Step 2. Target the text you want

OK, so your fonts are all set up and ready to use, but how do you tell your website to use them? And how do you get the right bits of text using the right one of your lovely new fonts?

The answer is CSS, or Cascading Style Sheets. Almost all modern websites are built using CSS to define the styles used for your website – from the layout to colours and, of course, fonts.

The principle behind CSS is that all styles are inherited, until they’re over-ruled by a more targeted style. CSS will check all rules that apply to a specific element (e.g. an image, a link or a paragraph). It there’s a conflict, it will prioritise them according to which is most specific. If they’re exactly the same, the one that comes last will be used.

So for example you can create a style for all paragraphs and a style for all links, but then write a more specific rule for paragraphs with a style class of ‘intro’. And an even more specific rule for links within a paragraph with a class of ‘intro’. And so on…

CSS is so powerful that some coders have even created artworks with it. This guide is not aimed at those people! 😉

TIP: If you’re using WordPress, you may not need to edit your theme stylesheet at this stage. Usually you can add extra styles via the Customiser, which is easier and will give you hints if you type the styles incorrectly. Look for the Additional CSS or Custom CSS section and add your new CSS there.

CSS Example 1

Let’s say you want all of the text on your whole website to use a sans-serif font called “Cloudy Day”. (Disclaimer: I have no idea whether such a font exists).

Assuming you’ve followed the steps above for Google Fonts, Typekit or other fonts, you just need to add this simple line to your CSS:

body { font-family: 'Cloudy Day', Arial, sans-serif; }

Note that the font name within the inverted commas must exactly match the font name used in your @fontface instruction or in your Google Fonts/Typekit set-up, including any capitalisation and spaces.

This command tells your website that the default font for all body text (i.e. everything) should be the Cloudy Day font. Or, if the browser can’t load the Cloudy Day font, then to use Arial. Or, in the very, very unlikely event that the browser can’t even display Arial, then to use its default sans-serif font.

CSS Example 2

But what if you want to use a different font, let’s call it ‘Windy Day’, for headings?

Headings should be identified with h1, h2, h3, etc, so you can use something like this:

h1,h2,h3,h4,h5,h6 { font-family: 'Windy Day', Times, serif; }

I’ve assumed that Windy Day is a serif font, so in this case I’m using ‘Times’ and ‘serif’ as my fallback fonts.

When it reaches a piece of heading text, the browser will now spot that there’s a more specific font style for headings and apply that instead of the style for ‘body’.

You can use this same principle throughout your website.

How do I change the font for this bit of text…?

It can be tricky for beginners to work out how to target a particular bit of text with a different style. Fortunately, browsers such as Chrome, Edge or Firefox have tools to make it easier.

You can view the code by hovering your mouse over the element that you want to target, then right clicking and choosing ‘inspect’ or ‘inspect element’.

CSS Example 3

Let’s say I want to change the WordPress ‘Entry Title’ (i.e. the title of a page or post).

Using the code inspector (in this case, using Chrome), I can look at the code and the CSS for one of my page titles:

Screenshot of the code inspector in the Chrome browser. A page element 'What we do' is selected and some of the CSS styles for the element can be seen below.
Code inspector in the Chrome browser: this can be used to identify the piece of text for which you want to change font

You can see that the HTML code for the page title (highlighted in blue) is:

<h1 class="entry-title" itemprop="headline">What We Do</h1>

More importantly, by looking in the boxes below, you can see the CSS which is affecting it. For example, the CSS setting the font size is defined for the entry-title class (denoted by .entry-title):

.entry-title {
    font-size: 36px;
    font-size: 3.6rem;

This is over-riding the (less specific) font size defined for ‘h1’, which you can see crossed out in the code inspector. (In this case, they were both the same anyway, but if they weren’t, ‘.entry-title’ would win!)

However, the page title’s colour, font style, and some other properties are set by the ‘h1’ class, since these aren’t defined for ‘.entry-title’:

h1, h2, h3, h4, h5, h6 {
    color: #333;
    font-family: 'Lato', sans-serif;
    font-weight: 400;
    line-height: 1.2;
    margin: 0 0 20px;

Now that I know what CSS already exists, I can add a targeted bit of CSS to overrule it. For this example, I’m going to use a new font called ‘Air’.

I could edit either of these bits of CSS, but to make sure it only affects text which is ‘h1’ and has the class ‘entry-title’, I use CSS like this:

h1.entry-title { font-family: 'Air', Times, serif; }

CSS Example 4

As another example, let’s say I want to use my ‘Air’ font for all the headings, but only on blog posts. This time, I need to find a selector that applies to all blog pages (but not other pages).

Screenshot of the code inspector showing the classes applied to the <body> tag. The 'single-post' class is highlighted by a red ellipse.

Fortunately for me, WordPress has just the style class I need. Looking at the ‘body’ element for my post, I can see a class called ‘single-post’, which applies to all individual blog posts. I can ignore all the other classes listed here as I don’t need those. I’ll combine this with my header selectors h1, h2, h3 etc to create the following CSS:

.single-post h1,
.single-post h2,
.single-post h3,
.single-post h4 {
   font-family: 'Air', Times, serif;

You may notice that this is a little different to the way I combined a class with a header before. That’s because of the way that the HTML is structured.

In the previous example, it was the h1 element itself that had the class ‘entry-title’ (like this: <h1 class=”entry-title”>). To target this with CSS, you join the two together as:


However, in this example, the h elements that I’m trying to target all sit inside an element with the class ‘single-post’ (the body). To target this in CSS, I need to list the outer element first, and separate it by a space, like this:

.single-post h1

If you need to, you can combine all sorts of elements and classes, ending up with long (and very specific) CSS like this:

.single-post .footer-widgets .footer-widget-1 h3.widget-title

Obviously I could give many more examples but the best way to learn is to try it and find out for yourself. Remember to do this on a copy of your website, not the live website itself!

For more tips, try this back-to-basics beginners’ guide to CSS.

A final tip: Clear the cache!

Sometimes you’ll change your CSS but the font (or whatever property you’re changing) will stay stubbornly the same. This might be a problem with your CSS, but sometimes it’s simply because you’re looking at a cached copy of your web page (i.e. a copy saved by your browser or server).

As you can imagine, it can be very frustrating to spend ages trying to fix code that isn’t broken!

Use the code inspector to check what CSS is being applied. If the changes you’ve made aren’t showing in the code inspector, it’s likely that the page is being cached.

If so, the first thing to try is a ‘hard refresh‘ of the page. Depending on your browser, you may need to press CTRL + F5, SHIFT + F5, CTRL + R (Windows) or CMD + SHIFT + R (Mac).

If that doesn’t work, check whether you’ve got a Caching plugin on your website. Many will have a ‘clear cache’ setting. Sometimes your web hosting company will cache the page, and you may be able to clear this via your hosting control panel. If all else fails, try using a different internet browser.

If none of that works, it’s likely that you haven’t managed to target quite the right selectors so you’ll need to go back and try again.

Are there any other topics you’d like me to cover in a tutorial? If so, please let me know.

Want more blog posts?

Subscribe to get my latest blog posts straight to your inbox