В этом статье мы создадим простой, но функциональный квиз с вопросами и вариантами ответов. Такой квиз отлично подходит для сбора данных, проведения опросов или создания тестов на сайте. Основная идея — у пользователя есть несколько шагов, каждый из которых содержит вопрос и набор ответов на выбор.
Вёрстка и стиль
Начнём с того, что дизайн квиза минималистичен, но при этом функционален. Всё начинается с фона: мы добавляем фоновое изображение, которое фиксируется при прокрутке страницы, создавая приятный визуальный эффект. Квиз выровнен по центру страницы и имеет ограниченную ширину, что делает его удобным для восприятия и не перегружает экран.
Кнопки, аватары, контейнеры для ответов — всё оформлено с учётом UX (пользовательского опыта). Прогресс-бар плавно изменяется с каждым шагом, помогая ориентироваться в процессе.
HTML
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="css/font.css" />
<link rel="stylesheet" href="css/reset.css" />
<link rel="stylesheet" href="css/base.css" />
<link rel="stylesheet" href="css/style.css" />
<title>Пример простого квиза</title>
</head>
<body>
<div class="container">
<div class="quiz">
<!-- Форма, которая содержит весь квиз -->
<form action="#!" class="quiz__form">
<!-- Поле для каждого шага квиза -->
<fieldset class="quiz__fieldset">
<legend class="quiz__legend">
<img src="./images/ava.webp" alt="avatar" class="quiz__ava" />
<div class="quiz__question">
<p>Оператор</p>
<!-- Здесь будет отображаться текст вопроса -->
<p id="question-text"></p>
</div>
</legend>
<!-- Прогресс бар -->
<div class="quiz__progress">
<div class="quiz__progress-line">
<div id="progress-fill" class="quiz__progress-fill"></div>
</div>
</div>
<!-- Контейнер для отображения ответов -->
<div class="quiz__answer" id="answers-container">
<!-- Ответы будут добавлены динамически через JavaScript -->
</div>
</fieldset>
<!-- Кнопка для перехода к следующему шагу -->
<button type="button" class="quiz__button" onclick="nextStep()">
Далее
</button>
</form>
</div>
</div>
<!-- Подключение файла JavaScript -->
<script src="./js/script.js"></script>
</body>
</html>
CSS
/* Стили для body, добавляют фоновое изображение */
body {
background-image: url(../images/low-angle-office.webp);
background-attachment: fixed;
background-size: cover;
}
/* Основной контейнер квиза */
.quiz {
width: 100%;
max-width: 900px;
display: flex;
flex-direction: column;
align-items: center;
flex: 1 0 auto;
margin-left: auto;
margin-right: auto;
user-select: none;
margin: 200px;
}
/* Стили для формы квиза */
.quiz__form {
display: flex;
flex-direction: column;
width: 100%;
background-color: #fff;
padding: 50px;
border-radius: 5px;
}
/* Поле для шага квиза */
.quiz__fieldset {
margin-bottom: 50px;
}
/* Легенда с вопросом и аватаром */
.quiz__legend {
display: flex;
align-items: center;
background-color: #f1f1f1;
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
width: 100%;
}
/* Стили для аватара */
.quiz__ava {
width: 60px;
margin-right: 20px;
}
/* Стили для вопроса */
.quiz__question p:first-child {
text-transform: uppercase;
font-weight: 500;
}
/* Контейнер для прогресс-бара */
.quiz__progress {
width: 100%;
height: 10px;
margin-bottom: 20px;
}
/* Линия прогресса */
.quiz__progress-line {
width: 100%;
height: 10px;
background-color: #ddd;
border-radius: 5px;
}
/* Заполнение прогресс-бара */
.quiz__progress-fill {
width: 20%;
height: 10px;
background: linear-gradient(45deg, #1fadff 0, #2684bb 100%);
border-radius: 5px;
transition: width 0.3s;
}
/* Сетка для ответов */
.quiz__answer {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
}
/* Стили для ответа */
.quiz__answer-item {
display: flex;
align-items: center;
border: 1px solid #bbb;
padding: 10px;
border-radius: 5px;
cursor: pointer;
}
/* Круг для отметки ответа */
.quiz__answer-item-circle {
width: 25px;
height: 25px;
border-radius: 5px;
border: 1px solid #bbb;
margin-right: 15px;
position: relative;
}
/* Иконка "проверки" ответа */
.quiz__answer-item-circle:after {
width: 20px;
height: 22px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
content: url(../images/check.svg);
opacity: 0;
transition: opacity 0.3s;
}
/* Текст ответа */
.quiz__answer-item-text {
line-height: 1.5;
}
/* Скрытие радиокнопок */
.quiz__answer-item input {
display: none;
}
/* Стили для выбранного ответа */
.quiz__answer-item input:checked + .quiz__answer-item-circle {
border: 1px solid #2684bb;
}
.quiz__answer-item input:checked + .quiz__answer-item-circle:after {
opacity: 1;
}
/* Стили для кнопки перехода */
.quiz__button {
width: 300px;
font-weight: 700;
color: #fff;
padding: 10px 0;
background: linear-gradient(45deg, #1fadff 0, #2684bb 100%);
border-radius: 5px;
margin: 0 auto;
cursor: pointer;
font-size: 17px;
text-align: center;
}
Логика квиза
Само взаимодействие происходит на стороне JavaScript. Вся логика крутится вокруг массива formSteps с вопросами и ответами. Каждый шаг представлен объектом, где есть свой текст вопроса и возможные варианты ответов. Это позволяет легко добавлять новые вопросы или редактировать существующие.
Ключевая функция — renderStep() — отвечает за отрисовку текущего вопроса и вариантов ответов. Когда пользователь выбирает один из ответов и нажимает кнопку «Далее», происходит переход к следующему вопросу. Если пользователь не выбрал ответ, его уведомят, что необходимо выбрать один из вариантов.
JavaScript
// Данные о каждом шаге квиза, включая вопрос и возможные ответы
const formSteps = [
{
question: "Что для вас является самым важным при выборе недвижимости?",
answers: [
"Близость к работе или учебе",
"Тихий район и хорошие соседи",
"Развитая инфраструктура и удобства",
"Инвестиционная привлекательность",
],
},
{
question:
"Какие дополнительные удобства вы бы хотели видеть в вашей новой недвижимости?",
answers: [
"Фитнес-центр или бассейн на территории",
"Парковочные места для автомобилей",
"Охраняемая территория и видеонаблюдение",
"Зона для барбекю и отдыха",
],
},
{
question: "Как вы планируете использовать новую недвижимость?",
answers: [
"Личное проживание",
"Сдача в аренду",
"Коммерческая деятельность",
"Как дача для отдыха",
],
},
{
question: "Какой вид вам хотелось бы видеть из окон?",
answers: [
"Панорама города",
"Вид на парк или лес",
"Вид на воду — реку или озеро",
"Горы или природные ландшафты",
],
},
{
question: "Что для вас важнее всего в плане ремонта и отделки?",
answers: [
"Максимальная готовность для заселения",
"Возможность сделать ремонт по своему вкусу",
"Экологически чистые и современные материалы",
"Ретро-стиль или уникальный дизайн",
],
},
{
question: "Какой этаж для вас предпочтителен?",
answers: [
"Первый этаж, ближе к выходу",
"Средние этажи (2-5)",
"Высокие этажи с видом",
"Без разницы, главное — удобство",
],
},
{
question: "Какая отделка вам ближе?",
answers: [
"Минималистичный стиль",
"Классический интерьер",
"Современный дизайн с акцентами",
"Скандинавский стиль или лофт",
],
},
{
question: "Насколько важна для вас экологичность района?",
answers: [
"Очень важна, хочу жить в зелёной зоне",
"Не имеет значения",
"Важно, но возможны компромиссы",
"Интересует, если это в пределах города",
],
},
{
question: "Какой доступ к транспорту вам необходим?",
answers: [
"Станция метро или остановка в шаговой доступности",
"Необходима парковка для личного автомобиля",
"Предпочитаю велодорожки и пешие маршруты",
"Не принципиально, работаю удалённо",
],
},
{
question: "Какие особенности дома или здания для вас важны?",
answers: [
"Новая постройка",
"Историческое здание",
"Дом с террасой или садом",
"Комплекс с закрытой территорией",
],
},
];
// Переменная для отслеживания текущего шага
let currentStep = 0;
// Массив для хранения выбранных ответов
let selectedAnswers = [];
// Функция для отображения текущего шага квиза
function renderStep() {
const questionText = document.getElementById("question-text");
const answersContainer = document.getElementById("answers-container");
const progressFill = document.getElementById("progress-fill");
// Отображаем текущий вопрос
questionText.textContent = formSteps[currentStep].question;
answersContainer.innerHTML = "";
// Создаем элементы для каждого ответа
formSteps[currentStep].answers.forEach((answer, index) => {
const label = document.createElement("label");
label.classList.add("quiz__answer-item");
label.setAttribute("for", `answer-${index}`);
const input = document.createElement("input");
input.setAttribute("type", "radio");
input.setAttribute("name", `question-${currentStep}`);
input.setAttribute("id", `answer-${index}`);
input.value = answer;
const circle = document.createElement("div");
circle.classList.add("quiz__answer-item-circle");
const text = document.createElement("div");
text.classList.add("quiz__answer-item-text");
text.textContent = answer;
label.appendChild(input);
label.appendChild(circle);
label.appendChild(text);
answersContainer.appendChild(label);
});
// Обновляем прогресс-бар
const progress = ((currentStep + 1) / formSteps.length) * 100;
progressFill.style.width = progress + "%";
}
// Функция для перехода к следующему шагу
function nextStep() {
const selectedAnswer = document.querySelector(
`input[name="question-${currentStep}"]:checked`
);
if (selectedAnswer) {
// Сохраняем выбранный ответ
selectedAnswers.push({
question: formSteps[currentStep].question,
answer: selectedAnswer.value,
});
} else {
alert("Пожалуйста, выберите ответ.");
return;
}
// Переход к следующему шагу или завершение квиза
if (currentStep < formSteps.length - 1) {
currentStep++;
renderStep();
} else {
const messageText = selectedAnswers
.map(
(step, index) =>
`Вопрос ${index + 1}: ${step.question}\nОтвет: ${step.answer}`
)
.join("\n\n");
sendResults(messageText);
alert("Квиз завершён");
}
}
// Функция для отправки результатов
function sendResults(data) {
// Выводим данные в консоль для отладки
console.log("Отправляем данные...");
console.log(data);
// Здесь можно добавить код для отправки данных на сервер
}
document.addEventListener("DOMContentLoaded", renderStep);
Важные моменты
- Гибкость: Квиз легко масштабируется: можно добавить сколько угодно шагов, просто расширив массив вопросов.
- Обратная связь: После завершения всех шагов пользователю выводятся результаты — он видит свои ответы на каждый вопрос.
- Простота в изменении стилей: CSS здесь структурирован так, что можно легко менять цвета, шрифты, размеры элементов, подстраивая дизайн под конкретный проект.
Такой квиз может быть полезен в самых разных сферах: от маркетинговых опросов до помощи в подборе недвижимости или обучения. Важно помнить, что основной акцент здесь сделан на простоту и удобство для пользователя.