Atelier Zone-Out 🎮¶
Contexte¶
🎮 Univers de l'atelier : ZONE-OUT 2026¶
Tu travailles sur le site officiel de ZONE-OUT, un tournoi battle royale québécois annuel basé sur le jeu fictif Dropzone. Le site doit être accessible autant sur mobile (les joueurs vérifient leurs stats entre deux parties) que sur desktop (pour les spectateurs en direct).
Objectif¶
Consolider la compréhension des requêtes médias (media queries) à travers des défis de complexité croissante.
Consignes générales¶
- Travail individuel.
- Avance à ton rythme : il n'est pas obligatoire de tout terminer en classe.
- Ce qui n'est pas terminé en classe est à compléter en devoir. Tu disposes de 2 semaines pour le terminer. Tu dois le terminer et le remettre:
- groupe du mercredi: cours 9: mercredi le 8 avril
- groupes du lundi: cours 10: lundi le 13 avril
- En classe, pose des questions à l'enseignante si tu es bloqué·e plus de 5 minutes.
- Hors classe: tu peux obtenir de l'aide avec les tuteurs TIM au C-1612 les mardis OU à distance sur Teams dans ce canal.
🟢 Niveau 1 — Navigation du tournoi¶
Défi : La barre de navigation du site ZONE-OUT est horizontale sur grand écran. Sur mobile, elle doit s'empiler verticalement pour rester utilisable.
Code de départ¶
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ZONE-OUT 2026</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: sans-serif; }
.site-nav {
background-color: #0d0d1a;
padding: 1rem 2rem;
border-bottom: 3px solid #ff4fcb;
box-shadow: 0 0 10px #ff4fcb;
}
.site-nav__logo {
color: #ff4fcb;
text-shadow: 0 0 5px #ff4fcb;
font-weight: 900;
font-size: 1.2rem;
letter-spacing: 0.1em;
text-transform: uppercase;
margin-bottom: 1rem;
}
.site-nav ul{
list-style: none;
}
.site-nav__list {
display: flex;
gap: 0.8rem;
/* TODO: Comment placer la nav par défaut (avant les media queries)? */
}
.site-nav__link {
color: #eee;
text-decoration: none;
padding: 0.5rem 0.2rem;
display: block;
text-transform: uppercase;
font-size: 0.85rem;
letter-spacing: 0.05em;
}
.site-nav__link:hover {
color: #ff4fcb;
background-color: rgba(255, 79, 203, 0.1);
border-radius: 4px;
}
/**TODO: ajouter ici la classe de type modificateur pour la page active */
/*
TODO: Sous ce commentaire, ajouter les media queries nécessaires pour compléter l'exercice.
*/
</style>
</head>
<body>
<nav class="site-nav">
<div class="site-nav__logo">ZONE-OUT</div>
<ul class="site-nav__list">
<li><a href="#" class="site-nav__link">Accueil</a></li>
<li><a href="#" class="site-nav__link">Tournois</a></li>
<li><a href="#" class="site-nav__link">Classement</a></li>
<li><a href="#" class="site-nav__link">Équipes</a></li>
<li><a href="#" class="site-nav__link">Billetterie</a></li>
<li><a href="#" class="site-nav__link">Horaire</a></li>
<li><a href="#" class="site-nav__link">FAQ</a></li>
<li><a href="#" class="site-nav__link">Contact</a></li>
</ul>
</nav>
</body>
</html>
Résultat attendu¶
- ≥ 768px : liens côte à côte (horizontal)
- < 768px : liens empilés (vertical), pleine largeur
Critères de réussite¶
- La navigation fonctionne dans les deux configurations
- Le code est mobile-first (on part du petit, on ajoute pour le grand)
- Aucun overflow horizontal
Ajout supplémentaire :
- Ajoute une classe de type "modificateur" sur le lien Accueil pour indiquer visuellement la page "active". En BEM, une variation d'apparence sur un élément existant s'exprime avec un modificateur (M), révise tes notes sur la nomenclature BEM au besoin.
- Stylise ce modificateur en ajoutant une bordure rose sous le lien.
🟡 Niveau 2 — Leaderboard des joueurs¶
Défi : La page de classement affiche les fiches joueurs en grille. Elle passe de 1 → 2 → 3 colonnes selon l'espace disponible.
Code de départ¶
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ZONE-OUT 2026 — Classement</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: sans-serif;
padding: 2rem;
background: #0d0d1a;
color: #eee;
}
.leaderboard-title {
font-size: 1.5rem;
font-weight: 900;
text-transform: uppercase;
letter-spacing: 0.1em;
color: #ff4fcb;
text-shadow: 0 0 5px #ff4fcb;
margin-bottom: 1.5rem;
}
.player-grid {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
/* Gestion du flexbox du conteneur des cartes ici. */
}
.player-card {
background: #1a1a2e;
border-radius: 8px;
padding: 1.5rem;
border: 1px solid #2a2a4a;
/* Quelle largeur par défaut (mobile) ? */
}
.player-card__avatar {
width: 56px;
height: 56px;
border-radius: 50%;
background: #ff4fcb;
box-shadow: 0 0 10px #ff4fcb;
margin-bottom: 0.75rem;
display: flex;
align-items: center;
justify-content: center;
font-weight: 900;
font-size: 1.2rem;
color: #2a2a4a;
}
.player-card__name {
font-weight: 700;
font-size: 1rem;
margin-bottom: 0.25rem;
}
.player-card__rank {
font-size: 0.8rem;
color: #ff4fcb;
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 0.75rem;
}
.player-card__stats {
display: flex;
gap: 1rem;
font-size: 0.85rem;
color: #aaa;
}
.player-card__stat span {
display: block;
font-weight: 700;
color: #eee;
font-size: 1rem;
}
/*
TODO: Sous ce commentaire, ajouter les media queries nécessaires pour compléter l'exercice.
*/
</style>
</head>
<body>
<h2 class="leaderboard-title">🏆 Classement — ZONE-OUT 2026</h2>
<div class="player-grid">
<div class="player-card">
<div class="player-card__avatar">D</div>
<div class="player-card__name">DragonSlyr</div>
<div class="player-card__rank">⚡ Légendaire</div>
<div class="player-card__stats">
<div class="player-card__stat">K/D <span>4.2</span></div>
<div class="player-card__stat">Winrate <span>68%</span></div>
</div>
</div>
<div class="player-card">
<div class="player-card__avatar">M</div>
<div class="player-card__name">xX_Maple_Xx</div>
<div class="player-card__rank">🔥 Diamant</div>
<div class="player-card__stats">
<div class="player-card__stat">K/D <span>3.7</span></div>
<div class="player-card__stat">Winrate <span>61%</span></div>
</div>
</div>
<div class="player-card">
<div class="player-card__avatar">Z</div>
<div class="player-card__name">ZephyrQC</div>
<div class="player-card__rank">🔥 Diamant</div>
<div class="player-card__stats">
<div class="player-card__stat">K/D <span>3.1</span></div>
<div class="player-card__stat">Winrate <span>55%</span></div>
</div>
</div>
<div class="player-card">
<div class="player-card__avatar">N</div>
<div class="player-card__name">N0vaStrike</div>
<div class="player-card__rank">💎 Platine</div>
<div class="player-card__stats">
<div class="player-card__stat">K/D <span>2.8</span></div>
<div class="player-card__stat">Winrate <span>49%</span></div>
</div>
</div>
<div class="player-card">
<div class="player-card__avatar">V</div>
<div class="player-card__name">VortexMTL</div>
<div class="player-card__rank">💎 Platine</div>
<div class="player-card__stats">
<div class="player-card__stat">K/D <span>2.5</span></div>
<div class="player-card__stat">Winrate <span>44%</span></div>
</div>
</div>
<div class="player-card">
<div class="player-card__avatar">P</div>
<div class="player-card__name">PixelPoutine</div>
<div class="player-card__rank">🥈 Or</div>
<div class="player-card__stats">
<div class="player-card__stat">K/D <span>1.9</span></div>
<div class="player-card__stat">Winrate <span>38%</span></div>
</div>
</div>
</div>
</body>
</html>
Résultat attendu¶
- Mobile (< 600px) : 1 colonne
- Tablette (600px–899px) : 2 colonnes
- Desktop (≥ 900px) : 3 colonnes
Indice : Pour gérer les colonnes avec Flexbox, pense à flex-basis et calc() pour tenir compte du gap.
💡 Savais-tu que…
En Flexbox, le
gapcrée de l'espace entre les éléments, mais cet espace est soustrait de la largeur disponible du conteneur. Résultat : si tu donnesflex-basis: 50%à tes cartes avec ungapactif, les deux cartes ensemble dépassent 100% — et la deuxième tombe à la ligne.La solution : soustraire la part du gap qui revient à chaque carte avec
calc()./* Exemple pour 2 colonnes avec gap: 1.5rem */ /* Le gap est partagé entre 2 cartes → chacune cède 0.75rem */ .player-card { flex-basis: calc(50% - 0.75rem); }Pour 3 colonnes, il y a 2 gaps à répartir entre 3 cartes: le calcul change un peu. Essaie de le déduire par toi-même avant de passer au niveau suivant !
Critères de réussite¶
- Les trois paliers fonctionnent correctement
- Les cartes ont la même hauteur dans une même rangée (bonus)
- L'approche mobile-first est respectée
🔴 Niveau 3 — Page d'accueil du tournoi¶
Défi : Le héros de la page d'accueil ZONE-OUT se réorganise complètement entre mobile et desktop, avec des changements typographiques.
Point de départ¶
Structure HTML fournie — à toi d'écrire tout le CSS responsive.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ZONE-OUT 2026 — Tournoi Battle Royale</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: sans-serif; background: #0d0d1a; color: #eee; }
.tournament-hero { width: 100vw; height: auto; border-bottom: 1px solid #ff4fcb;}
/* Écris tout ton CSS ici */
/* Pense mobile-first */
</style>
</head>
<body>
<section class="tournament-hero">
<div class="tournament-hero__content">
<span class="tournament-hero__label">Battle Royale • Édition 2026</span>
<h1 class="tournament-hero__title">Entre dans la zone. Sors en champion.</h1>
<p class="tournament-hero__desc">
ZONE-OUT est le plus grand tournoi Dropzone du Québec.
256 joueurs. Un seul vainqueur. Inscris-toi avant le 15 avril.
</p>
<div class="tournament-hero__actions">
<a href="#" class="btn btn--primary">S'inscrire maintenant</a>
<a href="#" class="btn btn--secondary">Voir le classement</a>
</div>
</div>
<div class="tournament-hero__visual">
<!-- Simuler une image avec un bloc coloré -->
</div>
</section>
</body>
</html>
Aperçu Desktop¶

Aperçu Mobile¶

Exigences¶
- Styliser les boutons comme sur l'aperçu.
- Ajouter des marges sur le titre et sous-titre pour aérer la mise en page (comme sur l'aperçu). Vous pourrez revenir ajuster cela à la fin.
- Dans
.tournament-hero__contentle texte doit être centré verticalement et aligné à gauche (utilise Flexbox pour ça).
| Propriété | Mobile | Desktop (≥ 768px) |
|---|---|---|
Layout du héros .tournament-hero |
hauteur automatique | hauteur de la fenêtre du navigateur |
Layout du héros .tournament-hero |
en colonne | en rangée (50/50) |
.tournament-hero__title font-size |
clamp(1.75rem, 5vw, 1.75rem) |
clamp(1.75rem, 4vw, 5rem) |
.tournament-hero__visual hauteur |
200px |
hauteur de la section |
.tournament-hero__visual background |
#ff4fcb |
#ff4fcb |
Boutons .tournament-hero__actions |
empilés (colonne) | côte à côte (rangée) |
Padding .tournament-hero__content |
2rem |
4rem |
Critères de réussite¶
- Les deux configurations sont visuellement propres
-
clamp()est utilisé pour la typographie - L'approche mobile-first est respectée
- Le code doit être est commenté (expliquer: pourquoi ce breakpoint, pourquoi cette valeur)...
Synthèse — La règle à retenir¶
Ajoute un breakpoint quand ton contenu te le demande. Jamais parce que c'est la taille d'un appareil populaire.
Checklist responsive de base¶
Avant de déclarer ton interface responsive, vérifie :
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">est présent - Aucune barre de défilement horizontale à aucune taille
- Le texte est lisible sans zoom sur mobile
- Les cibles tactiles (liens, boutons) font au moins 44px de hauteur
- Tes breakpoints ont été choisis en observant le contenu, pas un appareil spécifique
- L'approche mobile-first est respectée (
min-width, pasmax-width)