Table Of Contents
Setting up CSS font styles in a Next.js app using vanilla-extract & Capsize.
Last Tended | |
---|---|
Planted | |
Status | Seed |
1. Start a Next.js Project
In the terminal, run:
2. Remove Unrequired Boilerplate
Delete
Delete the following directories & files highlighted in red as they won't be required:
my-next-app ├── pages│ ├── api│ ├── _app.ts│ └── index.tsx├── public│ ├── favicon.ico│ └── vercel.svg├── styles ...
Modify
Replace the contents of the following files:
/pages/_app.tsx
/pages/index.tsx
3. Add Font Files
For this example, we will only be using 1 font family, Inter.
Download the family & move the variable font file Inter-VariableFont_slnt,wght.ttf
into the directory /public/fonts/
.
4. Install vanilla-extract
For this example, we'll be using vanilla-extract to generate our CSS. In the terminal, run:
> npm install @vanilla-extract/css @vanilla-extract/next-plugin_
Replace the /next.config.js
file with the following:
/next.config.js
5. Install Capsize
Capsize is a library that trims unwanted space above & below typography that is applied by the browser. In the terminal, run:
> npm install @capsizecss/core @capsizecss/vanilla-extract @capsizecss/metrics_
6. Create Typography Styles
Create a file /styles/typography.css.ts
.
This file will hold all typographic information & define all font styles.
Add the following:
/styles/typography.css.ts
We are only using 1 font-family but this file is structured to allow more if required. It also allows for non-variable fonts. The font sizes were calculated using type-scale. Notes on why unions are used instead of enums can be found here.
7. Load Fonts
Create a file /styles/app.css.ts
.
This will act as the CSS reset & where font families will be loaded.
Add the following:
/styles/app.css.ts
fontDisplay: 'optional'
is being used to prevent layout shifting & a flash of invisible text on page load.
This also requires preloading font files. Create a file /pages/_document.tsx
& add the following:
/pages/_document.tsx
Using fontDisplay: 'optional'
sets an extremely small block period & no swap period for font loading.
In my experience, even on a fast connection (25 Mbps), the font won't always load in time & the page will display the fallback.
If you require to always display the correct font & can accept a layout shift, fontDisplay: 'swap'
might be a better setting to use.
More information on font-display values can be found here.
To set the CSS reset styles in all pages within the app, import the app.css.ts
into /pages/_app.ts
:
/pages/_app.tsx
8. Test
Lets visually test the font styles to ensure everything is working correctly.
Normally I would do this using Storybook but that is out of the scope of this note.
Create a file /styles/test.css.ts
& add the following:
/styles/test.css.ts
This file creates a CSS class using each of our defined font sizes.
The last class, boldText
, is showing how a font style can be extended & how to use 1 of the font weights we defined earlier.
To use these styles, modify the pages/index.tsx
page as follows:
/pages/index.tsx
9. Result
The end result is typography rendering at the defined size & weight with unwanted space above & below trimmed off. The outlines around the text where produced from a browser extension: Pesticide for Chrome.
Sandbox
I wasn't able to get a sandbox working with Next.js & vanilla-extract.
As a workaround, I've created a GitHub repo.