Customising Fonts in Tailwind CSS and daisyUI
Tailwind is awesome n’ all but what do you do when you want to change the default fonts. I’ve spent a bit of time customising this site to use local fonts above the default used in Tailwind CSS. In this post I’ll go over adding in new fonts for Tailwind and also extending the daisyUI themes.
In this post I’ll detail adding custom fonts to a SvelteKit project and also extending the daisyUI themes.
If you not familiar, daisyUI is a plugin for Tailwind that adds a ton of additional utility classes component classes to enable you to move fast when building sites.
You can follow along in this post while I piece it all together or you can Tl;Dr and see the final code.
Local fonts
Ok, so I want to use fonts above the default that comes with Tailwind.
In the past I’ve added the files for the fonts I wanted to use in a
static
or public
folder and then used @font-face
to load them
into the global app.css
file for Tailwind to use.
Then I found out about Fontsource (thanks to Matia) which is basically fonts that you install as dependencies.
Extend Tailwind theme
I’ll tackle adding fonts into Tailwind first. I’ll spin up a new
SvelteKit project and install Tailwind and daisyUI using svelte-add
.
The options I’m picking are Skeleton project
,
Yes, using TypeScript syntax
and yes to all the additional options,
if you’re following along, you do you.
The terminal commands are:
pnpm create svelte sveltekit-local-fonts
cd sveltekit-local-fonts
npx svelte-add@latest tailwindcss --daisyui --typography
I also did a post a while back on how to set up Svelte with Tailwind if you want to have a bit more detail on it.
I’ll also want to install the fonts I want to use from Fontsource so I’ll install them now too:
pnpm i -D @fontsource/poppins @fontsource/victor-mono
I want these fonts to be available to Tailwind so in the app.postcss
file generated by svelte-add
I’ve added in the fonts I want to use:
@import '@fontsource/victor-mono/400-italic.css';
@import '@fontsource/victor-mono/700-italic.css';
@import '@fontsource/victor-mono/400.css';
@import '@fontsource/victor-mono/700.css';
@import '@fontsource/poppins/400.css';
@import '@fontsource/poppins/500.css';
@import '@fontsource/poppins/600.css';
@import '@fontsource/poppins/700.css';
@import '@fontsource/poppins/800.css';
@import '@fontsource/poppins/900.css';
@tailwind base;
@tailwind components;
@tailwind utilities;
Just note that I’ve seen imports being used without the weights specified but when I have tried this way they are not rendered. Your experience may vary.
Now that the fonts are available to Tailwind I can use them in the
tailwind.config.cjs
file. Tailwind gives you three named font family
options to use sans
, serif
and mono
.
I just want to use Poppins for the sans
option and Victor Mono for
mono
.
I’ll extend the theme
object in the tailwind.config.cjs
file and
add in the fontFamily
object defining the added fonts.
const config = {
content: ['./src/**/*.{html,js,svelte,ts}'],
theme: {
extend: {
fontFamily: {
sans: ['Poppins', ...tailwind_theme.fontFamily.sans],
mono: ['Victor Mono', ...tailwind_theme.fontFamily.mono],
// or name them
// 'victor-mono': ['Victor Mono'],
// poppins: ['Poppins'],
},
},
},
plugins: [typography, daisyui],
}
In the example above I’m using the Tailwind default (named) names for
the font families (sans
, serif
and mono
), there’s also the
option to name them yourself, I’ve commented out the lines to show you
how.
If for some reason the local font is not available then I’ll want to fallback to the defaults offered by Tailwind. That’s why I’m spreading in the rest of the font families from Tailwind.
Here’s the full tailwind.config.cjs
and you can see where I’m
pulling out the defaultTheme
from Tailwind as a variable and
spreading the sans
and mono
font families into the
theme.extend.fontFamily
object for each font family.
const daisyui = require('daisyui')
const typography = require('@tailwindcss/typography')
const tailwind_theme = require('tailwindcss/defaultTheme')
/** @type {import('tailwindcss').Config}*/
const config = {
content: ['./src/**/*.{html,js,svelte,ts}'],
theme: {
extend: {
fontFamily: {
sans: ['Poppins', ...tailwind_theme.fontFamily.sans],
mono: ['Victor Mono', ...tailwind_theme.fontFamily.mono],
// or name them
// 'victor-mono': ['Victor Mono'],
// poppins: ['Poppins'],
},
},
},
plugins: [typography, daisyui],
}
module.exports = config
So, now if I add some container classes to the
src/routes/+layout.svelte
file utilising the Tailwind prose plugin
as well:
<script>
import '../app.postcss'
</script>
<main class="container max-w-3xl mx-auto px-4 prose prose-xl">
<slot />
</main>
Then in the src/routes/+page.svelte
file I can add in some text
using the sans
and mono
font families:
<h1>Local Fonts with SvelteKit</h1>
<p>
Using <a href="https://fontsource.org/"><code>@fontsource</code></a>
to add local fonts.
</p>
<code>
<pre>Also added mono-space font for code blocks.</pre>
</code>
I’m not naming the fonts I want to use because I set the fonts as the Tailwind named fonts so there’s no need to specify them as the Tailwind prose plugin will take care of the font selection, sizing and spacing for the markup.
Ok, so that’s basically it for adding in custom fonts to Tailwind.
If you want to use more than the Tailwind named fonts then you can define your own font names and use them in the markup like I detailed in the example. Just bear in mind that you’ll need to specify the font you want to use in the markup.
I’ll move onto doing something similar now with daisyUI.
When I say something similar I mean that I’ll be adding in different fonts for different themes in daisyUI.
Using daisyUI themes
I touched on daisyUI at the start, what I didn’t mention is that it comes with 29 themes out of the box 🤯.
To use all the daisyUI themes I’ll need to configure them in the
tailwind.config.cjs
file.
const daisyui = require('daisyui')
const typography = require('@tailwindcss/typography')
const tailwind_theme = require('tailwindcss/defaultTheme')
/** @type {import('tailwindcss').Config}*/
const config = {
content: ['./src/**/*.{html,js,svelte,ts}'],
theme: {
extend: {
fontFamily: {
sans: ['Poppins', ...tailwind_theme.fontFamily.sans],
mono: ['Victor Mono', ...tailwind_theme.fontFamily.mono],
// or name them
// 'victor-mono': ['Victor Mono'],
// poppins: ['Poppins'],
},
},
},
daisyui: {
themes: true,
},
plugins: [typography, daisyui],
}
module.exports = config
The daisyui.themes=true
config means that I’m using all 29 daisyUI
themes.
If I want to restrict this to just a few themes then I can use an array of theme names instead:
daisyui: {
themes: ['dark', 'forest', 'wireframe'],
},
I’ll be using the previous configuration so I can cycle though all the themes.
All the daisyUI themes except Cyberpunk and Wireframe have the same font right now.
Once I’ve added in the daisyUI config I can change the daisyUI theme
on the root app.html
file in the project with the data-theme
attribute on the html
element.
So in this example I’m using the wireframe
theme:
<!DOCTYPE html>
<html lang="en" data-theme="wireframe">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>
Selecting a daisyUI theme
I recently did a post on Cookie-Based Theme Selection in SvelteKit with daisyUI and I’ll be using that now to cycle through the themes. If you need more detail on that then check out the post.
I’m going to rip the code from the sveltekit-theme-switch-example
repo and add it to the example I’m building out here.
I’ll scaffold out the files I need to make the select component and the hooks file:
# -p created the parent directory if it doesn't exist
mkdir src/lib/themes -p
touch src/lib/themes/index.ts
touch src/lib/theme-select.svelte
touch src/hooks.server.ts
In the src/lib/themes/index.ts
file I’ll copy the themes already in
the example repo you can expand out the details button for the list
if you like.
In src/lib/theme-select.svelte
I’ll copy the code from the
sveltekit-theme-switch-example
repo.
Then add in the code for the src/hooks.server.ts
file.
The to use the theme-select
component I’ll add it to the
src/routes/+layout.svelte
file so it’s available to all child pages
in the project (which is none but a good practice).
<script>
import ThemeSelect from '$lib/theme-select.svelte'
import '../app.postcss'
</script>
<ThemeSelect />
<main class="container max-w-3xl mx-auto px-4 prose prose-xl">
<slot />
</main>
Extend the daisyUI themes
Aight! Cycling though the themes now I can see that my custom font is
being used in all the themes except cypherpunk
and wireframe
.
Why? Well, if I take a look at the daisyUI themes config for
cyberpunk
I can see that the fontFamily
is set to a monospace
font.
Here’s a snippet from the config file:
"[data-theme=cyberpunk]": {
"color-scheme": "light",
"fontFamily":
"ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace",
"primary": "#ff7598",
"secondary": "#75d1f0",
"accent": "#c07eec",
"neutral": "#423f00",
"neutral-content": "#ffee00",
"base-100": "#ffee00",
"--rounded-box": "0",
"--rounded-btn": "0",
"--rounded-badge": "0",
"--tab-radius": "0",
},
I can override this in the tailwind.config.js
file by amending the
daisyui
config. For illustration purposes I’ll change the
cyberpunk
font to use Comic Sans MS
.
const daisyui = require('daisyui')
const typography = require('@tailwindcss/typography')
const tailwind_theme = require('tailwindcss/defaultTheme')
/** @type {import('tailwindcss').Config}*/
const config = {
content: ['./src/**/*.{html,js,svelte,ts}'],
theme: {
extend: {
fontFamily: {
sans: ['Poppins', ...tailwind_theme.fontFamily.sans],
mono: ['Victor Mono', ...tailwind_theme.fontFamily.mono],
// or name them
// 'victor-mono': ['Victor Mono'],
// poppins: ['Poppins'],
},
},
},
daisyui: {
themes: [
{
cyberpunk: {
...require('daisyui/src/theming/themes')[
'[data-theme=cyberpunk]'
],
fontFamily: 'Comic Sans MS',
},
},
],
},
plugins: [typography, daisyui],
}
module.exports = config
I found a GitHub discussion answered by Pouya (daisyUI creator) that details how to do this.
So changing that config now makes every theme the same as the
cyberpunk
theme, because that’s all that’s configured now. Makes
sense, right?
Wait, what? Yeah! I’ll have to add a config for each theme I want to use. In this example that’s all 29 of them! 😱
Let’s take a look at that theme config again:
{
cyberpunk: {
...require('daisyui/src/theming/themes')[
'[data-theme=cyberpunk]'
],
fontFamily: 'Comic Sans MS',
},
},
Repeat that 29 times! That’s going to be a lot of code duplication!
Parametrised config
What I can do is create a function that takes the theme name as a parameter and returns the config object so I can be used in daisyUI. Then I can use that function to create the config object for each theme.
As I’m only looking to change the fontFamily
I’ll add that as a
parameter too. This can be further extended to allow for more
customisation of the themes.
So, the function will look something like this:
function create_theme(theme_name, font_family) {
return {
[theme_name]: {
...require('daisyui/src/theming/themes')[
`[data-theme=${theme_name}]`
],
...(font_family ? { fontFamily: font_family } : {}),
},
}
}
Then pass all the themes through that function to create the config object, if there’s no theme then it’s going to fallback to the daisyUI default same if there’s no font specified.
const daisyui_themes = [
create_theme('acid'),
create_theme('aqua'),
create_theme('autumn'),
// rest of the themes
]
See the full array here:
Then I can use that array in the daisyui
config.
daisyui: {
themes: daisy_themes,
},
Here’s the full tailwind.config.js
file:
Now, if I select the cyberpunk
theme, I get the Victor Mono
font
being used, I can now pass any specific font to any theme.
As I mentioned earlier, it’s not just the font that can be changed
here, I can start modifying any of the daisyUI theme properties by
extending the create_theme
function.
Thanks
Thanks to Pouya for creating daisyUI I’ve been using it for a while now and it’s great! It’s pretty much the default I reach for now when starting a new project.
Massive thanks to Script Raccoon for helping me understand how to use a theme in the cookies! The dark mode toggle example they made, you can find that on their blog where they detail How to implement a cookie-based dark mode toggle in SvelteKit give it a read!
Conclusion
I’ve laid out and detailed how I’d go about this step-by-step. I hope you can get an idea on how to customize fonts in Tailwind with SvelteKit and daisyUI. I installed and integrated Fontsource fonts for local fonts to use in the project. I also demonstrated how to extend the Tailwind theme to incorporate theme.
I then looked as extending the daisyUI themes and how to modify them to use my preferred fonts. By creating a parameterized function, I avoided code duplication and provided a degree of customisation for each theme.
I hope you found this useful, if you did, please don’t forget to share it. 🙌
There's a reactions leaderboard you can check out too.
Analytics Information