Cours HTML et CSS · Module 9: CSS moderne
Fonctionnalités CSS modernes - L'avenir de la mise en forme des hiéroglyphes égyptiens
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é | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| aspect-ratio | 88+ (2020) | 89+ (2021) | 15+ (2021) | 88+ |
| gap dans Flexbox | 84+ (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+ |
| subgrid | 117+ (2023) | 71+ (2019) | 16+ (2022) | 117+ |
| @container | 106+ (2022) | 110+ (2023) | 16+ (2022) | 106+ |
| @layer | 99+ (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. Qu'est-ce qui a changé dans la prise en charge de la propriété gap depuis 2021 ?
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 :