Course
Apply Styles
Next.js Mastery: From Fundamentals to Full-Stack
Unlock the power of Next.js with this comprehensive course! Starting with the basics, you’ll learn essential skills such as routing, data fetching, and styling. Progress through practical projects, including building your own React Notes app, to gain hands-on experience. Dive into the source code to understand the inner workings and core principles of Next.js. Perfect for developers with a basic knowledge of React and Node.js, this course ensures you’ll be ready to create high-performance full-stack applications efficiently. Join us and master Next.js, backed by industry experts and a supportive learning community.
Apply Styles
1. Using className
So far, we've primarily discussed adding styles through the
className
property:import { Inter } from 'next/font/google';
const inter = Inter({ subsets: ['latin'],});
export default function RootLayout({ children }) { return ( <html lang="en" className={`${inter.className}`}> <body>{children}</body> </html> );}
When you access the
className
property of the font object, it returns a read-only CSS class name:For example,
inter.className
might return a value like __className_a64ecd
, which corresponds to a class automatically generated by Next.js in the layout.css
file:.__className_a64ecd { font-family: '__Inter_a64ecd', '__Inter_Fallback_a64ecd'; font-style: normal;}
@font-face { font-family: '__Inter_a64ecd'; //...}
@font-face { font-family: '__Inter_Fallback_a64ecd'; //...}
2. Using style
In addition to
className
, you can also use style
, which returns a read-only style object. Here's an example:// layout.jsimport { Inter } from 'next/font/google';
const inter = Inter({ subsets: ['latin'],});
export default function RootLayout({ children }) { return ( <html style={inter.style}> <body>{children}</body> </html> );}
The generated HTML code would look like this:
(Insert image showing the generated style attributes)
3. Using CSS Variables
We've already covered CSS variables in detail, so we won't go into it again here.
Common Issues
7.1. Using Multiple Fonts
You can import and use multiple fonts in two main ways:
Method 1: Utility Function
Create a utility function to export the fonts, then import the desired fonts wherever you need them and apply the
className
. This approach ensures that fonts are preloaded only when used.Export two font objects:
javascriptCopy code// app/fonts.jsimport { Inter, Roboto_Mono } from 'next/font/google'; export const inter = Inter({ subsets: ['latin'], display: 'swap',}); export const roboto_mono = Roboto_Mono({ subsets: ['latin'], display: 'swap',});
Import and use them as needed:
javascriptCopy code// app/layout.jsimport { inter } from './fonts'; export default function Layout({ children }) { return ( <html lang="en" className={inter.className}> <body> <div>{children}</div> </body> </html> );}
// app/page.jsimport { roboto_mono } from './fonts'; export default function Page() { return ( <> <h1 className={roboto_mono.className}>My page</h1> </> );}
Method 2: CSS Variables
Create a CSS variable that can be used with your preferred CSS strategy:
javascriptCopy code// app/layout.jsimport { Inter, Roboto_Mono } from 'next/font/google'; const inter = Inter({ subsets: ['latin'], variable: '--font-inter', display: 'swap',}); const roboto_mono = Roboto_Mono({ subsets: ['latin'], variable: '--font-roboto-mono', display: 'swap',}); export default function RootLayout({ children }) { return ( <html lang="en" className={`${inter.variable} ${roboto_mono.variable}`}> <body> <h1>My App</h1> <div>{children}</div> </body> </html> );}
The final implementation would be:
(Insert image showing CSS variable usage)
As seen, two CSS variables are declared:
--font-roboto-mono
and --font-inter
. When you need to style text with these fonts, use the corresponding variable:cssCopy code// app/global.csshtml { font-family: var(--font-inter);} h1 { font-family: var(--font-roboto-mono);}
7.2. Integrating with Tailwind CSS
next/font
can be used alongside Tailwind CSS by leveraging CSS variables.First, declare CSS variables using the
variable
property:javascriptCopy code// app/layout.js import './globals.css';import { Ma_Shan_Zheng, Roboto_Mono } from 'next/font/google';
const ma_shan_zheng = Ma_Shan_Zheng({ subsets: ['latin'], display: 'swap', weight: '400', variable: '--font-ma-shan-zheng',}); const roboto_mono = Roboto_Mono({ subsets: ['latin'], display: 'swap', variable: '--font-roboto-mono',});
export default function RootLayout({ children }) { return ( <html lang="en" className={`${ma_shan_zheng.variable} ${roboto_mono.variable}`}> <body>{children}</body> </html> );}
Then, add the CSS variables to your Tailwind CSS configuration:
javascriptCopy code// tailwind.config.jsmodule.exports = { content: [ './src/**/*.{js,ts,jsx,tsx,mdx}', ], theme: { extend: { fontFamily: { "ma": ['var(--font-ma-shan-zheng)'], "mono": ['var(--font-roboto-mono)'], }, }, }, plugins: [],}
Finally, apply styles to elements using the
font-
prefix (e.g., font-ma
, font-mono
):javascriptCopy code// page.jsexport default function Page() { return <h1 className="font-ma underline">你好,世界!Hello World!</h1>;}
7.3. Using a Font Definition File
When you call the font function, each font instance is managed separately. If multiple places use the same font, it's best to load it in one location and import it as needed. This is where a font definition file comes in handy.
For example, create a
fonts.ts
file in the styles
directory at the root level and define your fonts:javascriptCopy code// styles/fonts.jsimport { Inter, Lora, Source_Sans_3 } from 'next/font/google';import localFont from 'next/font/local'; const inter = Inter();const lora = Lora();
const sourceCodePro400 = Source_Sans_3({ weight: '400' });const sourceCodePro700 = Source_Sans_3({ weight: '700' });
const greatVibes = localFont({ src: './GreatVibes-Regular.ttf' }); export { inter, lora, sourceCodePro400, sourceCodePro700, greatVibes };
You can now use these definitions in your code:
javascriptCopy code// app/page.jsimport { inter, lora, sourceCodePro700, greatVibes } from '../styles/fonts'; export default function Page() { return ( <div> <p className={inter.className}>Hello world using Inter font</p> <p style={lora.style}>Hello world using Lora font</p> <p className={sourceCodePro700.className}> Hello world using Source_Sans_3 font with weight 700 </p> <p className={greatVibes.className}>My title in Great Vibes font</p> </div> );}
To make accessing the font definition file easier, you can define a path alias in
tsconfig.json
or jsconfig.json
:jsonCopy code// tsconfig.json{ "compilerOptions": { "paths": { "@/fonts": ["./styles/fonts"] } }}
You can now use it like this:
javascriptCopy code// app/about/page.jsimport { greatVibes, sourceCodePro400 } from '@/fonts';
4o