partie 3

HTML sémantique & Flexbox

Structurer sa page avec du sens, puis la mettre en page sur un axe.

Le HTML sémantique

Jusqu'ici, <div> a servi de conteneur générique pour tout découper. Le HTML propose aussi des balises qui décrivent le rôle du bloc qu'elles contiennent, pas seulement sa présence.

<header>En-tête d'une page ou d'une section ; logo, titre, navigation principale
<nav>Regroupe les liens de navigation principaux
<main>Le contenu principal de la page ; un seul par page
<section>Un regroupement thématique de contenu, en général avec son propre titre
<article>Un contenu autonome, qui aurait du sens seul ; un projet de portfolio, un article de blog
<aside>Contenu connexe, en marge du contenu principal ; une sidebar, une note
<footer>Pied d'une page ou d'une section ; crédits, contact, liens secondaires

Accessibilité

Les lecteurs d'écran utilisent ces balises pour permettre à leurs utilisateurs de naviguer directement d'une section à l'autre.

SEO

Les moteurs de recherche comprennent mieux la structure et l'importance relative du contenu.

Lisibilité du code

Un fichier avec <header>, <main>, <footer> se comprend d'un coup d'œil, sans avoir à lire les classes.

Comparez :

<!-- avant : que des div -->
<div class="header">
  <div class="logo">Logo</div>
  <div class="nav">...</div>
</div>
<div class="content">
  <div class="post">...</div>
</div>
<div class="footer">...</div>
<!-- après : sémantique -->
<header>
  <div class="logo">Logo</div>
  <nav>...</nav>
</header>
<main>
  <article>...</article>
</main>
<footer>...</footer>

Les classes (logo, etc.) restent utilisées pour le style ; les balises sémantiques décrivent le rôle uniquement, ce sont les classes qui décrivent l'apparence. On continue d'utiliser <div> et <span> pour tout ce qui n'a pas de rôle sémantique particulier.

Quelle méthode de mise en page utiliser ?

margin: autoCentrer un élément horizontalement ; Logo, image pleine taille, conteneur
flexAligner des éléments sur un axe (ligne ou colonne) ; Barre de navigation, galerie d'images, boutons
gridCréer un layout 2D complexe ; Mise en page complète, poster, grille de produits
positionSuperposer des éléments ou les fixer ; Menu sticky, badge de notification, overlay

Grid et position sont couverts en détail dans une section dédiée.

margin: auto

→ Pour centrer horizontalement un bloc.

Important : L'élément doit avoir une largeur définie pour que cela fonctionne.

.element {
  width: 600px; /* largeur définie */
  margin: 20px auto; /* centré horizontalement, avec marge verticale de 20px */
}

flex

→ Pour positionner dynamiquement les blocs sur un axe (lignes ou colonnes).

Flexbox pour aligner des éléments dans une direction, avec un contrôle précis sur l'espacement et l'alignement.

.container {
  display: flex;
  flex-direction: row; /* ou column */
  justify-content: space-between; /* alignement sur l'axe principal */
  align-items: center; /* alignement sur l'axe transversal */
}

Comprendre les axes

Propriétés principales

Sur le conteneur :

Sur les éléments enfants :

Exemples concrets

Navigation horizontale

HTML :

<nav class="navbar">
  <div class="logo">Logo</div>
  <ul class="nav-links">
    <li><a href="#">Accueil</a></li>
    <li><a href="#">Portfolio</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>

CSS :

.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  background-color: #333;
  color: white;
}

.nav-links {
  display: flex;
  gap: 30px;
  list-style: none;
}

Galerie d'images responsive

HTML :

<div class="gallery">
  <img src="https://picsum.photos/seed/1/200" alt="Photo 1">
  <img src="https://picsum.photos/seed/2/200" alt="Photo 2">
  <img src="https://picsum.photos/seed/3/200" alt="Photo 3">
  <img src="https://picsum.photos/seed/4/200" alt="Photo 4">
  <img src="https://picsum.photos/seed/5/200" alt="Photo 5">
  <img src="https://picsum.photos/seed/6/200" alt="Photo 6">
</div>

CSS :

.gallery {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  justify-content: center;
  padding: 20px;
}

.gallery img {
  flex: 1 1 200px; /* grow, shrink, basis */
  height: 200px;
  object-fit: cover;
  border-radius: 8px;
}

Centrer verticalement et horizontalement

HTML :

<section class="hero">
  <div class="hero-content">
    <h1>Bienvenue</h1>
    <p>Découvrez mon portfolio</p>
    <button>En savoir plus</button>
  </div>
</section>

CSS :

.hero {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  text-align: center;
}

.hero-content h1 {
  font-size: 3rem;
  margin-bottom: 1rem;
}

Card avec footer en bas

HTML :

<div class="card">
  <img src="https://picsum.photos/seed/DT1-2025/400" alt="Produit" class="card-image">
  <div class="card-content">
    <h3>Titre du projet</h3>
    <p>Description du projet qui peut être plus ou moins longue selon le contenu.</p>
  </div>
  <div class="card-footer">
    <span class="year">2025</span>
    <span class="tags">typography, graphic design</span>
  </div>
</div>

CSS :

.card {
  display: flex;
  flex-direction: column;
  width: 300px;
  height: 400px;
  border: 1px solid #ddd;
  border-radius: 8px;
  overflow: hidden;
}

.card-image {
  width: 100%;
  height: 150px;
  object-fit: cover;
}

.card-content {
  flex-grow: 1; /* prend tout l'espace disponible */
  padding: 20px;
}

.card-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  background-color: #f5f5f5;
  border-top: 1px solid #ddd;
}

.card-footer span {
  font-size: 12px;
  font-style: italic;
}

Erreurs courantes

Avec margin: auto

Problème : Mon élément ne se centre pas.

Solution : Vérifiez que l'élément a une width définie (en px, %, etc.).

Avec flex

Problème : Mes éléments dépassent du conteneur.

Solution : Ajoutez flex-wrap: wrap; au conteneur pour permettre le retour à la ligne.

Problème : Je confonds justify-content et align-items.

Solution : justify-content = axe principal (horizontal si row, vertical si column) ; align-items = axe transversal (perpendiculaire)

Problème : Mon élément ne prend pas toute la hauteur.

Solution : Utilisez align-items: stretch; (c'est la valeur par défaut) ou donnez une hauteur au conteneur.

Pour aller plus loin :