Cours HTML et CSS · Module 9: CSS moderne

Fonctionnalités CSS modernes - L'avenir de la mise en forme des hiéroglyphes égyptiens

9 min de lecture
Dans cette leçon12

Bienvenue dans le futur du CSS ! Tout comme les anciens Égyptiens étaient des pionniers de l'architecture, nous assistons à une révolution du CSS. Découvre les fonctionnalités CSS modernes de 2020-2024 qui changent notre façon de mettre en forme les sites web !

aspect-ratio - Des proportions parfaites

aspect-ratio te permet de créer facilement des éléments avec des proportions conservées sans astuces de padding !

Avant aspect-ratio (l'ancienne méthode)

1/* Ancienne astuce avec padding-bottom */
2.video-container {
3  position: relative;
4  padding-bottom: 56.25%; /* 16:9 = 9/16 = 0.5625 = 56.25% */
5  height: 0;
6}
7
8.video-container iframe {
9  position: absolute;
10  top: 0;
11  left: 0;
12  width: 100%;
13  height: 100%;
14}

Avec aspect-ratio (la nouvelle méthode)

1/* Méthode moderne - simple et lisible */
2.video-container {
3  aspect-ratio: 16 / 9;
4  width: 100%;
5}
6
7.video-container iframe {
8  width: 100%;
9  height: 100%;
10}

Analogie égyptienne : Comme les proportions parfaites de la Grande Pyramide (4:3) - conservées quelle que soit l'échelle !

Exemples pratiques d'aspect-ratio

1. Vidéo réactive

1.video-wrapper {
2  aspect-ratio: 16 / 9;
3  width: 100%;
4  max-width: 800px;
5  margin: 0 auto;
6}
7
8.video-wrapper iframe {
9  width: 100%;
10  height: 100%;
11  border: none;
12}

2. Cartes images

1.card-image {
2  aspect-ratio: 4 / 3;
3  width: 100%;
4  object-fit: cover;
5  border-radius: 8px;
6}

3. Avatars carrés

1.avatar {
2  aspect-ratio: 1;  /* 1:1 = carré */
3  width: 100px;
4  border-radius: 50%;
5  object-fit: cover;
6}

4. Nombre d'or

1.golden-box {
2  aspect-ratio: 1.618;  /* Nombre d'or */
3  width: 100%;
4  background: goldenrod;
5}

5. Post Instagram

1.instagram-post {
2  aspect-ratio: 1 / 1;  /* Carré Instagram */
3  width: 100%;
4  max-width: 600px;
5}

6. Écrans mobiles

1.phone-mockup {
2  aspect-ratio: 9 / 19.5;  /* Proportions iPhone */
3  width: 375px;
4  border: 10px solid black;
5  border-radius: 30px;
6}

gap pour Flexbox et Grid

gap fonctionne désormais à la fois dans Grid et Flexbox ! (depuis 2021)

1/* Grid - toujours pris en charge */
2.grid {
3  display: grid;
4  grid-template-columns: repeat(3, 1fr);
5  gap: 20px;  /* Gap de ligne et de colonne */
6}
7
8/* Flexbox - depuis 2021 ! */
9.flex-container {
10  display: flex;
11  gap: 20px;  /* Espace entre les éléments */
12}

Exemples pratiques de gap

1/* Navigation avec gap */
2.nav {
3  display: flex;
4  gap: 1.5rem;
5  align-items: center;
6}
7
8/* Groupe de boutons */
9.button-group {
10  display: flex;
11  gap: 0.5rem;
12}
13
14/* Champs de formulaire */
15.form {
16  display: flex;
17  flex-direction: column;
18  gap: 1rem;
19}
20
21/* Grille de cartes */
22.cards {
23  display: grid;
24  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
25  gap: 2rem 1rem;  /* 2rem ligne, 1rem colonne */
26}

:is() et :where() - Regroupement de sélecteurs

Les nouvelles pseudo-classes permettent un regroupement élégant !

:is() - avec poids de spécificité

1/* Au lieu de : */
2h1 a,
3h2 a,
4h3 a,
5h4 a,
6h5 a,
7h6 a {
8  color: goldenrod;
9}
10
11/* Utilise :is() */
12:is(h1, h2, h3, h4, h5, h6) a {
13  color: goldenrod;
14}

Spécificité de :is() : Prend la spécificité la plus élevée de la liste !

1/* Spécificité = ID (100) */
2:is(#id, .class, div) {
3  color: red;
4}

:where() - sans poids de spécificité

1/* Spécificité = 0 ! */
2:where(h1, h2, h3) {
3  margin-top: 0;
4}
5
6/* Facile à surcharger */
7h2 {
8  margin-top: 1rem;  /* Ceci l'emporte car :where() a une spécificité de 0 */
9}

Exemples pratiques

1/* Reset pour les titres */
2:where(h1, h2, h3, h4, h5, h6) {
3  margin: 0;
4  font-weight: 600;
5}
6
7/* États des liens */
8:is(a:hover, a:focus) {
9  text-decoration: underline;
10  color: goldenrod;
11}
12
13/* Champs de formulaire */
14:is(input, textarea, select):focus {
15  outline: 2px solid #3498db;
16  outline-offset: 2px;
17}
18
19/* Listes */
20:where(ul, ol):where(:not([class])) {
21  padding-left: 1.5em;
22}

:has() - Le sélecteur de parent !

:has() est une révolution - il te permet de styliser le parent en fonction des enfants !

1/* Styliser un article qui A une image */
2article:has(img) {
3  display: grid;
4  grid-template-columns: 1fr 2fr;
5}
6
7/* Styliser une carte qui A un bouton */
8.card:has(.button) {
9  padding-bottom: 4rem;
10}
11
12/* Styliser un formulaire qui A une erreur */
13form:has(.error) {
14  border: 2px solid red;
15}

Exemples pratiques de :has()

1. Adaptation de la mise en page

1/* Carte avec image - mise en page différente */
2.card:has(img) {
3  display: flex;
4  flex-direction: row;
5}
6
7/* Carte sans image - mise en page normale */
8.card:not(:has(img)) {
9  text-align: center;
10}

2. Validation de formulaire

1/* Champ de formulaire avec erreur */
2.form-field:has(input:invalid) {
3  border-color: red;
4}
5
6.form-field:has(input:valid) {
7  border-color: green;
8}
9
10/* Libellé quand l'input a le focus */
11.form-field:has(input:focus) label {
12  color: #3498db;
13  font-weight: bold;
14}

2. Stylisation des cases à cocher

1/* Styliser le libellé quand la case est cochée */
2.checkbox-wrapper:has(input:checked) label {
3  font-weight: bold;
4  color: green;
5}
6
7.checkbox-wrapper:has(input:checked) {
8  background: #e8f5e9;
9}

4. Mise en évidence de la navigation

1/* Mettre en évidence une section dans la navigation */
2nav:has(~ main #section-1) .nav-link[href="#section-1"] {
3  color: goldenrod;
4  font-weight: bold;
5}

5. État vide

1/* Styliser un conteneur quand il est vide */
2.list:not(:has(li)) {
3  display: flex;
4  align-items: center;
5  justify-content: center;
6}
7
8.list:not(:has(li))::before {
9  content: "Aucun élément trouvé";
10  color: #999;
11}

subgrid - Grilles imbriquées

subgrid permet aux enfants d'utiliser la grille du parent !

1.parent-grid {
2  display: grid;
3  grid-template-columns: repeat(4, 1fr);
4  gap: 20px;
5}
6
7.child-grid {
8  display: grid;
9  /* Utilise les colonnes du parent ! */
10  grid-template-columns: subgrid;
11  grid-column: span 2;
12}

Exemple pratique

1<div class="product-grid">
2  <article class="product">
3    <h3>Produit 1</h3>
4    <div class="product-details">
5      <span class="price">$99</span>
6      <button>Acheter</button>
7    </div>
8  </article>
9</div>
1.product-grid {
2  display: grid;
3  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
4  gap: 2rem;
5}
6
7.product {
8  display: grid;
9  /* Aligner tous les .product-details sur la même ligne */
10  grid-template-rows: auto 1fr auto;
11}
12
13.product-details {
14  display: grid;
15  grid-template-columns: subgrid;
16  grid-column: 1 / -1;
17  align-items: center;
18}

@layer - Cascade Layers

@layer te permet de contrôler la cascade sans spécificité !

1/* Définir l'ordre des couches */
2@layer reset, base, components, utilities;
3
4/* Couche reset - priorité la plus basse */
5@layer reset {
6  * {
7    margin: 0;
8    padding: 0;
9  }
10}
11
12/* Couche base */
13@layer base {
14  body {
15    font-family: Arial, sans-serif;
16  }
17}
18
19/* Couche components */
20@layer components {
21  .button {
22    background: #3498db;
23    color: white;
24  }
25}
26
27/* Couche utilities - priorité la plus élevée */
28@layer utilities {
29  .text-center {
30    text-align: center;
31  }
32}

@container - Container Queries

Les Container Queries te permettent de styliser en fonction de la taille du conteneur, et non du viewport !

1.card-container {
2  container-type: inline-size;
3  container-name: card;
4}
5
6.card {
7  padding: 1rem;
8}
9
10/* Quand le conteneur > 400px */
11@container card (min-width: 400px) {
12  .card {
13    display: flex;
14    gap: 1rem;
15  }
16
17  .card img {
18    width: 150px;
19  }
20}
21
22/* Quand le conteneur > 600px */
23@container card (min-width: 600px) {
24  .card {
25    padding: 2rem;
26  }
27}

color-mix() - Mélange de couleurs

1.element {
2  /* Mélanger 50% de bleu avec 50% de rouge */
3  background: color-mix(in srgb, blue 50%, red);
4
5  /* Éclaircir une couleur */
6  background: color-mix(in srgb, #3498db, white 20%);
7
8  /* Assombrir une couleur */
9  background: color-mix(in srgb, #3498db, black 20%);
10}

accent-color - Colorer les contrôles de formulaire

1/* Changer la couleur des cases à cocher, boutons radio, curseurs */
2input[type="checkbox"],
3input[type="radio"],
4input[type="range"] {
5  accent-color: goldenrod;
6}
7
8/* Globalement */
9:root {
10  accent-color: #3498db;
11}

Autres propriétés modernes

overflow: clip

1.element {
2  /* Comme overflow: hidden, mais ne crée pas de contexte de défilement */
3  overflow: clip;
4}

inset - Raccourci pour top/right/bottom/left

1/* Au lieu de : */
2.element {
3  top: 0;
4  right: 0;
5  bottom: 0;
6  left: 0;
7}
8
9/* Utilise inset */
10.element {
11  inset: 0;
12}
13
14/* Ou par côté */
15.element {
16  inset: 10px 20px;  /* top/bottom left/right */
17}

object-view-box - Recadrage d'image

1img {
2  object-view-box: inset(10% 20% 10% 20%);
3  /* Recadre l'image de tous les côtés */
4}

content-visibility - Performance

1.long-section {
2  /* Ne pas rendre en dehors du viewport - ÉNORME gain de performance ! */
3  content-visibility: auto;
4  contain-intrinsic-size: 0 500px;
5}

Support des navigateurs (2024)

FonctionnalitéChromeFirefoxSafariEdge
aspect-ratio88+ (2020)89+ (2021)15+ (2021)88+
gap dans Flexbox84+ (2020)63+ (2018)14.1+ (2021)84+
:is()88+78+14+88+
:where()88+78+14+88+
:has()105+ (2022)121+ (2023)15.4+ (2022)105+
subgrid117+ (2023)71+ (2019)16+ (2022)117+
@container106+ (2022)110+ (2023)16+ (2022)106+
@layer99+ (2022)97+ (2022)15.4+ (2022)99+

Résumé

Fonctionnalités modernes les plus importantes :

  • aspect-ratio - proportions parfaites sans astuces
  • gap - espacement dans Flexbox et Grid
  • :is()/:where() - regroupement élégant
  • :has() - le sélecteur de parent !
  • subgrid - grilles imbriquées
  • @layer - contrôle de la cascade
  • @container - réactivité au niveau du composant

Pourquoi les utiliser :

  • Code plus propre
  • Moins d'astuces
  • Meilleures performances
  • Maintenance plus facile
Code de cette leçon : index.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4    <meta charset="UTF-8">
5    <title>CSS moderne - Projet</title>
6    <link rel="stylesheet" href="style.css">
7</head>
8<body>
9    <div class="page">
10        <header>
11            <h1>Le Temple du CSS Moderne</h1>
12            <p class="subtitle">Combine toutes les techniques dans un seul projet</p>
13        </header>
14        <main class="grid-layout">
15            <div class="card-container">
16                <article class="card">
17                    <div class="card-media">Container Queries</div>
18                    <div class="card-body">
19                        <h2>Cartes adaptatives</h2>
20                        <p>Elles réagissent à la taille du conteneur.</p>
21                    </div>
22                </article>
23            </div>
24            <div class="card-container">
25                <article class="card">
26                    <div class="card-media">:has() + Nesting</div>
27                    <div class="card-body">
28                        <h2>Sélecteurs intelligents</h2>
29                        <p>Le parent stylisé par ses enfants.</p>
30                    </div>
31                </article>
32            </div>
33            <section class="scroll-section">
34                <h2>Galerie scroll-snap</h2>
35                <div class="snap-gallery">
36                    <div class="snap-item" style="background:#d4af37">Scarabée</div>
37                    <div class="snap-item" style="background:#8b6914">Ankh</div>
38                    <div class="snap-item" style="background:#1e3a5f">Œil d'Horus</div>
39                    <div class="snap-item" style="background:#b87333">Pyramide</div>
40                </div>
41            </section>
42            <section class="form-section">
43                <h2>Formulaire avec accent-color</h2>
44                <label><input type="checkbox" checked> Option 1</label>
45                <label><input type="range" min="0" max="100" value="70"></label>
46            </section>
47        </main>
48    </div>
49</body>
50</html>

Souviens-toi : Le CSS moderne, c'est comme découvrir de nouveaux hiéroglyphes - de nouvelles possibilités, des solutions plus simples, des outils plus puissants !

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. 1. Qu'est-ce qui a changé dans la prise en charge de la propriété gap depuis 2021 ?

  2. 2. Qu'est-ce que la propriété inset: 0 en CSS ?

Voici 2 des 3 questions de cette leçon. Réponds aux autres dans le jeu.

Tâches pratiques dans le jeu

  • Tri horizontal

    Mets dans l'ordre la déclaration valide overflow: clip sur une seule ligne :

Articles utiles