Cours Next.js · Module 3: Styles et optimisation visuelle

Styles globaux et CSS Modules dans Next.js 16

15 min de lecture
Dans cette leçon9

Bienvenue à Quantum Metropolis, la ville du futur, où chaque élément de l'espace urbain possède son propre style unique, tout en maintenant une esthétique d'ensemble cohérente. Comme dans cette ville futuriste, dans les applications Next.js 16 nous avons besoin à la fois de règles de style globales qui définissent l'apparence générale, et de styles locaux et modulaires qui évitent les conflits et maintiennent l'ordre.

Dans ce chapitre, nous allons explorer deux approches clés du style dans Next.js 16 :

  1. Les styles globaux - qui affectent toute l'application
  2. Les CSS Modules - qui permettent un style de composant local et encapsulé

Les styles globaux dans Next.js 16

À Quantum Metropolis, les éléments d'infrastructure fondamentaux comme le système de transport, l'éclairage et la signalétique ont une apparence uniforme dans toute la ville. De même, dans les applications web, nous avons besoin de règles de style globales pour les éléments de base comme la typographie, les couleurs, les marges et les grilles.

Le fichier global.css

Dans Next.js 16, les styles globaux sont le plus souvent définis dans le fichier app/globals.css, qui est ensuite importé dans le layout principal de l'application. Voici à quoi ressemble une structure typique :

1// app/layout.tsx
2import './globals.css';
3import type { Metadata } from 'next';
4
5export const metadata: Metadata = {
6  title: 'Metropolis Quantum',
7  description: 'Your gateway to the city of the future',
8};
9
10export default function RootLayout({
11  children,
12}: {
13  children: React.ReactNode;
14}) {
15  return (
16    <html lang="pl">
17      <body>{children}</body>
18    </html>
19  );
20}

Le contenu du fichier globals.css pourrait ressembler à ceci :

1/* app/globals.css */
2:root {
3  --primary-color: #3a86ff;
4  --secondary-color: #8338ec;
5  --accent-color: #ff006e;
6  --background-light: #f8f9fa;
7  --background-dark: #212529;
8  --text-light: #f8f9fa;
9  --text-dark: #212529;
10  --spacing-unit: 0.5rem;
11  --border-radius: 0.375rem;
12}
13
14* {
15  box-sizing: border-box;
16  padding: 0;
17  margin: 0;
18}
19
20html,
21body {
22  max-width: 100vw;
23  overflow-x: hidden;
24  font-family: 'Quantum Sans', sans-serif;
25}
26
27body {
28  color: var(--text-dark);
29  background: var(--background-light);
30}
31
32a {
33  color: var(--primary-color);
34  text-decoration: none;
35}
36
37h1, h2, h3, h4, h5, h6 {
38  font-family: 'Quantum Display', sans-serif;
39  margin-bottom: var(--spacing-unit);
40}
41
42.container {
43  width: 100%;
44  max-width: 1200px;
45  margin: 0 auto;
46  padding: 0 var(--spacing-unit);
47}
48
49@media (prefers-color-scheme: dark) {
50  body {
51    color: var(--text-light);
52    background: var(--background-dark);
53  }
54}

Reset et normalisation CSS

C'est souvent une bonne pratique de commencer par un CSS Reset ou une normalisation, qui élimine les différences entre les styles par défaut des différents navigateurs. Tu peux utiliser des solutions populaires comme :

  • normalize.css
  • reset.css
  • Une solution sur mesure

Par exemple, tu peux installer normalize.css via npm et l'importer au début du fichier globals.css :

1npm install normalize.css
1/* app/globals.css */
2@import 'normalize.css';
3
4/* Rest of global styles */

Utiliser les variables CSS

Comme tu peux le voir dans l'exemple ci-dessus, les variables CSS (custom properties) sont un outil puissant pour définir des valeurs globales qui peuvent ensuite être utilisées dans toute l'application :

1:root {
2  --primary-color: #3a86ff;
3  --spacing-large: 2rem;
4}
5
6.button {
7  background-color: var(--primary-color);
8  padding: var(--spacing-large);
9}

Cette approche permet de gérer facilement les palettes de couleurs, les espacements, les tailles de police et d'autres valeurs récurrentes.

Styles globaux pour des routes spécifiques

Dans Next.js 16, tu peux aussi définir des styles globaux qui ne s'appliqueront qu'à certaines routes ou layouts. Cela se fait via des fichiers layout.tsx dans des répertoires spécifiques :

1// app/dashboard/layout.tsx
2import '../dashboard-styles.css';
3
4export default function DashboardLayout({
5  children,
6}: {
7  children: React.ReactNode;
8}) {
9  return <div className="dashboard-container">{children}</div>;
10}

Ces styles ne s'appliqueront qu'aux pages situées dans le répertoire /dashboard.

CSS Modules : l'encapsulation des styles

À Quantum Metropolis, chaque quartier possède sa propre esthétique unique : le Quartier Quantique regorge d'éléments futuristes et holographiques, tandis que la Vieille Ville mêle modernité et architecture rétro. Malgré ces différences, tous les quartiers forment un ensemble cohérent.

Les CSS Modules fonctionnent de manière similaire : ils permettent de créer des styles locaux et encapsulés pour les composants, qui n'affecteront pas le reste de l'application.

Les bases des CSS Modules

Les CSS Modules sont une technique qui crée automatiquement des noms de classe CSS uniques, évitant ainsi les conflits. Dans Next.js 16, tout fichier portant l'extension .module.css est traité comme un module CSS.

Créer et utiliser un module CSS :

1/* Button.module.css */
2.button {
3  padding: 0.75rem 1.5rem;
4  border-radius: 0.375rem;
5  font-weight: 600;
6  transition: all 0.2s;
7}
8
9.primary {
10  background-color: var(--primary-color);
11  color: white;
12}
13
14.secondary {
15  background-color: var(--secondary-color);
16  color: white;
17}
18
19.button:hover {
20  transform: translateY(-2px);
21  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
22}
1// components/Button.tsx
2import styles from './Button.module.css';
3
4interface ButtonProps {
5  variant?: 'primary' | 'secondary';
6  children: React.ReactNode;
7  onClick?: () => void;
8}
9
10export default function Button({ variant = 'primary', children, onClick }: ButtonProps) {
11  return (
12    <button
13      className={`${styles.button} ${styles[variant]}`}
14      onClick={onClick}
15    >
16      {children}
17    </button>
18  );
19}

Comment fonctionnent les CSS Modules

Lors de la construction de l'application, Next.js traite les fichiers .module.css et génère des noms de classe uniques. Par exemple, la classe .button de l'exemple ci-dessus peut être transformée en .Button_button__XYZ123. Grâce à cela, même si tu définis une classe portant le même nom dans un autre composant, il n'y aura aucun conflit.

Accéder aux variables CSS globales

Les CSS Modules peuvent utiliser les variables CSS globales définies dans globals.css :

1/* Card.module.css */
2.card {
3  background-color: white;
4  border-radius: var(--border-radius);
5  padding: calc(var(--spacing-unit) * 2);
6  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
7}

Composer des classes

Les CSS Modules permettent de composer des classes grâce à la syntaxe composes :

1/* Text.module.css */
2.base {
3  font-family: 'Quantum Sans', sans-serif;
4  line-height: 1.5;
5}
6
7.heading {
8  composes: base;
9  font-weight: 700;
10  line-height: 1.2;
11}
12
13.paragraph {
14  composes: base;
15  margin-bottom: 1rem;
16}

Styles dynamiques avec les CSS Modules

Tu peux appliquer des classes de façon dynamique selon l'état du composant :

1// components/Alert.tsx
2import { useState } from 'react';
3import styles from './Alert.module.css';
4
5interface AlertProps {
6  type: 'info' | 'success' | 'warning' | 'error';
7  message: string;
8}
9
10export default function Alert({ type, message }: AlertProps) {
11  const [isVisible, setIsVisible] = useState(true);
12
13  if (!isVisible) return null;
14
15  return (
16    <div className={`${styles.alert} ${styles[type]} ${isVisible ? styles.visible : ''}`}>
17      <p>{message}</p>
18      <button
19        className={styles.closeButton}
20        onClick={() => setIsVisible(false)}
21      >
22        &times;
23      </button>
24    </div>
25  );
26}
1/* Alert.module.css */
2.alert {
3  padding: 1rem;
4  border-radius: var(--border-radius);
5  margin-bottom: 1rem;
6  display: flex;
7  justify-content: space-between;
8  align-items: center;
9}
10
11.info {
12  background-color: #e3f2fd;
13  color: #0d47a1;
14}
15
16.success {
17  background-color: #e8f5e9;
18  color: #1b5e20;
19}
20
21.warning {
22  background-color: #fff3e0;
23  color: #e65100;
24}
25
26.error {
27  background-color: #ffebee;
28  color: #b71c1c;
29}
30
31.visible {
32  opacity: 1;
33  transition: opacity 0.3s ease-in;
34}
35
36.closeButton {
37  background: none;
38  border: none;
39  font-size: 1.5rem;
40  cursor: pointer;
41  opacity: 0.7;
42}
43
44.closeButton:hover {
45  opacity: 1;
46}

Combiner styles globaux et CSS Modules

Dans les applications réelles, on utilise le plus souvent les deux approches :

  1. Les styles globaux pour :

    • Les resets CSS
    • Les éléments typographiques de base
    • Les variables (couleurs, espacements, ombres, etc.)
    • Les classes utilitaires
  2. Les CSS Modules pour :

    • Les composants spécifiques
    • Les éléments qui peuvent avoir des styles différents selon le contexte

Exemple : structure de projet

1app/
2├── layout.tsx
3├── page.tsx
4├── globals.css
5├── dashboard/
6│   ├── layout.tsx
7│   ├── page.tsx
8│   └── dashboard.module.css
9└── components/
10    ├── Button/
11    │   ├── Button.tsx
12    │   └── Button.module.css
13    ├── Card/
14    │   ├── Card.tsx
15    │   └── Card.module.css
16    └──

Approches de style alternatives dans Next.js 16

Outre les styles globaux et les CSS Modules, Next.js 16 prend également en charge d'autres approches de style :

1. Styled JSX

Next.js prend en charge nativement Styled JSX, qui permet de créer des styles locaux directement dans les composants :

1export default function Button() {
2  return (
3    <>
4      <button>Cliquez-moi</button>
5      <style jsx>{`
6        button {
7          padding: 0.5rem 1rem;
8          background-color: #3a86ff;
9          color: white;
10          border: none;
11          border-radius: 0.25rem;
12        }
13        button:hover {
14          background-color: #2563eb;
15        }
16      `}</style>
17    </>
18  );
19}

2. Sass/SCSS

Next.js prend aussi en charge Sass/SCSS. Il suffit d'installer sass :

1npm install sass

Tu peux ensuite créer des fichiers .scss ou .sass, y compris des modules CSS avec l'extension .module.scss :

1// Button.module.scss
2$primary-color: #3a86ff;
3
4.button {
5  padding: 0.75rem 1.5rem;
6  background-color: $primary-color;
7
8  &:hover {
9    background-color: darken($primary-color, 10%);
10  }
11
12  .icon {
13    margin-right: 0.5rem;
14  }
15}

3. CSS-in-JS

Next.js prend également en charge les bibliothèques CSS-in-JS comme styled-components et emotion. Pour ces bibliothèques, une configuration supplémentaire est nécessaire pour fonctionner avec le SSR (Server-Side Rendering) :

1// components/StyledButton.tsx
2import styled from 'styled-components';
3
4const StyledButton = styled.button`
5  padding: 0.75rem 1.5rem;
6  background-color: #3a86ff;
7  color: white;
8  border: none;
9  border-radius: 0.25rem;
10
11  &:hover {
12    background-color: #2563eb;
13  }
14`;
15
16export default function Button({ children }) {
17  return <StyledButton>{children}</StyledButton>;
18}

Pour que styled-components fonctionne avec le SSR, tu dois créer ton propre document dans Next.js :

1// app/registry.tsx
2'use client';
3
4import { useState } from 'react';
5import { useServerInsertedHTML } from 'next/navigation';
6import { ServerStyleSheet, StyleSheetManager } from 'styled-components';
7
8export default function StyledComponentsRegistry({
9  children,
10}: {
11  children: React.ReactNode;
12}) {
13  const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet());
14
15  useServerInsertedHTML(() => {
16    const styles = styledComponentsStyleSheet.getStyleElement();
17    styledComponentsStyleSheet.instance.clearTag();
18    return <>{styles}</>;
19  });
20
21  if (typeof window !== 'undefined') return <>{children}</>;
22
23  return (
24    <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
25      {children}
26    </StyleSheetManager>
27  );
28}
1// app/layout.tsx
2import StyledComponentsRegistry from './registry';
3import './globals.css';
4
5export default function RootLayout({
6  children,
7}: {
8  children: React.ReactNode;
9}) {
10  return (
11    <html>
12      <body>
13        <StyledComponentsRegistry>{children}</StyledComponentsRegistry>
14      </body>
15    </html>
16  );
17}

Exemples pratiques

Exemple 1 : créer un système de grille

1/* app/globals.css */
2.row {
3  display: flex;
4  flex-wrap: wrap;
5  margin: 0 -1rem;
6}
7
8.col {
9  padding: 0 1rem;
10}
11
12.col-1 { flex: 0 0 8.333%; max-width: 8.333%; }
13.col-2 { flex: 0 0 16.666%; max-width: 16.666%; }
14.col-3 { flex: 0 0 25%; max-width: 25%; }
15.col-4 { flex: 0 0 33.333%; max-width: 33.333%; }
16.col-5 { flex: 0 0 41.666%; max-width: 41.666%; }
17.col-6 { flex: 0 0 50%; max-width: 50%; }
18.col-7 { flex: 0 0 58.333%; max-width: 58.333%; }
19.col-8 { flex: 0 0 66.666%; max-width: 66.666%; }
20.col-9 { flex: 0 0 75%; max-width: 75%; }
21.col-10 { flex: 0 0 83.333%; max-width: 83.333%; }
22.col-11 { flex: 0 0 91.666%; max-width: 91.666%; }
23.col-12 { flex: 0 0 100%; max-width: 100%; }
24
25@media (max-width: 768px) {
26  .col-md-12 { flex: 0 0 100%; max-width: 100%; }
27  .col-md-6 { flex: 0 0 50%; max-width: 50%; }
28  .col-md-4 { flex: 0 0 33.333%; max-width: 33.333%; }
29}
30
31@media (max-width: 576px) {
32  .col-sm-12 { flex: 0 0 100%; max-width: 100%; }
33  .col-sm-6 { flex: 0 0 50%; max-width: 50%; }
34}

Utilisation dans un composant :

1// app/page.tsx
2export default function Home() {
3  return (
4    <div className="container">
5      <div className="row">
6        <div className="col col-4 col-md-6 col-sm-12">
7          <div className="card">Kolumna 1</div>
8        </div>
9        <div className="col col-4 col-md-6 col-sm-12">
10          <div className="card">Kolumna 2</div>
11        </div>
12        <div className="col col-4 col-md-12 col-sm-12">
13          <div className="card">Kolumna 3</div>
14        </div>
15      </div>
16    </div>
17  );
18}

Exemple 2 : styliser des formulaires

1/* Form.module.css */
2.form {
3  margin-bottom: 2rem;
4}
5
6.formGroup {
7  margin-bottom: 1rem;
8}
9
10.label {
11  display: block;
12  margin-bottom: 0.5rem;
13  font-weight: 500;
14}
15
16.input {
17  display: block;
18  width: 100%;
19  padding: 0.75rem;
20  font-size: 1rem;
21  border: 1px solid #ddd;
22  border-radius: var(--border-radius);
23  background-color: white;
24}
25
26.input:focus {
27  outline: none;
28  border-color: var(--primary-color);
29  box-shadow: 0 0 0 3px rgba(58, 134, 255, 0.2);
30}
31
32.error {
33  color: var(--accent-color);
34  font-size: 0.875rem;
35  margin-top: 0.25rem;
36}
37
38.submitButton {
39  composes: button from './Button.module.css';
40  composes: primary from './Button.module.css';
41}

Bonnes pratiques

  1. Maintiens une structure cohérente

    • Les styles globaux dans app/globals.css
    • Les modules CSS à côté des composants
    • Un nommage de fichier cohérent (par ex. ComponentName.module.css)
  2. Utilise des variables CSS pour les valeurs récurrentes

    • Les couleurs
    • Les espacements
    • Les tailles de police
    • Les rayons de bordure
    • Les ombres
  3. Crée des classes utilitaires pour les styles fréquemment utilisés

    • .text-center, .mb-2, etc.
  4. Utilise des commentaires pour une meilleure organisation

    1/*
    2 * TYPOGRAPHY
    3 * -------------
    4 */
    5
    6/*
    7 * LAYOUT
    8 * -------------
    9 */
  5. Applique des méthodologies CSS (si nécessaire)

    • BEM (Block Element Modifier)
    • SMACSS (Scalable and Modular Architecture for CSS)
    • OOCSS (Object-Oriented CSS)
  6. Préfère la composition à l'héritage

    • Combine de petites classes à usage unique plutôt que de créer de grands sélecteurs complexes

Performance et style

Next.js 16 optimise automatiquement le CSS :

  1. Lors du build de production, le CSS est minifié
  2. Les CSS Modules sont traités et des noms de classe uniques sont générés
  3. Les styles critiques sont automatiquement injectés dans la balise <head>

Pour les applications plus grandes, il vaut la peine d'envisager :

  1. Le code splitting du CSS

    • Le CSS est divisé en fichiers plus petits et chargé uniquement quand c'est nécessaire
    • Dans Next.js, cela se fait automatiquement pour les CSS Modules
  2. L'utilisation d'outils pour éliminer le CSS inutilisé

    • PurgeCSS
    • Unused CSS (ucss)

Exemples étendus et applications

Système de composants utilisant les CSS Modules

Voici un exemple de système de composants étendu utilisant les CSS Modules dans une application Next.js 16 :

  1. Structure des répertoires :
1components/
2├── ui/
3│   ├── Button/
4│   │   ├── Button.tsx
5│   │   └── Button.module.css
6│   ├── Card/
7│   │   ├── Card.tsx
8│   │   └── Card.module.css
9│   ├── Input/
10│   │   ├── Input.tsx
11│   │   └── Input.module.css
12│   └──
13├── layout/
14│   ├── Header/
15│   │   ├── Header.tsx
16│   │   └── Header.module.css
17│   ├── Footer/
18│   │   ├── Footer.tsx
19│   │   └── Footer.module.css
20│   └──
21└──
  1. Le composant Button avec différentes variantes :
1// components/ui/Button/Button.tsx
2import styles from './Button.module.css';
3import { ReactNode } from 'react';
4
5type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'outline' | 'text';
6type ButtonSize = 'sm' | 'md' | 'lg';
7
8interface ButtonProps {
9  variant?: ButtonVariant;
10  size?: ButtonSize;
11  children: ReactNode;
12  onClick?: () => void;
13  disabled?: boolean;
14  fullWidth?: boolean;
15  icon?: ReactNode;
16  iconPosition?: 'left' | 'right';
17  className?: string;
18}
19
20export function Button({
21  variant = 'primary',
22  size = 'md',
23  children,
24  onClick,
25  disabled = false,
26  fullWidth = false,
27  icon,
28  iconPosition = 'left',
29  className = '',
30}: ButtonProps) {
31  const buttonClasses = [
32    styles.button,
33    styles[variant],
34    styles[size],
35    fullWidth ? styles.fullWidth : '',
36    icon ? styles.hasIcon : '',
37    icon && iconPosition === 'right' ? styles.iconRight : '',
38    disabled ? styles.disabled : '',
39    className
40  ].filter(Boolean).join(' ');
41
42  return (
43    <button
44      className={buttonClasses}
45      onClick={onClick}
46      disabled={disabled}
47    >
48      {icon && iconPosition === 'left' && (
49        <span className={styles.icon}>{icon}</span>
50      )}
51      <span className={styles.text}>{children}</span>
52      {icon && iconPosition === 'right' && (
53        <span className={styles.icon}>{icon}</span>
54      )}
55    </button>
56  );
57}
1/* components/ui/Button/Button.module.css */
2.button {
3  display: inline-flex;
4  align-items: center;
5  justify-content: center;
6  font-weight: 500;
7  border: none;
8  border-radius: var(--border-radius);
9  cursor: pointer;
10  transition: all 0.2s ease;
11  font-family: inherit;
12}
13
14/* Variants */
15.primary {
16  background-color: var(--primary-color);
17  color: white;
18}
19
20.primary:hover {
21  background-color: var(--primary-dark);
22}
23
24.secondary {
25  background-color: var(--secondary-color);
26  color: white;
27}
28
29.secondary:hover {
30  background-color: var(--secondary-dark);
31}
32
33.tertiary {
34  background-color: var(--tertiary-color);
35  color: white;
36}
37
38.tertiary:hover {
39  background-color: var(--tertiary-dark);
40}
41
42.outline {
43  background-color: transparent;
44  border: 1px solid var(--primary-color);
45  color: var(--primary-color);
46}
47
48.outline:hover {
49  background-color: rgba(58, 134, 255, 0.1);
50}
51
52.text {
53  background-color: transparent;
54  color: var(--primary-color);
55  padding-left: 0;
56  padding-right: 0;
57}
58
59.text:hover {
60  background-color: transparent;
61  color: var(--primary-dark);
62  text-decoration: underline;
63}
64
65/* Sizes */
66.sm {
67  font-size: 0.875rem;
68  padding: 0.5rem 1rem;
69}
70
71.md {
72  font-size: 1rem;
73  padding: 0.75rem 1.5rem;
74}
75
76.lg {
77  font-size: 1.125rem;
78  padding: 1rem 2rem;
79}
80
81/* Modifiers */
82.fullWidth {
83  width: 100%;
84}
85
86.hasIcon {
87  gap: 0.5rem;
88}
89
90.iconRight {
91  flex-direction: row-reverse;
92}
93
94.disabled {
95  opacity: 0.6;
96  cursor: not-allowed;
97}
98
99.disabled:hover {
100  background-color: var(--primary-color);
101}
102
103.outline.disabled:hover {
104  background-color: transparent;
105}
106
107.text.disabled:hover {
108  background-color: transparent;
109  text-decoration: none;
110}
111
112.icon {
113  display: flex;
114  align-items: center;
115  justify-content: center;
116}
117
118.button .text {
119  display: inline-block;
120}
  1. Utilisation du composant Button :
1// app/examples/page.tsx
2import { Button } from '@/components/ui/Button/Button';
3import { FiDownload, FiHeart, FiArrowRight } from 'react-icons/fi';
4
5export default function ButtonExamplesPage() {
6  return (
7    <div className="container">
8      <h1>Button Examples</h1>
9
10      <h2>Warianty</h2>
11      <div className="button-group">
12        <Button variant="primary">Primary</Button>
13        <Button variant="secondary">Secondary</Button>
14        <Button variant="tertiary">Tertiary</Button>
15        <Button variant="outline">Outline</Button>
16        <Button variant="text">Text</Button>
17      </div>
18
19      <h2>Tailles</h2>
20      <div className="button-group">
21        <Button size="sm">Small</Button>
22        <Button size="md">Medium</Button>
23        <Button size="lg">Large</Button>
24      </div>
25
26      <h2>Z ikonami</h2>
27      <div className="button-group">
28        <Button icon={<FiDownload />}>Télécharger</Button>
29        <Button icon={<FiHeart />} variant="outline">Polub</Button>
30        <Button icon={<FiArrowRight />} iconPosition="right">
31          Continue
32        </Button>
33      </div>
34
35      <h2>Full Width</h2>
36      <Button fullWidth>Full Width Button</Button>
37
38      <h2>Disabled</h2>
39      <div className="button-group">
40        <Button disabled>Disabled Button</Button>
41        <Button variant="outline" disabled>Disabled Outline</Button>
42      </div>
43    </div>
44  );
45}

Résumé

Le style dans Next.js 16 est flexible et autorise différentes approches, des styles globaux aux CSS Modules encapsulés. Comme à Quantum Metropolis, où l'esthétique de la ville entière est cohérente mais où chaque quartier conserve son caractère unique, dans les applications Next.js nous pouvons combiner des règles globales avec des styles de composant locaux.

Points clés à retenir :

  1. Les styles globaux sont idéaux pour définir des règles générales, des variables et des classes utilitaires
  2. Les CSS Modules offrent un style local sans conflit, idéal pour les composants
  3. Next.js 16 prend aussi en charge Sass, Styled JSX et les bibliothèques CSS-in-JS
  4. De bonnes pratiques d'organisation des styles améliorent la lisibilité et facilitent la maintenance du code

Dans le prochain chapitre, nous étudierons l'intégration de Tailwind CSS, un framework CSS utility-first populaire qui peut considérablement accélérer le processus de style dans Next.js 16.

Code de cette leçon : app/layout.tsx
1// Root Layout with Global Styles
2import { ReactNode } from 'react';
3import './globals.css';
4
5interface RootLayoutProps {
6  children: ReactNode;
7}
8
9export const metadata = {
10  title: 'Metropolis Quantum - Styling System',
11  description: 'CSS Modules and Global Styles in Next.js 16',
12};
13
14export default function RootLayout({ children }: RootLayoutProps) {
15  console.log("Styling system initialized");
16
17  return (
18    <html lang="en" className="theme-system">
19      <body>
20        <div className="metropolis-app">
21          <header className="global-header">
22            <div className="header-container">
23              <h1 className="logo">Metropolis Quantum</h1>
24              <nav className="main-nav">
25                <a href="/" className="nav-link">Home</a>
26                <a href="/themes" className="nav-link">Themes</a>
27                <a href="/components" className="nav-link">Components</a>
28                <a href="/animations" className="nav-link">Animations</a>
29              </nav>
30              <button className="theme-toggle" onclick="toggleTheme()">
31                Dark Mode
32              </button>
33            </div>
34          </header>
35
36          <main className="main-content">
37            {children}
38          </main>
39
40          <footer className="global-footer">
41            <p>Styled with CSS Modules & Global CSS • Next.js 16</p>
42          </footer>
43        </div>
44      </body>
45    </html>
46  );
47}

Tu as repéré une erreur dans cette leçon ?

Articles utiles