Chapitre 4 — TP Complet
CSS3 & Web Design
Solutions pratiques couvrant les Sélecteurs, le Box Model, Flexbox, Grid, le Responsive Design et les Animations.
Exercice 1 : Sélecteurs et spécificité
1.1 Sélecteurs
Étant donné le HTML suivant, écrivez les sélecteurs CSS demandés :
Code HTML fourni :
<nav class="main-nav">
<ul>
<li><a href="/" class="active">Accueil</a></li>
<li><a href="/about">À propos</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
<main>
<article class="post featured">
<h2>Premier article</h2>
<p>Contenu...</p>
</article>
<article class="post">
<h2>Deuxième article</h2>
<p>Contenu...</p>
</article>
</main>
Solutions :
- Sélectionnez tous les liens dans la navigation :
.main-nav aounav.main-nav ul li a - Sélectionnez uniquement le lien actif :
.main-nav a.activeoua.active - Sélectionnez l'article qui a la classe featured :
article.post.featured - Sélectionnez le premier paragraphe de chaque article :
article.post p:first-of-type - Sélectionnez les éléments <li> pairs :
li:nth-child(even)
1.2 Spécificité
Questions : Classez ces sélecteurs par spécificité croissante : p, .text, #main, p.text, #main .text p. Si deux règles ont la même spécificité, laquelle gagne ? Pourquoi faut-il éviter !important ?
Solutions :
- Ordre croissant :
p(0,0,1) <.text(0,1,0) <p.text(0,1,1) <#main(1,0,0) <#main .text p(1,1,1) - Égalité de spécificité : C'est la règle déclarée en dernier dans le fichier CSS qui l'emporte (effet de cascade).
- Pourquoi éviter
!important: Cela casse la cascade naturelle et rend la surcharge impossible sans réutiliser!important, ce qui rend le code incontrôlable.
Exercice 2 : Box Model
2.1 Comprendre le Box Model
Code CSS fourni :
.box {
width: 300px;
padding: 20px;
border: 5px solid #333;
margin: 15px;
}
Questions : Avec box-sizing: content-box (défaut), quelle est la largeur totale visible ? Avec box-sizing: border-box, quelle est la largeur totale visible ? Écrivez le reset CSS universel pour box-sizing.
Solutions :
- Largeur totale avec content-box :
350px(300 width + 40 padding + 10 border) - Largeur totale avec border-box :
300px(le bord et le padding sont inclus dans la largeur donnée)
Reset CSS Universel (code complet) :
*, *::before, *::after {
box-sizing: border-box;
}
2.2 Centrer un élément
Centrez horizontalement un élément <div> de 600px de large, puis centrez-le aussi verticalement dans la page.
Solutions :
On peut utiliser position: absolute; (une très belle alternative moderne serait display: grid; place-items: center; sur le parent).
/* La méthode position absolue pour le centrage complet */
.center-div {
width: 600px;
padding: 20px;
background-color: #007bff;
color: white;
/* Le centrage vertical/horizontal */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
Exercice 3 : Flexbox
3.1 Barre de navigation
Créez une barre de navigation horizontale avec un logo à gauche et des liens à droite :
Code HTML fourni :
<nav class="navbar">
<div class="logo">MonSite</div>
<ul class="nav-links">
<li><a href="#">Accueil</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
Solutions :
.navbar {
display: flex;
justify-content: space-between; /* Espace équitable entre la gauche et la droite */
align-items: center; /* Aligné verticalement au centre */
background-color: #333;
padding: 1rem 2rem;
color: white;
}
.nav-links {
display: flex;
gap: 20px; /* Écartement entre les liens */
list-style: none; /* Enlève les puces de */
margin: 0;
padding: 0;
}
.nav-links li a {
color: white;
text-decoration: none;
}
3.2 Cartes de même hauteur
Créez 3 cartes côte à côte avec un footer qui reste toujours en bas :
Code HTML fourni :
<div class="cards">
<div class="card">
<h3>Carte 1</h3>
<p>Contenu court.</p>
<a href="#" class="card-link">En savoir plus</a>
</div>
<!-- autres cartes... -->
</div>
Solutions :
.cards {
display: flex;
gap: 20px;
}
.card {
display: flex;
flex-direction: column; /* Agence les enfants de haut en bas */
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
flex: 1; /* Permet aux cartes de partager l'espace horizontal équitablement */
}
.card-link {
margin-top: auto; /* Aligne le bouton tout en bas même s'il manque du texte */
display: inline-block;
padding: 10px 15px;
background-color: #007bff;
color: white;
text-decoration: none;
text-align: center;
border-radius: 4px;
}
Carte 2
Contenu beaucoup plus long pour tester l'alignement vertical des boutons. Flexbox garantit que le bouton du bas reste poussé vers le bas grâce à margin-top: auto en étant en flex-direction: column.
Exercice 4 : CSS Grid
4.1 Grille de cartes responsive
Créez une grille de cartes qui s'adapte automatiquement au nombre de colonnes :
Code HTML fourni :
<div class="grid-cards">
<div class="card">Carte 1</div>
...
<div class="card">Carte 6</div>
</div>
Solutions :
.grid-cards {
display: grid;
/* auto-fit répartit les colonnes, minmax garantit une largeur minimale de 250px */
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
.card {
padding: 20px;
background-color: #28a745;
color: white;
border-radius: 6px;
text-align: center;
}
4.2 Layout complet avec Grid Areas
Créez une mise en page complète : header, sidebar, main, footer.
Code HTML fourni :
<div class="page-layout">
<header class="header">Header</header>
<nav class="sidebar">Sidebar</nav>
<main class="main">Contenu principal</main>
<footer class="footer">Footer</footer>
</div>
Solutions :
.page-layout {
display: grid;
/* On nomme nos emplacements de layout */
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
gap: 10px;
}
/* Attachement aux zones */
.header { grid-area: header; background: #333; color: white; padding: 20px; }
.sidebar { grid-area: sidebar; background: #f4f4f4; padding: 20px; }
.main { grid-area: main; padding: 20px; }
.footer { grid-area: footer; background: #333; color: white; padding: 20px; text-align: center; }
Exercice 5 : Responsive Design
5.1 Mobile First
Transformez cette page pour qu'elle soit responsive (mobile first). Ajoutez les media queries pour tablette et desktop :
Code CSS fourni :
/* Base mobile */
.container { width: 100%; padding: 15px; }
.nav-menu { display: flex; flex-direction: column; gap: 5px; }
.content { display: block; }
.sidebar { display: none; }
Solutions :
/* Base mobile */
.container {
width: 100%;
padding: 15px;
}
.nav-menu {
display: flex;
flex-direction: column;
gap: 5px;
}
.content {
display: block;
}
.sidebar {
display: none; /* Caché sur mobile */
}
/* Tablette */
@media (min-width: 768px) {
.nav-menu {
flex-direction: row;
justify-content: space-around;
}
}
/* Desktop */
@media (min-width: 1024px) {
.container {
display: grid;
grid-template-columns: 250px 1fr;
gap: 30px;
}
.sidebar {
display: block; /* On affiche la sidebar sur grand écran */
}
}
Exercice 6 : Variables CSS et thèmes
6.1 Système de couleurs
Créez un système de variables CSS pour un thème clair et sombre :
Solutions :
/* Thème Clair - Par défaut */
:root {
--bg-color: #ffffff;
--text-color: #333333;
--primary-color: #007bff;
}
/* Thème Sombre - Appliqué quand dataset theme="dark" */
[data-theme="dark"] {
--bg-color: #1a1a1a;
--text-color: #f5f5f5;
--primary-color: #4da3ff;
}
/* Autre méthode: Media query système native */
@media (prefers-color-scheme: dark) {
:root {
--bg-color: #1a1a1a;
--text-color: #f5f5f5;
}
}
/* Application au Body et aux éléments globaux */
body {
background-color: var(--bg-color);
color: var(--text-color);
/* Transition douce au changement de couleur */
transition: background-color 0.3s ease, color 0.3s ease;
}
button {
background-color: var(--primary-color);
color: white;
border: none;
padding: 10px 20px;
}
Thème Clair
Utilise --bg-color: #f8f9fa;
Thème Sombre
Utilise --bg-color: #212529;
Exercice 7 : Transitions et animations
7.1 Bouton animé
Créez un bouton avec des transitions au survol :
Solutions :
.btn {
padding: 10px 20px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
/* La propriété transition gère tous les effets d'animation (fond et taille) */
transition: background-color 0.3s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
/* Effets animés lors du survol du bouton */
.btn:hover {
background-color: #0056b3;
transform: translateY(-3px); /* Fait monter le bouton de 3px */
box-shadow: 0 4px 10px rgba(0,0,0,0.2); /* Ajoute de l'ombre de profondeur */
}
7.2 Animation de chargement
Créez un spinner de chargement avec @keyframes :
Solutions :
.spinner {
width: 50px;
height: 50px;
border: 6px solid #e9ecef; /* Couleur de l'anneau de base */
border-top: 6px solid #17a2b8; /* Couleur de la barre de temps qui tourne */
border-radius: 50%; /* Arrondi parfait = cercle */
/* Animation: "spin" tourne pendant 1 seconde de façon linéaire à l'infini */
animation: spin 1s linear infinite;
}
/* L'animation fait tourner l'objet de 0 à 360 degrés */
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}