Cours Next.js · Module 3: Styles et optimisation visuelle
Optimisation des polices et composant Font dans Next.js 16
Dans cette leçon14
À Metropolis Quantum, les concepteurs de la ville savent que la typographie est un élément clé de l'identité visuelle de la cité. Chaque panneau, écran d'information et interface de terminal urbain utilise des caractères soigneusement choisis, non seulement esthétiques mais aussi optimisés pour la vitesse de rendu et la lisibilité sur différents appareils. Dans le monde du web, les polices jouent un rôle similaire : ce sont un élément de design important mais qui peut aussi affecter considérablement la performance d'un site.
Next.js 16 propose une façon optimisée de gérer les polices grâce au module next/font, disponible depuis Next.js 13. Dans ce chapitre, nous explorerons cette solution ainsi que les bonnes pratiques d'optimisation des polices dans les applications Next.js.
Pourquoi l'optimisation des polices est-elle importante ?
Les polices web personnalisées peuvent avoir un impact significatif sur la performance des pages :
- Un chargement de page plus lent - les polices web sont des ressources supplémentaires à télécharger
- Le scintillement du texte (FOUT - Flash of Unstyled Text) - lorsque le texte s'affiche d'abord avec la police par défaut puis bascule vers la police personnalisée une fois chargée
- Le texte invisible (FOIT - Flash of Invisible Text) - lorsque le texte est masqué jusqu'au chargement de la police
- Un impact sur les Core Web Vitals - en particulier sur le Largest Contentful Paint (LCP) et le Cumulative Layout Shift (CLS)
Le système de polices de Next.js 16 résout ces problèmes en offrant :
- Aucune requête HTTP supplémentaire vers des serveurs externes
- L'auto-hébergement automatique des fichiers de police
- Un système de fallback automatique
- Aucun décalage de mise en page
- Des indications de font-swap intégrées pour les navigateurs
Le composant Font dans Next.js 16
Next.js 16 fournit le module next/font, qui prend en charge :
- Google Fonts (
next/font/google) - Les fichiers de police locaux (
next/font/local)
Google Fonts
Voici comment utiliser Google Fonts dans Next.js 16 :
1// app/fonts.ts
2import { Inter, Roboto_Mono } from 'next/font/google';
3
4// Export variables allow reuse of the same font instances
5export const inter = Inter({
6 subsets: ['latin'],
7 display: 'swap',
8});
9
10export const roboto_mono = Roboto_Mono({
11 subsets: ['latin'],
12 display: 'swap',
13 weight: ['400', '700'],
14});Tu peux ensuite utiliser ces polices dans ton layout :
1// app/layout.tsx
2import { inter } from './fonts';
3import './globals.css';
4import type { Metadata } from 'next';
5
6export const metadata: Metadata = {
7 title: 'Metropolis Quantum',
8 description: 'Official information portal of the city of the future',
9};
10
11export default function RootLayout({
12 children,
13}: {
14 children: React.ReactNode;
15}) {
16 return (
17 <html lang="pl" className={inter.className}>
18 <body>{children}</body>
19 </html>
20 );
21}Fichiers de police locaux
Tu peux aussi utiliser des fichiers de police locaux, ce qui est recommandé pour les caractères personnalisés et non standard :
1// app/fonts.ts
2import localFont from 'next/font/local';
3
4export const quantumSans = localFont({
5 src: [
6 {
7 path: '../public/fonts/QuantumSans-Regular.woff2',
8 weight: '400',
9 style: 'normal',
10 },
11 {
12 path: '../public/fonts/QuantumSans-Bold.woff2',
13 weight: '700',
14 style: 'normal',
15 },
16 {
17 path: '../public/fonts/QuantumSans-Italic.woff2',
18 weight: '400',
19 style: 'italic',
20 },
21 ],
22 display: 'swap',
23 variable: '--font-quantum-sans',
24});Options de configuration des polices
Le composant Font dans Next.js 16 offre toute une série d'options de configuration :
Pour Google Fonts :
1import { Roboto } from 'next/font/google';
2
3const roboto = Roboto({
4 weight: ['400', '700'], // Selecting specific font weights
5 style: ['normal', 'italic'], // Selecting font styles
6 subsets: ['latin'], // Selecting character subsets
7 display: 'swap', // Display strategy: 'auto', 'block', 'swap', 'fallback', 'optional'
8 preload: true, // Whether to preload the font
9 fallback: ['system-ui', 'Arial'], // Czcionki zapasowe
10 adjustFontFallback: true, // Automatyczne dostosowywanie czcionek zapasowych
11 variable: '--font-roboto', // CSS variable if using variable API
12});Pour les polices locales :
1import localFont from 'next/font/local';
2
3const quantumDisplay = localFont({
4 src: [
5 {
6 path: './fonts/QuantumDisplay-Regular.woff2',
7 weight: '400',
8 style: 'normal',
9 },
10 {
11 path: './fonts/QuantumDisplay-Bold.woff2',
12 weight: '700',
13 style: 'normal',
14 },
15 ],
16 display: 'swap',
17 preload: true,
18 variable: '--font-quantum-display',
19 fallback: ['system-ui', 'Arial'],
20 adjustFontFallback: true,
21});Utiliser les polices dans l'application
1. Utilisation globale pour toute l'application
1// app/layout.tsx
2import { quantumSans } from './fonts';
3import './globals.css';
4
5export default function RootLayout({
6 children,
7}: {
8 children: React.ReactNode;
9}) {
10 return (
11 <html lang="pl" className={quantumSans.className}>
12 <body>{children}</body>
13 </html>
14 );
15}2. Utiliser des variables CSS pour plus de flexibilité
1// app/fonts.ts
2import { Inter, Roboto_Mono } from 'next/font/google';
3
4export const inter = Inter({
5 subsets: ['latin'],
6 display: 'swap',
7 variable: '--font-inter',
8});
9
10export const roboto_mono = Roboto_Mono({
11 subsets: ['latin'],
12 display: 'swap',
13 weight: ['400', '700'],
14 variable: '--font-roboto-mono',
15});1// app/layout.tsx
2import { inter, roboto_mono } from './fonts';
3import './globals.css';
4
5export default function RootLayout({
6 children,
7}: {
8 children: React.ReactNode;
9}) {
10 return (
11 <html lang="pl" className={`${inter.variable} ${roboto_mono.variable}`}>
12 <body>{children}</body>
13 </html>
14 );
15}1/* app/globals.css */
2:root {
3 --font-inter: 'Inter', system-ui, sans-serif;
4 --font-roboto-mono: 'Roboto Mono', monospace;
5}
6
7body {
8 font-family: var(--font-inter);
9}
10
11code {
12 font-family: var(--font-roboto-mono);
13}3. Utilisation pour des composants spécifiques
1// components/Heading.tsx
2import { quantumDisplay } from '@/app/fonts';
3
4export function Heading({ children }: { children: React.ReactNode }) {
5 return (
6 <h1 className={quantumDisplay.className}>
7 {children}
8 </h1>
9 );
10}Techniques avancées d'optimisation des polices
1. Optimiser les sous-ensembles pour différentes langues
Si ton application prend en charge plusieurs langues, tu peux optimiser les fichiers de police en ne chargeant que les sous-ensembles de caractères nécessaires :
1import { Roboto } from 'next/font/google';
2
3// Pour la page en français
4export const robotoPolish = Roboto({
5 subsets: ['latin', 'latin-ext'], // latin-ext contains characters used in Polish
6 weight: ['400', '700'],
7});
8
9// For a Japanese page
10export const robotoJapanese = Roboto({
11 subsets: ['latin', 'japanese'],
12 weight: ['400', '700'],
13});2. Utiliser les variable fonts
Les variable fonts sont un format de police moderne qui permet de stocker plusieurs styles et graisses dans un seul fichier, réduisant considérablement la quantité de données à télécharger :
1import { Roboto_Flex } from 'next/font/google';
2
3export const roboto = Roboto_Flex({
4 subsets: ['latin'],
5 display: 'swap',
6 // Variable fonts often offer a wider range of weights
7});3. Preload vs lazy loading
Par défaut, Next.js précharge les polices, mais tu peux désactiver cette fonctionnalité pour les polices qui ne sont pas utilisées immédiatement :
1import { Roboto } from 'next/font/google';
2
3// Main font, preloaded
4export const robotoMain = Roboto({
5 subsets: ['latin'],
6 weight: ['400', '700'],
7 preload: true,
8});
9
10// Font used only in some components, without preloading
11export const robotoSpecial = Roboto({
12 subsets: ['latin'],
13 weight: ['900'],
14 preload: false,
15});4. Stratégies d'affichage (font-display)
La propriété display détermine comment le navigateur doit gérer la phase de chargement de la police :
swap(par défaut) : affiche immédiatement le texte avec la police de fallback, puis la remplace par la police personnalisée une fois chargée.block: masque brièvement le texte, puis l'affiche avec la police de fallback, et bascule vers la police cible après le chargement.fallback: similaire àswap, mais avec une courte période de texte masqué. Si le chargement est trop long, la police de fallback est utilisée pour la session.optional: similaire àfallback, mais le navigateur peut complètement ignorer la police personnalisée selon les conditions réseau.
1import { Roboto } from 'next/font/google';
2
3// For main text, we use swap to ensure immediate readability
4export const robotoBody = Roboto({
5 subsets: ['latin'],
6 weight: ['400'],
7 display: 'swap',
8});
9
10// For decorative headings, we can use optional since they are not critical
11export const robotoHeading = Roboto({
12 subsets: ['latin'],
13 weight: ['900'],
14 display: 'optional',
15});Implémentation dans différents layouts
1. Layout de base avec deux polices
1// app/fonts.ts
2import { Inter, Playfair_Display } from 'next/font/google';
3
4export const inter = Inter({
5 subsets: ['latin'],
6 display: 'swap',
7 variable: '--font-sans',
8});
9
10export const playfair = Playfair_Display({
11 subsets: ['latin'],
12 display: 'swap',
13 variable: '--font-serif',
14});1// app/layout.tsx
2import { inter, playfair } from './fonts';
3import './globals.css';
4
5export default function RootLayout({
6 children,
7}: {
8 children: React.ReactNode;
9}) {
10 return (
11 <html lang="pl" className={`${inter.variable} ${playfair.variable}`}>
12 <body>
13 <header className={playfair.className}>
14 <h1>Metropolis Quantum</h1>
15 </header>
16 <main className={inter.className}>
17 {children}
18 </main>
19 </body>
20 </html>
21 );
22}1/* app/globals.css */
2:root {
3 --font-sans: 'Inter', system-ui, sans-serif;
4 --font-serif: 'Playfair Display', Georgia, serif;
5}
6
7h1, h2, h3, h4, h5, h6 {
8 font-family: var(--font-serif);
9}
10
11body {
12 font-family: var(--font-sans);
13}2. Tableau de bord avec police monospace pour les données
1// app/dashboard/layout.tsx
2import { roboto_mono } from '../fonts';
3
4export default function DashboardLayout({
5 children,
6}: {
7 children: React.ReactNode;
8}) {
9 return (
10 <div className="dashboard-layout">
11 <div className="sidebar">
12 {/* Sidebar content */}
13 </div>
14 <div className={`content ${roboto_mono.className}`}>
15 {children}
16 </div>
17 </div>
18 );
19}3. Système de composants typographiques
1// components/Typography.tsx
2import { ReactNode } from 'react';
3import { inter, playfair, roboto_mono } from '@/app/fonts';
4
5type FontVariant = 'sans' | 'serif' | 'mono';
6
7interface TypographyProps {
8 children: ReactNode;
9 variant?: FontVariant;
10 as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'div';
11 className?: string;
12}
13
14export function Typography({
15 children,
16 variant = 'sans',
17 as: Component = 'p',
18 className = '',
19}: TypographyProps) {
20 let fontClass = '';
21
22 switch (variant) {
23 case 'sans':
24 fontClass = inter.className;
25 break;
26 case 'serif':
27 fontClass = playfair.className;
28 break;
29 case 'mono':
30 fontClass = roboto_mono.className;
31 break;
32 }
33
34 return (
35 <Component className={`${fontClass} ${className}`}>
36 {children}
37 </Component>
38 );
39}Exemple d'utilisation :
1// app/page.tsx
2import { Typography } from '@/components/Typography';
3
4export default function HomePage() {
5 return (
6 <div>
7 <Typography as="h1" variant="serif" className="text-4xl mb-4">
8 Bienvenue à Metropolis Quantum
9 </Typography>
10
11 <Typography variant="sans" className="mb-6">
12 The city of the future where technology meets everyday life.
13 </Typography>
14
15 <div className="code-example">
16 <Typography variant="mono" className="text-sm">
17 console.log("Hello, Quantum World!");
18 </Typography>
19 </div>
20 </div>
21 );
22}Impact sur les Core Web Vitals
Une bonne implémentation des polices a un impact direct sur les métriques de performance clés :
Largest Contentful Paint (LCP)
Les polices personnalisées peuvent retarder le rendu du plus grand élément de contenu. Le composant Font de Next.js 16 minimise ce problème grâce à :
- L'auto-hébergement automatique des polices
- Le préchargement des polices critiques
- Des stratégies d'affichage permettant un rendu immédiat du texte
Cumulative Layout Shift (CLS)
Le calcul automatique de la taille des polices de fallback minimise les décalages de mise en page lorsque la police personnalisée est enfin chargée.
First Input Delay (FID) et Interaction to Next Paint (INP)
Les polices n'ont pas d'impact direct sur ces métriques, mais un chargement efficace des polices peut réduire la charge du thread principal du navigateur.
Analyser la performance des polices
1. Lighthouse
Utilise l'outil Lighthouse pour analyser la performance des polices :
- Ouvre les outils de développement de Chrome (F12)
- Va dans l'onglet « Lighthouse »
- Coche « Performance » et lance le test
- Vérifie les sections « Opportunities » et « Diagnostics » pour repérer d'éventuels problèmes de police
2. L'onglet Network dans les DevTools
Analyse le chargement des polices dans l'onglet Network :
- Filtre par « Font » ou « Woff2 »
- Vérifie le temps de téléchargement, la taille des fichiers et la priorité de chargement
3. WebPageTest
L'outil WebPageTest (webpagetest.org) offre une analyse détaillée du chargement des ressources, y compris les polices, sur différents appareils et connexions internet.
Bonnes pratiques
- Utilise le composant Font de Next.js 16 au lieu d'importer les polices directement depuis Google Fonts ou d'autres sources externes
- Limite le nombre de polices utilisées à 2-3 familles (par ex. une pour les titres, une pour le texte, éventuellement une monospace)
- Ne choisis que les graisses et styles nécessaires - chaque graisse supplémentaire représente des données à télécharger en plus
- Utilise des sous-ensembles spécifiques aux langues de ton application
- Envisage les variable fonts pour les familles comportant de nombreuses graisses
- Choisis la stratégie d'affichage appropriée (
display) selon l'usage de la police - Utilise des variables CSS pour plus de flexibilité dans le style
- Teste la performance sur différents appareils et connexions
Exemple d'implémentation complète
Voici un exemple d'implémentation complète d'un système de polices dans une application Next.js 16 :
1// app/fonts.ts
2import { Inter, Playfair_Display, Roboto_Mono } from 'next/font/google';
3import localFont from 'next/font/local';
4
5// Main font for text
6export const inter = Inter({
7 subsets: ['latin', 'latin-ext'],
8 display: 'swap',
9 variable: '--font-sans',
10 weight: ['400', '500', '700'],
11});
12
13// Font for headings
14export const playfair = Playfair_Display({
15 subsets: ['latin', 'latin-ext'],
16 display: 'optional',
17 variable: '--font-serif',
18 weight: ['700', '900'],
19});
20
21// Police pour le code
22export const roboto_mono = Roboto_Mono({
23 subsets: ['latin'],
24 display: 'swap',
25 variable: '--font-mono',
26 weight: ['400', '700'],
27});
28
29// Custom, non-standard font (logo and highlighted elements)
30export const quantumDisplay = localFont({
31 src: [
32 {
33 path: '../public/fonts/QuantumDisplay-Regular.woff2',
34 weight: '400',
35 style: 'normal',
36 },
37 {
38 path: '../public/fonts/QuantumDisplay-Bold.woff2',
39 weight: '700',
40 style: 'normal',
41 },
42 ],
43 display: 'swap',
44 variable: '--font-quantum',
45});1// app/layout.tsx
2import { inter, playfair, roboto_mono, quantumDisplay } from './fonts';
3import './globals.css';
4
5export default function RootLayout({
6 children,
7}: {
8 children: React.ReactNode;
9}) {
10 return (
11 <html lang="pl" className={`
12 ${inter.variable}
13 ${playfair.variable}
14 ${roboto_mono.variable}
15 ${quantumDisplay.variable}
16 `}>
17 <body className={inter.className}>{children}</body>
18 </html>
19 );
20}1/* app/globals.css */
2:root {
3 --font-sans: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
4 --font-serif: 'Playfair Display', Georgia, Cambria, 'Times New Roman', Times, serif;
5 --font-mono: 'Roboto Mono', SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
6 --font-quantum: 'Quantum Display', var(--font-sans);
7
8 /* Font sizes */
9 --fs-xs: 0.75rem;
10 --fs-sm: 0.875rem;
11 --fs-base: 1rem;
12 --fs-lg: 1.125rem;
13 --fs-xl: 1.25rem;
14 --fs-2xl: 1.5rem;
15 --fs-3xl: 1.875rem;
16 --fs-4xl: 2.25rem;
17 --fs-5xl: 3rem;
18
19 /* Line-heights */
20 --lh-tight: 1.25;
21 --lh-snug: 1.375;
22 --lh-normal: 1.5;
23 --lh-relaxed: 1.625;
24 --lh-loose: 2;
25}
26
27body {
28 font-family: var(--font-sans);
29 font-size: var(--fs-base);
30 line-height: var(--lh-normal);
31}
32
33h1, h2, h3, h4, h5, h6 {
34 font-family: var(--font-serif);
35 line-height: var(--lh-tight);
36 font-weight: 700;
37}
38
39h1 {
40 font-size: var(--fs-4xl);
41 margin-bottom: 1.5rem;
42}
43
44h2 {
45 font-size: var(--fs-3xl);
46 margin-bottom: 1.25rem;
47}
48
49.logo {
50 font-family: var(--font-quantum);
51 font-weight: 700;
52}
53
54code, pre {
55 font-family: var(--font-mono);
56 font-size: var(--fs-sm);
57}
58
59.title-quantum {
60 font-family: var(--font-quantum);
61 font-weight: 700;
62 letter-spacing: -0.025em;
63}Problèmes courants et leurs solutions
Problème 1 : FOUT (Flash of Unstyled Text)
Solution : utilise display: 'swap' et assure-toi que les polices sont préchargées.
Problème 2 : fichiers de police trop volumineux
Solution :
- Limite le nombre de graisses et de styles
- N'utilise que les sous-ensembles nécessaires
- Envisage les variable fonts
- Optimise les fichiers WOFF2 (Next.js le fait automatiquement)
Problème 3 : les polices retardent le chargement de la page
Solution :
- Pour les polices moins critiques, utilise
display: 'optional' - Pour les polices utilisées uniquement dans certains composants, désactive le préchargement
Problème 4 : différences d'apparence entre la police de fallback et la police personnalisée
Solution : Next.js 16 ajuste automatiquement les métriques de la police de fallback à celles de la police cible, minimisant les décalages. Tu peux aussi utiliser adjustFontFallback: true.
Compatibilité des navigateurs
Le composant Font de Next.js 16 livre automatiquement les polices au format WOFF2, qui est pris en charge par tous les navigateurs modernes. Pour les anciens navigateurs qui ne prennent pas en charge le WOFF2, les polices de fallback définies dans la configuration sont affichées.
Prise en charge des langues aux systèmes d'écriture non standard
Lorsque tu travailles sur des applications multilingues, n'oublie pas :
- Des sous-ensembles appropriés pour chaque langue
- Des fichiers plus volumineux pour les langues aux systèmes de caractères étendus (par ex. le chinois, le japonais)
- La performance de rendu - certains systèmes d'écriture complexes peuvent solliciter le navigateur
1// Example for a multilingual application
2import { Noto_Sans_JP, Noto_Sans } from 'next/font/google';
3
4// For Latin languages (e.g., English, Polish)
5export const notoSansLatin = Noto_Sans({
6 subsets: ['latin', 'latin-ext'],
7 weight: ['400', '700'],
8 variable: '--font-latin',
9});
10
11// For Japanese language
12export const notoSansJP = Noto_Sans_JP({
13 subsets: ['japanese'],
14 weight: ['400', '700'],
15 variable: '--font-japanese',
16});Résumé
Le composant Font de Next.js 16 fournit une solution complète pour gérer et optimiser les polices dans les applications web :
- L'auto-hébergement automatique - élimine les requêtes HTTP externes
- Le format WOFF2 optimisé - des fichiers plus petits à télécharger
- La prévention des décalages de mise en page - un meilleur CLS
- Les stratégies d'affichage - le contrôle du comportement de chargement des polices
- Le preload et le lazy loading - une utilisation optimale de la bande passante réseau
Tout comme à Metropolis Quantum, où chaque aspect de la communication visuelle est soigneusement conçu et optimisé, un système de polices bien implémenté dans Next.js 16 garantit l'équilibre parfait entre esthétique et performance. Grâce au composant Font, les applications Next.js peuvent offrir une expérience typographique cohérente, belle et performante sans compromis sur la performance.
Dans le prochain chapitre, nous aborderons la gestion des assets statiques dans le répertoire public, ce qui nous permettra de mieux comprendre comment organiser et servir efficacement différents types de ressources dans les applications Next.js 16.
Code de cette leçon : app/components/DesignSystem.tsx
1// Design System - Quantum UI Library
2'use client';
3
4import styles from './DesignSystem.module.css';
5
6// Design Tokens jako const
7export const tokens = {
8 colors: {
9 primary: { main: '#64ffda', light: '#96ffe6', dark: '#32cc99' },
10 secondary: { main: '#448aff', light: '#80b3ff', dark: '#0056cc' },
11 accent: { main: '#7c4dff', light: '#b47cff', dark: '#4400cc' },
12 neutral: { gray900: '#0f0f23', gray700: '#1a1a2e', gray500: '#3d3d55' }
13 },
14 spacing: { xs: '0.25rem', sm: '0.5rem', md: '1rem', lg: '1.5rem', xl: '2rem' },
15 typography: {
16 fontFamily: { primary: 'Inter, sans-serif', mono: 'Fira Code, monospace' },
17 fontSize: { sm: '0.875rem', base: '1rem', lg: '1.125rem', xl: '1.25rem', '2xl': '1.5rem' },
18 fontWeight: { regular: 400, medium: 500, semibold: 600, bold: 700 }
19 },
20 borderRadius: { sm: '0.25rem', md: '0.5rem', lg: '0.75rem', xl: '1rem' },
21 shadows: {
22 sm: '0 2px 8px rgba(0,0,0,0.15)',
23 md: '0 4px 16px rgba(0,0,0,0.25)',
24 lg: '0 8px 32px rgba(0,0,0,0.35)',
25 neon: '0 0 20px rgba(100,255,218,0.5)'
26 }
27};
28
29export default function DesignSystemDemo() {
30 return (
31 <div className={styles.container}>
32 <h1 className={styles.title}>Quantum Design System</h1>
33
34 {/* Color Palette */}
35 <section className={styles.section}>
36 <h2 className={styles.sectionTitle}>Color Palette</h2>
37 <div className={styles.colorGrid}>
38 <div className={styles.colorCard}>
39 <div className={styles.colorSwatch} style={{background: tokens.colors.primary.main}}></div>
40 <p>Primary</p>
41 <code>{tokens.colors.primary.main}</code>
42 </div>
43 <div className={styles.colorCard}>
44 <div className={styles.colorSwatch} style={{background: tokens.colors.secondary.main}}></div>
45 <p>Secondary</p>
46 <code>{tokens.colors.secondary.main}</code>
47 </div>
48 <div className={styles.colorCard}>
49 <div className={styles.colorSwatch} style={{background: tokens.colors.accent.main}}></div>
50 <p>Accent</p>
51 <code>{tokens.colors.accent.main}</code>
52 </div>
53 </div>
54 </section>
55
56 {/* Typography */}
57 <section className={styles.section}>
58 <h2 className={styles.sectionTitle}>Typography Scale</h2>
59 <div className={styles.typographyDemo}>
60 <p style={{fontSize: tokens.typography.fontSize['2xl'], fontWeight: tokens.typography.fontWeight.bold}}>
61 Heading 2XL
62 </p>
63 <p style={{fontSize: tokens.typography.fontSize.xl, fontWeight: tokens.typography.fontWeight.semibold}}>
64 Heading XL
65 </p>
66 <p style={{fontSize: tokens.typography.fontSize.lg, fontWeight: tokens.typography.fontWeight.medium}}>
67 Heading LG
68 </p>
69 <p style={{fontSize: tokens.typography.fontSize.base}}>
70 Body Text Base
71 </p>
72 <p style={{fontSize: tokens.typography.fontSize.sm}}>
73 Small Text
74 </p>
75 </div>
76 </section>
77
78 {/* Component Library */}
79 <section className={styles.section}>
80 <h2 className={styles.sectionTitle}>Component Library</h2>
81
82 {/* Buttons */}
83 <div className={styles.componentGroup}>
84 <h3>Buttons</h3>
85 <div className={styles.buttonShowcase}>
86 <button className={styles.btnPrimary}>Primary</button>
87 <button className={styles.btnSecondary}>Secondary</button>
88 <button className={styles.btnOutline}>Outline</button>
89 <button className={styles.btnGhost}>Ghost</button>
90 </div>
91 </div>
92
93 {/* Cards */}
94 <div className={styles.componentGroup}>
95 <h3>Cards</h3>
96 <div className={styles.cardShowcase}>
97 <div className={styles.card}>
98 <h4>Standard Card</h4>
99 <p>This is a standard card component with consistent padding and styling.</p>
100 </div>
101 <div className={styles.cardElevated}>
102 <h4>Elevated Card</h4>
103 <p>This card has elevated shadow for emphasis.</p>
104 </div>
105 <div className={styles.cardNeon}>
106 <h4>Neon Card</h4>
107 <p>Cyberpunk-styled card with neon glow effect.</p>
108 </div>
109 </div>
110 </div>
111
112 {/* Form Elements */}
113 <div className={styles.componentGroup}>
114 <h3>Form Elements</h3>
115 <div className={styles.formShowcase}>
116 <input type="text" placeholder="Text Input" className={styles.input} />
117 <select className={styles.select}>
118 <option>Select Option</option>
119 <option>Option 1</option>
120 <option>Option 2</option>
121 </select>
122 <textarea placeholder="Textarea" className={styles.textarea}></textarea>
123 </div>
124 </div>
125 </section>
126
127 {/* Spacing System */}
128 <section className={styles.section}>
129 <h2 className={styles.sectionTitle}>Spacing System</h2>
130 <div className={styles.spacingDemo}>
131 {Object.entries(tokens.spacing).map(([key, value]) => (
132 <div key={key} className={styles.spacingItem}>
133 <div className={styles.spacingBar} style={{width: value}}></div>
134 <span>{key}: {value}</span>
135 </div>
136 ))}
137 </div>
138 </section>
139
140 {/* Shadow System */}
141 <section className={styles.section}>
142 <h2 className={styles.sectionTitle}>Shadow System</h2>
143 <div className={styles.shadowGrid}>
144 <div className={styles.shadowBox} style={{boxShadow: tokens.shadows.sm}}>Small</div>
145 <div className={styles.shadowBox} style={{boxShadow: tokens.shadows.md}}>Medium</div>
146 <div className={styles.shadowBox} style={{boxShadow: tokens.shadows.lg}}>Large</div>
147 <div className={styles.shadowBox} style={{boxShadow: tokens.shadows.neon}}>Neon</div>
148 </div>
149 </section>
150 </div>
151 );
152}Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. CSS Grid sert à :
2. Flexbox est le mieux adapté à :
Tâches pratiques dans le jeu
- Clique dans l'ordre
Reconstitue la syntaxe d'une classe Tailwind avec breakpoint responsive :
- Éditeur de code
Crée un composant card en utilisant uniquement des classes Tailwind CSS (padding, shadow, border-radius, etc.)
- Tri horizontal
Reconstitue la syntaxe d'import d'un CSS Module dans Next.js :
- Clique dans l'ordre
Reconstitue la syntaxe d'import d'un CSS Module dans Next.js
- Éditeur de code
Crée du CSS avec des techniques d'optimisation : will-change, transform, contain, content-visibility