Avant même d’écrire une ligne de PHP dynamique ou de connecter notre interface à une base de données, nous avons fait le choix de concevoir le Dashboard en HTML et CSS statique. Ce n’est pas un hasard.
Développer d’abord une version statique du Dashboard de Créa-code permet de visualiser, tester et affiner la structure visuelle et l’expérience utilisateur sans se préoccuper de la logique serveur. Cela nous offre plusieurs avantages :
- Nous nous concentrons d’abord sur le design et l’ergonomie ;
- Nous pouvons ajuster les couleurs, les proportions, les espacements sans craindre de « casser » le backend ;
- Le temps de chargement est plus rapide, ce qui facilite les tests ;
- Une fois la base HTML/CSS solide, nous pourrons injecter dynamiquement les vraies données (XP, modules, historique…) grâce à PHP et MySQL dans les jours suivants.
C’est exactement comme pour une maquette papier : on esquisse avant de peindre. Et ce Dashboard, c’est un peu notre interface centrale, le cœur du site après la connexion. Il mérite donc un soin particulier. Il est tiré de la maquette réalisé le jour 23 : Maquette du Dashboard.
- 1. Le HTML du Dashboard : structure générale
- 2. Détail du bloc d’accueil .dashboard-greeting
- 3. Avatar et texte d’accueil
- 4. Le grade utilisateur
- 5. Bloc .progression : suivi du niveau et XP
- 6. La barre d’XP
- 7. Le bouton "Reprendre"
- 8. Les raccourcis : .dashboard-shortcuts
- 9. La section « Aujourd’hui » : .dashboard-today
- 10. Historique utilisateur : .dashboard-history
- 11. Première étape : le Dashboard sur tablette (max-width: 850px)
- 12. Deuxième étape : le Dashboard sur mobile (max-width: 650px)
- 13. Responsive : une démarche progressive et utile
- 14. Utilisation des variables CSS : une base solide et modifiable
- 15. Une architecture CSS bien nommée et lisible
- 16. Gestion propre des espacements
- 17. Utilisation des effets visuels légers mais efficaces
- 18. Typographie cohérente et hiérarchique
- 19. Un code CSS prêt pour le mode sombre
- 20. Le code HTML et CSS complet
- 21. Bilan de la version statique
- 22. Pourquoi avoir commencé en statique ?
1. Le HTML du Dashboard : structure générale
Dans notre vue app/Views/dashboard/dashboard.php, on place le code HTML dans une balise <main class="dashboard">
, ce qui est une bonne pratique en HTML5 : cela indique que ce contenu est le principal de la page.
À l’intérieur de ce <main>
, nous avons quatre grandes sections, clairement identifiées dans le template élaboré hier :
- dashboard-greeting : le bloc d’accueil de l’utilisateur (avatar, pseudo, niveau, bouton reprendre)
- dashboard-shortcuts : les raccourcis pour accéder aux parties importantes du site
- dashboard-today : les objectifs du jour et la mascotte Echo
- dashboard-history : un historique des dernières actions de l’utilisateur connecté
Ces sections sont facilement réutilisables, lisibles, et bien séparées, ce qui facilitera la maintenance du code.

2. Détail du bloc d’accueil .dashboard-greeting
Ce premier bloc sert à accueillir l’utilisateur avec un message personnalisé, son avatar, son grade actuel, et un récapitulatif de sa progression. Voici comment il est structuré :
<section class="dashboard-greeting">
<header class="dashboard-header">
...
</header>
<article class="progression">
...
</article>
</section>
La balise <header>
ici est utilisée à bon escient : elle introduit la partie supérieure de la section de bienvenue. On y trouve trois éléments :
- Un avatar circulaire : l’image de profil de l’utilisateur
- Un message de bienvenue avec son pseudo en PHP
- Le grade actuel, ici « Jeune apprenti » avec une icône 🥇
Le pseudo est inséré en PHP :
<?= htmlspecialchars($_SESSION['user']['pseudo']) ?>
Cela permet d’afficher dynamiquement le pseudo tout en le protégeant contre les attaques XSS grâce à htmlspecialchars()
.
Côté CSS :
.dashboard-header {
display: flex;
justify-content: space-between;
align-items: center;
margin: 2rem auto 5rem;
padding: 0 2.5em;
}
Nous utilisons display: flex
pour aligner l’avatar, le message et le grade sur une seule ligne, avec des espacements automatiques grâce à justify-content: space-between
.
3. Avatar et texte d’accueil
L’avatar est stylisé ainsi :
.dashboard-header .avatar img {
width: 85px;
border-radius: 50%;
}
La largeur est fixe (85 pixels), et le border-radius: 50%
permet de créer un cercle parfait, quel que soit le format d’origine de l’image.
À côté, le message d’accueil est dans une div.welcome-text
:
<h2>Bonjour <a href="#">Alban</a>,<br>Prêt à coder aujourd'hui ?</h2>
Le CSS associé :
.dashboard-header .welcome-text h2 {
font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.773), 1.3rem);
color: var(--color-text);
line-height: 1.5;
font-weight: 700;
}
Ici, --color-text
est une variable CSS, définie dans notre thème global (mode clair/sombre). Le texte est donc lisible et responsive.
4. Le grade utilisateur
Le grade s’affiche à droite de l’en-tête. On voit ceci dans le HTML :
<div class="grade">
<span>Grade</span><br>
<strong><small>🥇</small>Jeune apprenti</strong>
</div>
Et voici le CSS associé :
.dashboard-header .grade {
text-align: right;
position: relative;
top: -5px;
}
Ce top: -5px
permet un léger ajustement visuel vertical pour bien aligner le bloc avec le reste du contenu.
5. Bloc .progression
: suivi du niveau et XP
C’est une des parties les plus importantes du Dashboard : elle montre la progression de l’utilisateur dans son parcours d’apprentissage.
Nous avons trois sous-éléments ici :
- Un cercle avec le numéro de niveau
- Les informations d’XP et de parcours
- Un bouton « Reprendre » pour continuer le module en cours
HTML :
<div class="level-circle">
<div class="background-level-circle">
<span>Niveau</span>
<strong>3</strong>
</div>
</div>
CSS associé :
.level-circle {
background-color: var(--color-bg);
color: var(--color-bg);
border-radius: 50%;
width: 100px;
height: 100px;
display: flex;
flex-direction: column;
justify-content: center;
}
.level-circle .background-level-circle {
background: var(--color-accent-secondary);
width: 86px;
height: 86px;
border-radius: 50%;
margin-left: 6px;
display: flex;
flex-direction: column;
justify-content: center;
}
Ici, deux cercles concentriques sont utilisés pour créer un effet visuel propre et centré. Le niveau est mis en valeur dans un strong
avec une taille de police de 3rem
.
6. La barre d’XP
L’élément suivant est la barre de progression :
<div class="xp-bar">
<div class="xp-current"><em>80 %</em></div>
</div>
Cette barre est stylisée de manière fluide :
.xp-bar {
height: 20px;
background: var(--backgound-bar);
border-radius: 8px;
overflow: hidden;
max-width: 500px;
}
.xp-current {
height: 100%;
width: 80%;
background-color: var(--color-accent-secondary);
}
La largeur (width: 80%
) est ici codée en dur, mais elle sera bien sûr rendue dynamique plus tard via une variable PHP.
Le pourcentage est affiché dans un em
, qui est repositionné pour apparaître au bon endroit grâce à :
.xp-current em {
margin-left: 89.5%;
position: relative;
top: -3px;
opacity: 0.8;
color: var(--color-bg);
}
7. Le bouton « Reprendre »
Enfin, le lien pour continuer le parcours est le suivant. Il est en jaune pour être visible et appelé à l’action :
<a href="#" class="btn btn-signin"><span>⏵</span>Reprendre</a>
Le CSS ajoute du style :
.resume-button a span {
margin-right: 9px;
font-size: 2rem;
position: relative;
top: 5px;
}
L’icône ⏵ attire l’attention de manière intuitive.
8. Les raccourcis : .dashboard-shortcuts
Juste après l’accueil, nous retrouvons une section très pratique : des icônes cliquables pour accéder rapidement aux pages principales du site. Cela rend la navigation fluide et intuitive, surtout sur un site pédagogique avec beaucoup de fonctionnalités.
Voici le HTML de base :
<section class="dashboard-shortcuts">
<div class="grid-shortcuts">
<a href="#" class="shortcut">
<?= IconHelper::get('parcours', '') ?>
<span>Mon parcours</span>
</a>
...
</div>
</section>
Chaque lien <a class="shortcut">
représente un raccourci vers les pages :
- Mon parcours
- Mes challenges
- Mon classement
- Mes récompenses
- Mon compte
- Mes statistiques
Les icônes sont générées en PHP par la fonction IconHelper::get()
– coder précédemment. Cela permet de centraliser l’usage des icônes (SVG ou PNG), ce qui est pratique pour les modifier ultérieurement en un seul endroit.
Structure CSS : grid-shortcuts
.grid-shortcuts {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 2rem;
}
On utilise ici un système de grille CSS moderne, avec 4 colonnes égales (1fr
) espacées par un gap
de 2rem.
Style des raccourcis
.shortcut {
background-color: var(--color-bg-alt);
border-radius: 4px;
text-align: center;
padding: 1rem 1rem 1.5rem;
text-decoration: none;
color: var(--font-text);
transition: transform 0.2s;
}
Le raccourci est une carte cliquable avec une apparence propre et arrondie. L’effet transform: translateY(-3px)
dans le :hover
ajoute une animation fluide au survol, renforçant l’expérience utilisateur :
.shortcut:hover {
transform: translateY(-3px);
color: var(--color-success);
background: var(--gray-txt);
}
Enfin, les icônes sont centrées avec une taille bien visible :
.shortcut img, .shortcut svg {
width: 80px;
height: 80px;
display: block;
margin: 1em auto 1em;
}
Et le texte est en gras :
.shortcut span {
font-weight: 600;
}
Responsive Design
Sur petit écran, la grille passe à 3 colonnes (tablette) ou 2 colonnes (mobile) grâce aux media queries suivantes :
@media (max-width: 850px) {
.grid-shortcuts {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 650px) {
.grid-shortcuts {
grid-template-columns: repeat(2, 1fr);
}
}
C’est une manière simple et efficace d’adapter l’interface aux différentes tailles d’écran.
9. La section « Aujourd’hui » : .dashboard-today
Cette partie du Dashboard est importante pour garder la motivation de l’utilisateur au quotidien. Elle affiche des éléments utiles et encourageants :
- Une série en cours
- Un objectif du jour
- Une lecture recommandée
- Un challenge du jour
- Et la présence de Echo, la mascotte du site

Voici le HTML de base :
<section class="dashboard-today">
<h3><span>Aujourd’hui</span></h3>
<div class="dashboard-today-flex">
<ul class="daily-info">
<li>🔥 <strong>Série en cours :</strong> 5 jours d’affilée !</li>
...
</ul>
<div class="container-echo">
<div class="bubble">Salut, je suis Echo !</div>
<img class="img-theme-switch" src="..." alt="Echo">
</div>
</div>
</section>
Titre stylisé
Le <h3>
contient un span
qui permet d’ajouter une séparation fine et propre, visuellement :
.dashboard h3 {
font-size: 1.5rem;
margin: 7rem 0 2rem;
border-top: 1px solid var(--border-color);
}
.dashboard h3 span {
background: var(--color-bg);
position: relative;
top: -16px;
padding-right: 30px;
}
Ce style crée un effet de titre inséré dans une ligne, un peu comme une section surlignée. C’est élégant et discret.
Liste des informations du jour
La liste est simple mais percutante :
<ul class="daily-info">
<li>🔥 <strong>Série en cours :</strong> 5 jours d’affilée !</li>
...
</ul>
Chaque élément utilise un emoji pour créer un repère visuel rapide et motivant.
Le CSS n’est pas très chargé ici. Sur mobile, on ajoute simplement un peu d’espace :
.daily-info {
line-height: 1.6;
margin-left: 20px;
}
La mascotte Echo et sa bulle de dialogue
Voici une belle touche humaine et motivante : une mascotte sympathique qui parle à l’utilisateur.

HTML :
<div class="container-echo">
<div class="bubble">Salut, je suis Echo !</div>
<img class="img-theme-switch" src="..." alt="Echo">
</div>
CSS :
.container-echo {
position: relative;
margin-right: 7%;
top: 40px;
}
.bubble {
position: absolute;
top: -60px;
left: 50%;
transform: translateX(-50%);
background: var(--color-bg);
border: 1px solid var(--border-color);
padding: 10px 15px;
border-radius: 15px;
width: max-content;
max-width: 200px;
box-shadow: var(--shadow);
}
.bubble::after {
content: '';
position: absolute;
bottom: -15px;
left: 50%;
transform: translateX(-50%);
border-width: 10px;
border-style: solid;
border-color: var(--color-bg) transparent transparent transparent;
}
Ce système crée une bulle de BD, très visuelle et simple à mettre en place avec du CSS pur. L’image d’Echo est ensuite affichée avec une hauteur adaptée :
.dashboard .dashboard-today-flex img {
height: 140px;
}
10. Historique utilisateur : .dashboard-history
Dernier bloc du Dashboard : il affiche une liste chronologique des dernières actions récentes de l’utilisateur. Cela donne une sensation de progression concrète.
HTML :
<section class="dashboard-history">
<h3><span>Historique</span></h3>
<ul class="history-list">
<li>Tu as réussi l’exercice 3... <span>08/07/25 à 12:25</span></li>
...
</ul>
</section>
Chaque <li>
est daté, avec un span
pour la date et l’heure :
.history-list span {
font-size: 0.8rem;
color: var(--gray-txt);
margin-left: 10px;
}
On ajoute une indentation :
.history-list li {
list-style-type: circle;
margin-left: 20px;
}
Sur mobile, la disposition est optimisée avec un média-query :
@media (max-width: 650px) {
.history-list span {
display: block;
margin-left: 0;
}
.history-list li {
list-style-type: none;
}
}
Cela garantit que le texte ne déborde pas et reste lisible, même sur petits écrans.
Pourquoi penser « responsive » dès le début ?
Aujourd’hui, les utilisateurs consultent les sites web sur des écrans très variés : smartphones, tablettes, ordinateurs portables ou moniteurs ultra-larges. Il est donc indispensable que notre Dashboard reste lisible et agréable à utiliser sur toutes ces tailles.
C’est ce qu’on appelle le responsive design, et dans notre code CSS, il est géré avec des media queries (requêtes de média). Elles permettent d’appliquer des styles spécifiques à certaines tailles d’écrans.
11. Première étape : le Dashboard sur tablette (max-width: 850px)
Quand l’écran fait 850 pixels de large ou moins, nous passons en mode « tablette ». Voici les adaptations :

Des formations informatique pour tous !
Débutant ou curieux ? Apprenez le développement web, le référencement, le webmarketing, la bureautique, à maîtriser vos appareils Apple et bien plus encore…
Formateur indépendant, professionnel du web depuis 2006, je vous accompagne pas à pas et en cours particulier, que vous soyez débutant ou que vous souhaitiez progresser. En visio, à votre rythme, et toujours avec pédagogie.
Découvrez mes formations Qui suis-je ?Bloc d’accueil .dashboard-header
@media (max-width: 850px) {
.dashboard-header {
flex-direction: column;
}
}
Au lieu d’avoir les éléments alignés en ligne (flex-direction: row
par défaut), on les empile verticalement (column
). Cela permet d’éviter que l’avatar, le message de bienvenue et le grade soient trop compressés.
L’avatar devient plus petit et centré :
.dashboard-header .avatar img {
width: 60%;
margin: 0 auto 30px;
}
Cela garantit qu’il reste visible sans déborder. Le texte est aussi centré :
.dashboard-header .welcome-text h2 {
text-align: center;
}
Et pour le grade :
.dashboard-header .grade {
text-align: center;
margin-top: 20px;
top: 0;
}
.dashboard-header .grade span {
display: none;
}
.dashboard-header .grade strong {
background: var(--color-bg-alt);
padding: 1em;
border-radius: 4px;
}
On supprime l’étiquette « Grade », on met en valeur le titre dans un cadre gris, ce qui améliore la lisibilité sur petit écran.
Grille des raccourcis
On adapte la grille :
.grid-shortcuts {
grid-template-columns: repeat(3, 1fr);
}
On passe de 4 colonnes à 3 colonnes, ce qui est mieux adapté à la largeur d’une tablette.
Section du jour
Les éléments (texte + Echo) ne sont plus côte à côte. Et la mascotte Echo se recentre en bas de la section :
.dashboard .dashboard-today-flex {
flex-direction: column;
align-items: flex-start;
}
.container-echo {
position: relative;
margin: 60px auto auto;
}
Cela permet à l’ensemble de rester fluide, centré et lisible.
12. Deuxième étape : le Dashboard sur mobile (max-width: 650px)
Sur écran de 650 pixels ou moins, nous passons en mode smartphone. Le CSS devient encore plus adaptatif.
Bloc général .dashboard-greeting
On resserre la marge :
.dashboard-greeting {
margin: -1rem auto 2rem;
}
Cela réduit l’espace vide pour que le contenu prenne plus de place sur l’écran réduit.
.progression
devient vertical
.progression {
flex-direction: column;
}
Les éléments qui étaient sur la même ligne (cercle + barre XP + bouton) passent les uns en dessous des autres, ce qui améliore la lisibilité et évite les débordements.
Grille des raccourcis : deux colonnes
.grid-shortcuts {
grid-template-columns: repeat(2, 1fr);
}
Cela permet d’avoir deux icônes par ligne, parfaitement espacées.
Historique : retour à la verticalité
On améliore l’historique pour mobile :
.history-list span {
display: block;
margin-left: 0;
}
La date qui était à droite passe en dessous de l’action, pour économiser la largeur. On supprime les puces (cercles) qui sont peu lisibles sur petit écran :
.history-list li {
list-style-type: none;
}
Taille de l’image Echo
.dashboard .dashboard-today-flex img {
height: 190px;
margin-bottom: 50px;
}
L’image de la mascotte est plus grande pour rester visible et sympathique, même sur petit écran. Le margin-bottom
ajoute une respiration visuelle.
13. Responsive : une démarche progressive et utile
Nous avons donc utilisé deux points de rupture principaux pour le responsive :
- 850px → mode tablette
- 650px → mode mobile
Chaque fois, nous avons modifié le comportement des éléments clés : positionnement, marges, tailles, alignements.
C’est une méthode mobile-friendly, simple à mettre en œuvre, et qui offre une expérience utilisateur fluide sur tous les appareils.
14. Utilisation des variables CSS : une base solide et modifiable
L’une des premières forces de ce Dashboard, c’est l’utilisation intelligente de variables CSS.
Dans tout le fichier CSS, on retrouve des instructions comme :
background: var(--color-bg);
color: var(--color-text);
border: 1px solid var(--border-color);
Ces --color-bg
, --color-text
, --color-accent-secondary
, etc., ne sont pas des couleurs fixes comme #fff
ou #333
, mais des valeurs personnalisables définies ailleurs (souvent dans un fichier :root
ou dans un thème clair/sombre).
Pourquoi c’est génial ?
Parce que si demain nous voulons modifier les couleurs du site ou améliorer les contrastes, il suffit de changer la valeur d’une variable à un seul endroit, au lieu de parcourir tout le fichier CSS.
C’est une approche moderne, propre et durable. Cela fait partie de ce qu’on appelle la « CSS Custom Properties », introduite avec CSS3.
15. Une architecture CSS bien nommée et lisible
Un autre point très positif de cette feuille de style, c’est l’organisation des noms de classes :
.dashboard-header
.dashboard-greeting
.dashboard-shortcuts
.dashboard-today
.dashboard-history
Les noms sont clairs, contextualisés, et suivent une logique hiérarchique. Cela veut dire que si quelqu’un d’autre (ou nous, dans 3 mois) relit ce fichier, tout est facilement compréhensible.
Le code respecte la convention BEM light (Block-Element-Modifier, mais simplifiée) sans surcharge syntaxique.
16. Gestion propre des espacements
Les marges (margin
) et les paddings (padding
) sont utilisés avec modération mais pertinence. Voici quelques bonnes pratiques que l’on a mit en place.
On utilise des unités relatives (rem
) au lieu de pixels fixes. Cela permet à la mise en page de s’adapter à la taille du texte, donc à la configuration de l’utilisateur. C’est très important pour l’accessibilité.
Les valeurs sont équilibrées pour garantir une lecture aérée, sans que les blocs ne paraissent trop serrés ou trop espacés.
17. Utilisation des effets visuels légers mais efficaces
Pas d’animations tape-à-l’œil ici, mais quelques effets subtils qui rendent l’interface plus fluide et agréable :
Survol des raccourcis :
.shortcut:hover {
transform: translateY(-3px);
background: var(--gray-txt);
color: var(--color-success);
}
Ce simple glissement de 3 pixels vers le haut donne un retour visuel agréable à l’utilisateur, qui sent que le bouton est cliquable. L’arrière-plan change légèrement et la couleur de texte aussi.
Bulle de dialogue Echo :
.bubble {
position: absolute;
background: var(--color-bg);
border-radius: 15px;
box-shadow: var(--shadow);
}
.bubble::after {
content: '';
border-style: solid;
border-color: var(--color-bg) transparent transparent transparent;
}
On crée une bulle de bande dessinée en pur CSS. Pas besoin d’image. Le petit triangle (::after
) rend le tout visuellement clair et stylisé. Encore une fois, simple, mais efficace.
18. Typographie cohérente et hiérarchique
Le CSS met bien en évidence la hiérarchie visuelle grâce à la taille et au poids des polices. On utilise rem
ou em
au lieu de pixels fixes : cela permet à l’ensemble d’être zoomable sans casser la mise en page. Le texte est donc :
- Lisible ;
- Cohérent ;
- Accessible.
De plus, le texte important (strong
, em
) est bien mis en valeur.
19. Un code CSS prêt pour le mode sombre
Un point très intéressant, c’est que tout le CSS repose sur des variables comme --color-bg
, --gray-txt
, --color-accent-secondary
, etc…
Cela veut dire qu’il est toujours facile de basculer d’un thème clair vers un thème sombre :
body[data-theme="dark"] { :root {
--color-bg: #1a1a1a;
--color-text: #eee;
--color-accent-secondary: #ffbf00;
...
}
}
Le code est donc moderne et évolutif.
20. Le code HTML et CSS complet
Le code HTML complet :
<?php
use App\Helpers\IconHelper;
?>
<main class="dashboard">
<!-- Bloc d’accueil et progression -->
<section class="dashboard-greeting">
<header class="dashboard-header">
<div class="avatar">
<img src="<?= BASE_URL ?>assets/img/avatar/avatar.png" alt="Avatar utilisateur">
</div>
<div class="welcome-text">
<h2>Bonjour <a href="#"><?= htmlspecialchars($_SESSION['user']['pseudo']) ?></a>,<br>Prêt à coder aujourd'hui ?</h2>
</div>
<div class="grade">
<span>Grade</span><br>
<strong><small>🥇</small>Jeune apprenti</strong>
</div>
</header>
<article class="progression">
<div class="level-circle">
<div class="background-level-circle">
<span>Niveau</span>
<strong>3</strong>
</div>
</div>
<div class="xp-info">
<strong>Niveau XP</strong> <span>40 / 50 XP</span>
<div class="xp-bar">
<div class="xp-current"><em>80 %</em></div>
</div>
<strong class="bleu">Parcours :</strong> <em>Module HTML de base (4/5)</em>
</div>
<div class="resume-button">
<a href="#" class="btn btn-signin"><span>⏵</span>Reprendre</a>
</div>
</article>
</section>
<!-- Raccourcis navigation -->
<section class="dashboard-shortcuts">
<div class="grid-shortcuts">
<a href="#" class="shortcut">
<?= IconHelper::get('parcours', '') ?>
<span>Mon parcours</span>
</a>
<a href="#" class="shortcut">
<?= IconHelper::get('challenge', '') ?>
<span>Mes challenges</span>
</a>
<a href="#" class="shortcut">
<?= IconHelper::get('classement', '') ?>
<span>Mon classement</span>
</a>
<a href="#" class="shortcut">
<?= IconHelper::get('recompense', '') ?>
<span>Mes récompenses</span>
</a>
<a href="#" class="shortcut">
<?= IconHelper::get('utilisateur', '') ?>
<span>Mon compte</span>
</a>
<a href="#" class="shortcut">
<?= IconHelper::get('stat', '') ?>
<span>Mes statistiques</span>
</a>
</div>
</section>
<!-- Bloc du jour -->
<section class="dashboard-today">
<h3><span>Aujourd’hui</span></h3>
<div class="dashboard-today-flex">
<ul class="daily-info">
<li>🔥 <strong>Série en cours :</strong> 5 jours d’affilée !</li>
<li>🎯 <strong>Objectif du jour :</strong> 1 exercice, 1 quizz ou 1 challenge</li>
<li>📖 <strong>Lecture du jour :</strong> <a href="#">La sémantique en HTML</a></li>
<li>🧠 <strong>Challenge du jour :</strong> <a href="#">Les listes non ordonnée en HTML</a></li>
</ul>
<div class="container-echo">
<div class="bubble">Salut, je suis Echo !</div>
<img class="img-theme-switch" src="<?= BASE_URL ?>assets/img/echo/echo-serein.webp"
data-src-light="<?= BASE_URL ?>assets/img/echo/echo-serein.webp"
data-src-dark="<?= BASE_URL ?>assets/img/echo/echo-serein-dark.webp"
alt="Logo Créa-code" loading="lazy">
</div>
</div>
</section>
<!-- Historique -->
<section class="dashboard-history">
<h3><span>Historique</span></h3>
<ul class="history-list">
<li>Tu as réussi l’exercice 3 du module HTML de base <span>08/07/25 à 12:25</span></li>
<li>Tu as réussi l’exercice 2 du module HTML de base <span>05/07/25 à 14:32</span></li>
<li>Connexion à ton compte <span>04/07/25 à 09:43</span></li>
<li>Tu as réussi l’exercice 1 du module HTML de base <span>03/07/25 à 19:15</span></li>
<li>Tu as débloqué le grade "Jeune apprenti" <span>03/07/25 à 18:57</span></li>
<li>Tu as réussi le quizz du module d’introduction <span>02/07/25 à 10:25</span></li>
</ul>
</section>
</main>
Le code CSS complet :
/*************************
* *
* Dashboard *
* *
*************************/
/* Bloc d’accueil utilisateur */
.dashboard-greeting {
margin: 2rem auto;
}
.dashboard-header {
display: flex;
justify-content: space-between;
align-items: center;
margin: 2rem auto 5rem;
padding: 0 2.5em;
}
.dashboard-header .avatar img {
width: 85px;
border-radius: 50%;
}
.dashboard-header .welcome-text {
text-align: left;
flex: 1;
margin-left: 2rem;
}
.dashboard-header .welcome-text h2 {
font-size: 1.3rem;
color: var(--color-text);
line-height: 1.5;
font-weight: 700;
}
.dashboard-header .grade {
text-align: right;
position: relative;
top: -5px;
}
.dashboard-header .grade span {
font-weight: 700;
color: var(--color-accent-secondary);
font-size: 0.8em;
}
.dashboard-header .grade strong {
font-weight: 700;
font-size: 1.5em;
}
.dashboard-header .grade strong small {
font-weight: 700;
font-size: 0.8em;
margin-right: 10px;
}
/* Progression utilisateur */
.progression {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 2rem;
background: var(--color-bg-alt);
border-radius: 4px;
padding: 1.5rem 2rem;
}
.level-circle {
background-color: var(--color-bg);
color: var(--color-bg);
border-radius: 50%;
width: 100px;
height: 100px;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
padding: 0;
border: 1px solid var(--border-color);
}
.level-circle .background-level-circle {
background: var(--color-accent-secondary);
width: 86px;
height: 86px;
border-radius: 50%;
margin-left: 6px;
display: flex;
flex-direction: column;
justify-content: center;
}
.level-circle span {
position: relative;
top: 3px;
font-size: 0.8rem
}
.level-circle strong {
font-size: 3rem;
line-height: 1;
}
.xp-info {
flex: 1;
}
.xp-info span {
font-size: 0.8rem;
color: var(--gray-txt);
margin-left: 10px;
}
.xp-info em {
font-weight: 900;
font-style: normal;
}
.xp-bar {
height: 20px;
background: var(--backgound-bar);
border-radius: 8px;
margin: 0.5rem 0;
overflow: hidden;
max-width: 500px;
display: flex;
justify-content: space-between;
}
.xp-current {
height: 100%;
width: 80%;
background-color: var(--color-accent-secondary);
}
.xp-current em {
font-size: 0.8rem;
margin-left: 89.5%;
position: relative;
top: -3px;
opacity: 0.8;
color: var(--color-bg);
}
.resume-button a {
position: relative;
top: -5px;
}
.resume-button a span {
margin-right: 9px;
font-size: 2rem;
position: relative;
top: 5px;
}
/* Navigation rapide */
.dashboard-shortcuts {
margin-bottom: 2rem;
}
.grid-shortcuts {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 2rem;
}
.shortcut {
background-color: var(--color-bg-alt);
border-radius: 4px;
text-align: center;
padding: 1rem 1rem 1.5rem;
text-decoration: none;
color: var(--font-text);
transition: transform 0.2s;
}
.shortcut:hover {
transform: translateY(-3px);
olor:var(--color-success);
background: var(--gray-txt);
}
.shortcut img, .shortcut svg {
width: 80px;
height: 80px;
margin-bottom: 0.5rem;
display: block;
margin: 1em auto 1em;
}
.shortcut span {
font-weight: 600;
}
/* Objectif du jour et Historique */
.dashboard h3 {
font-size: 1.5rem;
margin: 7rem 0 2rem;
border-top: 1px solid var(--border-color);
}
.dashboard h3 span {
background: var(--color-bg);
position: relative;
top: -16px;
padding-right: 30px;
}
.dashboard li {
margin-bottom: 0.8rem;
}
.dashboard li strong {
margin-left: 10px
}
.dashboard .dashboard-today-flex {
display: flex;
justify-content: space-between;
align-items: center;
}
.history-list {
margin-bottom: 5em;
}
.history-list li {
list-style-type: circle;
margin-left: 20px;
}
.history-list span {
font-size: 0.8rem;
color: var(--gray-txt);
margin-left: 10px;
}
.container-echo {
position: relative;
margin-right: 7%;
top: 40px;
}
.bubble {
position: absolute;
top: -60px;
left: 50%;
transform: translateX(-50%);
background: var(--color-bg);
border: 1px solid var(--border-color);
padding: 10px 15px;
border-radius: 15px;
width: max-content;
max-width: 200px;
box-shadow: var(--shadow);
}
.bubble::after {
content: '';
position: absolute;
bottom: -15px;
left: 50%;
transform: translateX(-50%);
border-width: 10px;
border-style: solid;
border-color: var(--color-bg) transparent transparent transparent;
}
.character {
width: 200px;
border-radius: 8px;
}
.dashboard .dashboard-today-flex img {
height: 140px;
}
/*************************
* *
* RESPONSIVE *
* *
*************************/
@media (max-width: 850px) {
.dashboard-header {
flex-direction: column;
}
.dashboard-header .avatar img {
width: 60%;
margin: 0 auto 30px;
}
.dashboard-header .welcome-text {
margin-left: 0;
}
.dashboard-header .welcome-text h2 {
text-align: center;
}
.dashboard-header .grade {
text-align: center;
margin-top: 20px;
top: 0;
}
.dashboard-header .grade span {
display: none;
}
.dashboard-header .grade strong {
background: var(--color-bg-alt);
padding: 1em;
border-radius: 4px;
}
.grid-shortcuts {
grid-template-columns: repeat(3, 1fr);
}
.dashboard .dashboard-today-flex {
flex-direction: column;
align-items: flex-start;
}
.container-echo {
position: relative;
margin: 60px auto auto;
}
}
@media (max-width: 650px) {
.dashboard-greeting {
margin: -1rem auto 2rem;
}
.progression {
flex-direction: column;
}
.grid-shortcuts {
grid-template-columns: repeat(2, 1fr);
}
.history-list span {
display: block;
margin-left: 0;
}
.dashboard h3 {
margin: 4rem 0 1rem;
}
.daily-info {
line-height: 1.6;
margin-left: 20px;
}
.dashboard li strong {
width: 89%;
display: inline-block;
}
.dashboard li {
margin-bottom: 1rem;
}
.dashboard .dashboard-today-flex img {
margin-bottom: 50px;
}
.history-list {
margin-bottom: 3em;
}
.history-list li {
list-style-type: none;
}
footer .footer-newsletter {
margin-bottom: 3em;
}
footer .footer-about {
padding: 3em 0 2em;
}
.dashboard .dashboard-today-flex img {
height: 190px;
}
.dashboard-header {
margin: 2rem auto 3rem;
}
}
21. Bilan de la version statique
Nous avons conçu une interface de tableau de bord claire, structurée et motivante. Voici ce que nous avons mis en place :
- Un bloc d’accueil personnalisé avec l’avatar, le pseudo, et le grade
- Une zone de progression avec un cercle de niveau, une barre XP, et un bouton « Reprendre »
- Une grille de raccourcis qui permet d’accéder rapidement à toutes les fonctionnalités principales
- Une section quotidienne avec des objectifs, des ressources, et la présence sympathique d’Echo, la mascotte
- Un historique utilisateur pour suivre ses réussites et sa progression dans le temps
- Un design responsive adapté à tous les écrans, de l’ordinateur au smartphone
- Une architecture CSS moderne et propre, basée sur des variables et des classes bien nommées
Le tout a été codé en HTML et CSS pur, sans appel dynamique aux bases de données pour le moment.
22. Pourquoi avoir commencé en statique ?
Vous vous demandez peut-être pourquoi coder tout cela en « dur », sans faire appel à PHP, SQL ou JavaScript dynamique dès le départ. C’est volontaire, et c’est même une méthode pédagogique très efficace. Voici pourquoi :
a) On pose les fondations
Créer d’abord une structure statique, c’est comme dessiner les plans d’une maison avant d’y ajouter les meubles, les tuyaux, l’électricité.
Cela nous permet de visualiser l’interface finale, de corriger la disposition, les tailles, les couleurs… sans être distrait par la logique serveur, les erreurs PHP ou les requêtes SQL.
b) On travaille en couches
Dans le développement web, on construit par couches :
- Structure HTML (contenu)
- Style CSS (visuel)
- Dynamique PHP/JS (comportement)
- Données (stockage, API)
Faire étape par étape permet d’éviter de tout mélanger, ce qui est souvent source d’erreurs pour les débutants (et même les pros !).
c) On gagne du temps à long terme
Une fois que le HTML/CSS est validé, il est beaucoup plus facile de brancher dynamiquement les données avec PHP :
- Le pseudo s’affiche déjà à la bonne place ;
- Le grade a déjà son style ;
- Les blocs ont leur taille, leur comportement responsive, leur animation.
Il suffira d’injecter des valeurs dynamiques dans le HTML existant, au lieu de coder à l’aveugle.
23. Les prochaines étapes…
Bientôt, nous allons transformer ce Dashboard statique en une version dynamique, connectée à notre base de données.
Voici ce qui est prévu :
a) Récupérer les données utilisateur
Nous allons utiliser PHP pour afficher en direct :
- Le pseudo depuis
$_SESSION['user']['pseudo']
; - Le niveau et l’XP depuis une base de données ;
- Le grade calculé automatiquement ;
- Les éléments de l’historique.
Tout sera personnalisé selon l’utilisateur connecté.
b) Injecter les icônes, liens et contenus réels
Actuellement, les icônes et liens sont encore factices (href="#"
). Nous allons :
- Relier chaque raccourci à sa vraie page
- Faire en sorte que les icônes viennent automatiquement d’un composant PHP (
IconHelper
) - Charger les challenges et lectures du jour depuis des données dynamiques (fichier JSON, table
daily_missions
, …)
c) Créer une interface réactive
Avec JavaScript, nous pourrons ensuite :
- Faire évoluer la barre d’XP sans recharger la page ;
- Afficher des notifications (félicitations, badges, etc.) ;
- Mettre à jour Echo en fonction de l’heure, du thème, ou de l’humeur du jour.
Mais chaque chose en son temps !
Aujourd’hui, nous avons découvert comment structurer une vraie page de Dashboard utilisateur, étape par étape :
- En comprenant chaque bloc HTML (header, progression, raccourcis, historique…)
- En analysant chaque section CSS (flexbox, grille, responsive, variables, typographie…)
- En posant une base stable, réutilisable et maintenable
- En préparant un design prêt à accueillir des données dynamiques
Nous avons aussi vu que travailler en statique au départ, ce n’est pas une perte de temps, bien au contraire. C’est comme construire une arène avant d’y faire jouer un match.
On va rentrer dans le cœur dynamique du Dashboard !