Dans ce tutoriel, tu vas créer une Quiz App en JavaScript, avec HTML et CSS : un menu de sujets, des questions à choix multiples, une barre de progression, un retour visuel immédiat et un score final. Un projet complet et personnalisable, idéal pour réviser, tester des élèves ou s’amuser entre amis.

Ce que tu vas construire : une Quiz App en JavaScript complète
Imagine que tu es formateur et que tu veux évaluer tes élèves après un cours, ou que tu veux préparer un quiz pour sensibiliser au tri des déchets, ou même tester tes amis sur vos meilleurs souvenirs. Cette Quiz App en JavaScript s’adapte à tous ces cas : il suffit de changer les questions.
Prérequis
Aucun prérequis particulier : chaque étape est expliquée. Il te faut simplement :
- Un éditeur de code comme Visual Studio Code
- Un navigateur récent
- Idéalement, quelques notions de HTML, CSS et JavaScript
Si tu découvres JavaScript, commence par la calculatrice en HTML, CSS et JavaScript, un projet plus court.
Arborescence du projet
Crée un dossier quiz-game avec trois fichiers et un sous-dossier images pour ton logo et les icônes de chaque sujet :
- index.html : la structure de la page, sa colonne vertébrale
- style.css : les couleurs, les tailles et les effets
- script.js : le cerveau du quiz, qui affiche les questions et calcule le score
Étape 1 : créer la base HTML
Ouvre index.html et écris ce squelette :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Quiz Game</title>
<link rel="stylesheet" href="style.css">
<link
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
rel="stylesheet"
>
</head>
<body>
<div class="app">
<div id="image-container" class="d-flex justify-content-center mb-5">
<img id="image" src="images/logo.png" alt="Logo Quiz" class="img-fluid">
</div>
<h1>Quiz Game – Test de connaissances</h1>
<div class="menu">
<h2>Choisis ton sujet</h2>
<div class="subjects">
<!-- Bloc de sélection d’un sujet -->
<div class="subject-button">
<button
class="small-icon"
onclick="selectSubject('PHP')"
style="background-image: url('images/php.svg')"
alt="PHP"
></button>
<p>PHP</p>
</div>
<!-- Répète ce bloc pour Python, JavaScript, Powershell et Java -->
</div>
</div>
<div class="quiz" style="display: none;">
<div id="progress-bar"></div>
<h2 id="question">Ici ta question apparaîtra</h2>
<div id="answer-buttons"></div>
<div id="feedback" style="display: none;">
<div id="success-message" style="display: none;">Bravo !</div>
<div id="failure-message" style="display: none;">Dommage !</div>
</div>
<button id="next-btn">Suivant</button>
<button id="menu-btn" onclick="returnToMenu()">Revenir au menu</button>
</div>
</div>
<a href="https://lm-code.be" class="watch-link">LM-Code</a>
<script src="script.js"></script>
</body>
</html>index.htmlÀ quoi sert chaque élément
- <!DOCTYPE html> et lang= »fr » : du HTML5 moderne, en français
- Dans le <head> : l’encodage UTF-8 pour les accents, le titre de l’onglet, ta feuille
style.csset Bootstrap (facultatif) - La zone logo : un conteneur flex qui centre l’image
- Le menu des sujets : un bouton par thème, qui appelle
selectSubject('…') - La zone quiz, cachée au départ : barre de progression, question, réponses, message de retour et boutons « Suivant » et « Retour au menu »
À ce stade, la page n’a encore aucun style :

Étape 2 : embellir le quiz avec le CSS
Ouvre style.css et copie ce code :
/* 1. Reset global et police */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
/* 2. Fond sombre */
body {
background: #001e4d;
}
/* 3. Conteneur principal */
.app {
max-width: 600px;
width: 90%;
margin: 100px auto 0;
padding: 30px;
border-radius: 10px;
background: #fff;
}
/* 4. Titre de l’application */
.app h1 {
text-align: center;
font-size: 25px;
color: #0b54c9;
margin-bottom: 20px;
}
/* 5. Espacements pour menu et quiz */
.menu, .quiz {
padding: 20px 0;
}
.menu h2, .quiz h2 {
font-size: 18px;
color: #001e4d;
margin-bottom: 15px;
}
/* 6. Boutons génériques */
.btn {
width: 100%;
padding: 10px;
margin: 8px 0;
border: 1px solid #222;
border-radius: 4px;
background: #fff;
color: #222;
cursor: pointer;
transition: background 0.3s, color 0.3s;
}
.btn:hover {
background: #222;
color: #fff;
}
.btn:disabled {
cursor: not-allowed;
opacity: 0.6;
}
/* 7. Boutons navigation */
#next-btn, #menu-btn {
display: none;
margin: 20px auto 0;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
#next-btn {
background: #0b54c9;
color: #fff;
}
#menu-btn {
background: #d9534f;
color: #fff;
}
/* 8. Boutons de réponse */
#answer-buttons .btn {
background: #131212de;
border: 1px solid #1e90ff;
border-radius: 50px;
color: #fff;
text-align: left;
}
#answer-buttons .btn:hover {
background: #4682b4;
}
#answer-buttons .btn:disabled {
background: #484444;
}
/* 9. Barre de progression */
#progress-bar {
width: 0;
height: 20px;
background: #4caf50;
margin-bottom: 20px;
transition: width 0.3s;
}
/* 10. Feedback correct/incorrect */
.correct {
background: #2fe980 !important;
}
.incorrect {
background: #f50c0c !important;
}
/* 11. Dispositions supplémentaires */
.subjects {
display: flex;
justify-content: space-between;
}
.small-icon {
width: 90px;
height: 90px;
background-size: cover;
border: none;
cursor: pointer;
}
.watch-link {
position: fixed;
bottom: 10px;
right: 10px;
color: #fff;
text-decoration: none;
}style.cssLa page prend forme, mais le quiz ne fonctionne pas encore :

Étape 3 : donner vie au quiz avec JavaScript
C’est la partie la plus importante de ta Quiz App en JavaScript. Ouvre script.js et copie ce code commenté :
// 1. Définition des questions pour chaque sujet
const subjects = {
PHP: [
{
question: "Quelle fonction permet d'afficher du texte en PHP ?",
answers: [
{ text: "echo", correct: true },
{ text: "print", correct: false },
{ text: "printf", correct: false },
{ text: "write", correct: false }
]
},
// Ajoute d’autres questions si tu veux
],
Python: [
{
question: "Comment écris-tu une fonction en Python ?",
answers: [
{ text: "def ma_fonction():", correct: true },
{ text: "function ma_fonction()", correct: false },
{ text: "func ma_fonction()", correct: false },
{ text: "define ma_fonction()", correct: false }
]
},
// etc.
]
// Complète avec JavaScript, Powershell, Java…
};
// 2. Sélection des éléments dans la page
const questionElement = document.getElementById("question");
const answerButtons = document.getElementById("answer-buttons");
const progressBar = document.getElementById("progress-bar");
const nextButton = document.getElementById("next-btn");
const menuButton = document.getElementById("menu-btn");
const feedbackContainer = document.getElementById("feedback");
const successMessage = document.getElementById("success-message");
const failureMessage = document.getElementById("failure-message");
// 3. Variables pour garder la trace de l’état du jeu
let currentSubject = null;
let currentQuestions = [];
let currentQuestionIndex = 0;
let score = 0;
// 4. Démarrer le quiz quand on choisit un sujet
function selectSubject(subject) {
currentSubject = subject;
currentQuestions = [...subjects[subject]]; // on clone pour ne pas modifier l’original
currentQuestionIndex = 0;
score = 0;
// On cache le menu, on montre le quiz
document.querySelector(".menu").style.display = "none";
document.querySelector(".quiz").style.display = "block";
showQuestion(); // On affiche la première question
}
// 5. Afficher la question actuelle
function showQuestion() {
resetState(); // on vide l’ancien affichage
// On récupère l’objet question
const questionObj = currentQuestions[currentQuestionIndex];
questionElement.innerText = questionObj.question;
// Pour chaque réponse possible, on crée un bouton
questionObj.answers.forEach(answer => {
const btn = document.createElement("button");
btn.innerText = answer.text;
btn.classList.add("btn");
btn.dataset.correct = answer.correct; // on garde l’info si c’est juste
btn.addEventListener("click", selectAnswer);
answerButtons.appendChild(btn);
});
}
// 6. Réinitialiser l’affichage pour la question suivante
function resetState() {
feedbackContainer.style.display = "none";
nextButton.style.display = "none";
answerButtons.innerHTML = ""; // on efface les anciens boutons
const percent = (currentQuestionIndex / currentQuestions.length) * 100;
progressBar.style.width = percent + "%";
}
// 7. Gérer la sélection d’une réponse
function selectAnswer(e) {
const selectedBtn = e.target;
const isCorrect = selectedBtn.dataset.correct === "true";
// On affiche la zone de feedback
feedbackContainer.style.display = "block";
// On colore chaque bouton
Array.from(answerButtons.children).forEach(button => {
button.disabled = true;
if (button.dataset.correct === "true") {
button.classList.add("correct");
} else {
button.classList.add("incorrect");
}
});
// On affiche le message adapté
if (isCorrect) {
score++;
successMessage.style.display = "block";
} else {
failureMessage.style.display = "block";
}
nextButton.style.display = "block"; // on peut passer à la suite
}
// 8. Passer à la question suivante ou afficher le score
nextButton.addEventListener("click", () => {
currentQuestionIndex++;
if (currentQuestionIndex < currentQuestions.length) {
showQuestion();
} else {
showScore();
}
});
// 9. Afficher le score final
function showScore() {
resetState();
questionElement.innerText = `Tu as obtenu ${score} / ${currentQuestions.length}.`;
nextButton.innerText = "Rejouer";
nextButton.style.display = "block";
menuButton.style.display = "block";
}
// 10. Retour au menu principal
menuButton.addEventListener("click", returnToMenu);
function returnToMenu() {
document.querySelector(".quiz").style.display = "none";
document.querySelector(".menu").style.display = "block";
}
// 11. Au chargement de la page, on attend que tu cliques sur un sujetscript.jsCe que fait ce code
Les boutons de réponse sont créés automatiquement à partir des données. Pour ajouter un sujet ou une question, tu modifies uniquement l’objet subjects, sans toucher au reste du code.
Étape 4 : tester et personnaliser
- Enregistre tes fichiers et ouvre
index.htmldans ton navigateur - Choisis un sujet, réponds aux questions et observe la barre de progression
- Ajoute tes propres questions dans l’objet
subjects - Change les couleurs dans
style.csset remplace le logo et les icônes du dossierimages
Aller plus loin
Enregistrer le meilleur score
Grâce au localStorage, le navigateur peut retenir le meilleur score. Appelle cette fonction dans showScore() en lui passant le score obtenu :
function saveBestScore(score) {
const best = Number(localStorage.getItem('bestScore')) || 0;
if (score > best) {
localStorage.setItem('bestScore', score);
return score;
}
return best;
}script.jsD’autres idées pour enrichir ta Quiz App :
- Ajouter un chronomètre pour chaque question
- Mélanger l’ordre des questions et des réponses
- Ajouter un thème sombre
- Charger les questions depuis un fichier JSON avec
fetch() - Découvrir la version mobile : application mobile de tri des déchets
- Continuer avec l’application de gestion de tâches en JavaScript
FAQ : questions fréquentes
Comment ajouter mes propres questions ?
Ouvre script.js et modifie l’objet subjects : chaque question contient son texte et une liste de réponses, dont une marquée comme correcte. Le quiz s’adapte automatiquement.
Puis-je ajouter un nouveau sujet ?
Oui. Ajoute une nouvelle clé dans l’objet subjects avec ses questions, puis un bouton dans index.html qui appelle selectSubject() avec le nom de ce sujet.
Faut-il absolument Bootstrap ?
Non. Bootstrap est facultatif ici : le style principal vient de style.css. Tu peux retirer le lien Bootstrap si tu préfères tout faire à la main.
Ma Quiz App fonctionne-t-elle sur mobile ?
Oui, elle s’affiche dans n’importe quel navigateur. Pour un confort optimal, ajuste les tailles de police et de boutons avec une media query.
Bravo, ta Quiz App en JavaScript est terminée ! De la structure HTML à la logique JavaScript, tu as construit une vraie application. Expérimente, casse pour mieux comprendre, et partage ta version en commentaire !


Le projet est bien structuré, je l’ai repris pour créer un quiz avec mes élèves. Merci
ou mettre les explications des réponses, Merci
Hello Claude,
tu dois stocker une explication dans tes donnéees puis l’afficher après le choix.
Concrètement, il s’agit simplement d’ajoouter un champ explication dans tes données pour chaque réponse (dans answers), avec une petite phrase qui explique pourquoi elle est vraie ou fausse. Comme ici:
{ text: "echo", correct: true, explication: "echo est l'instruction la plus courante pour afficher du texte en PHP." }Ensuite, dans selectAnswer(), récupère l’explication de la réponse cliquée (answer.explication) et affiche-la dans un bloc
"div id="explication""que tu ajoutes sous le feedback.Bàt,