Содержание
Длинная форма с 10 полями на одном экране пугает посетителей — конверсия падает. Та же форма, разбитая на 3-4 коротких шага, даёт в 1.5-2 раза больше заявок. Почему так работает: каждый шаг — небольшое психологическое обязательство, отвечать на короткие вопросы проще, прогресс-бар стимулирует дойти до конца. В статье — готовый код многошаговой формы на чистом HTML+JS, без библиотек, с валидацией, сохранением прогресса и отправкой данных.
Содержание
- Зачем нужна многошаговая форма
- Когда использовать
- Как разбить на шаги
- HTML-структура
- CSS-стили
- JS-логика переходов
- Валидация по шагам
- Сохранение прогресса при выходе
- Отправка формы
- Приёмы повышения конверсии
- Частые ошибки
- FAQ
- Чек-лист
Зачем нужна многошаговая форма
- Снижает страх формы. 3 поля на экране не пугают, как 10.
- Эффект вовлечения. Заполнил один шаг — психологически обязан продолжить.
- Прогресс мотивирует. «Осталось 1 из 3» — стимул дойти до конца.
- Можно собрать больше данных. Тот, кто прошёл шаг 1, спокойно заполнит и шаг 3.
- Аналитика воронки. Видно, на каком шаге отваливаются — можно оптимизировать.
Когда использовать
Многошаговая форма выгодна, когда:
- Нужно собрать 5+ полей данных;
- Аудитория «холодная» — нужно их «прогреть» в процессе;
- Продукт сложный — много параметров;
- Высокая стоимость лида — оправдывает усложнение.
НЕ нужна, когда:
- Только 2-3 поля (имя + телефон);
- Аудитория готовая и нетерпеливая;
- Простой массовый продукт.
Как разбить на шаги
Правильное разбиение — это половина успеха.
- Сначала простые вопросы. Тип услуги, выбор из вариантов — не требует усилий.
- Потом более сложные. Параметры, объём, требования.
- Контакты в конце. Когда пользователь уже инвестирован.
Пример для лендинга ремонта:
- Шаг 1: Тип помещения (квартира / дом / офис).
- Шаг 2: Площадь.
- Шаг 3: Тип ремонта (косметический, евро, дизайнерский).
- Шаг 4: Контакты (имя, телефон).
HTML-структура
<form id="multistep-form">
<!-- Прогресс -->
<div class="progress-bar">
<div class="progress-fill" id="progress-fill"></div>
</div>
<p class="step-counter">Шаг <span id="current">1</span> из 4</p>
<!-- Шаг 1 -->
<div class="form-step active" data-step="1">
<h2>Тип помещения?</h2>
<label><input type="radio" name="type" value="квартира" required> Квартира</label>
<label><input type="radio" name="type" value="дом" required> Дом</label>
<label><input type="radio" name="type" value="офис" required> Офис</label>
<button type="button" class="next-btn">Далее</button>
</div>
<!-- Шаг 2 -->
<div class="form-step" data-step="2">
<h2>Площадь, м²?</h2>
<input type="number" name="area" min="1" required>
<button type="button" class="prev-btn">Назад</button>
<button type="button" class="next-btn">Далее</button>
</div>
<!-- Шаг 3 -->
<div class="form-step" data-step="3">
<h2>Тип ремонта?</h2>
<label><input type="radio" name="kind" value="косметический" required> Косметический</label>
<label><input type="radio" name="kind" value="евро" required> Евро</label>
<label><input type="radio" name="kind" value="дизайнерский" required> Дизайнерский</label>
<button type="button" class="prev-btn">Назад</button>
<button type="button" class="next-btn">Далее</button>
</div>
<!-- Шаг 4 (финальный) -->
<div class="form-step" data-step="4">
<h2>Куда отправить расчёт?</h2>
<input type="text" name="name" placeholder="Имя" required>
<input type="tel" name="phone" placeholder="Телефон" required>
<button type="button" class="prev-btn">Назад</button>
<button type="submit">Получить расчёт</button>
</div>
</form>
CSS-стили
.form-step { display: none; }
.form-step.active { display: block; }
.progress-bar {
width: 100%;
height: 6px;
background: #eee;
border-radius: 3px;
margin-bottom: 1rem;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: #4a5cf5;
width: 25%;
transition: width 0.3s;
}
.step-counter {
text-align: center;
color: #666;
margin-bottom: 2rem;
}
.form-step label {
display: block;
padding: 1rem;
margin: 0.5rem 0;
border: 1px solid #ddd;
border-radius: 6px;
cursor: pointer;
}
.form-step label:hover { background: #f5f6ff; }
.form-step input[type="text"],
.form-step input[type="tel"],
.form-step input[type="number"] {
width: 100%;
padding: 1rem;
margin: 0.5rem 0;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 1rem;
}
.next-btn, button[type="submit"] {
width: 100%;
padding: 1rem;
background: #4a5cf5;
color: white;
border: none;
border-radius: 6px;
font-weight: 600;
margin-top: 1rem;
cursor: pointer;
}
.prev-btn {
background: #eee;
color: #333;
border: none;
padding: 0.75rem 1.5rem;
border-radius: 6px;
margin-right: 0.5rem;
cursor: pointer;
}
JS-логика переходов
const form = document.getElementById('multistep-form');
const steps = form.querySelectorAll('.form-step');
const totalSteps = steps.length;
let currentStep = 1;
function showStep(step) {
steps.forEach(s => s.classList.remove('active'));
form.querySelector(`[data-step="${step}"]`).classList.add('active');
document.getElementById('current').textContent = step;
document.getElementById('progress-fill').style.width = (step / totalSteps * 100) + '%';
}
form.querySelectorAll('.next-btn').forEach(btn => {
btn.addEventListener('click', () => {
const stepEl = btn.closest('.form-step');
if (!validateStep(stepEl)) return;
currentStep++;
showStep(currentStep);
ym(СЧЁТЧИК, 'reachGoal', `form_step_${currentStep}`);
});
});
form.querySelectorAll('.prev-btn').forEach(btn => {
btn.addEventListener('click', () => {
currentStep--;
showStep(currentStep);
});
});
Валидация по шагам
function validateStep(stepEl) {
const inputs = stepEl.querySelectorAll('input[required]');
for (const input of inputs) {
if (input.type === 'radio') {
const name = input.name;
const checked = stepEl.querySelector(`input[name="${name}"]:checked`);
if (!checked) {
alert('Выберите вариант');
return false;
}
} else if (!input.value.trim()) {
input.focus();
input.style.borderColor = 'red';
return false;
}
}
return true;
}
Сохранение прогресса при выходе
Если пользователь закрыл вкладку и вернулся — пусть продолжит с того места. Через localStorage:
// Сохраняем при изменении любого поля
form.addEventListener('input', () => {
const data = {};
new FormData(form).forEach((value, key) => { data[key] = value; });
data._step = currentStep;
localStorage.setItem('form_progress', JSON.stringify(data));
});
// Восстанавливаем при загрузке
window.addEventListener('load', () => {
const saved = localStorage.getItem('form_progress');
if (!saved) return;
const data = JSON.parse(saved);
for (const [key, value] of Object.entries(data)) {
if (key === '_step') continue;
const input = form.querySelector(`[name="${key}"]`);
if (!input) continue;
if (input.type === 'radio') {
const radio = form.querySelector(`[name="${key}"][value="${value}"]`);
if (radio) radio.checked = true;
} else {
input.value = value;
}
}
if (data._step) {
currentStep = data._step;
showStep(currentStep);
}
});
Отправка формы
form.addEventListener('submit', async (e) => {
e.preventDefault();
const data = {};
new FormData(form).forEach((value, key) => { data[key] = value; });
const text = `🔔 Заявка
Тип: ${data.type}
Площадь: ${data.area} м²
Ремонт: ${data.kind}
Имя: ${data.name}
Телефон: ${data.phone}`;
await fetch(`https://api.telegram.org/bot${TOKEN}/sendMessage`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ chat_id: CHAT_ID, text })
});
localStorage.removeItem('form_progress');
ym(СЧЁТЧИК, 'reachGoal', 'form_complete');
window.location.href = '/thank-you.html';
});
Приёмы повышения конверсии
- Понятный CTA на каждом шаге. «Далее» лучше, чем «Submit». «Получить расчёт» лучше «Отправить».
- Картинки в вариантах. Дизайн квартиры, типа ремонта — увеличивает вовлечение.
- Прогресс-бар крупно. Чтобы пользователь видел путь.
- Сначала легкие вопросы. Сначала кликнуть на вариант → потом печатать.
- Социальное доказательство между шагами. «Уже подобрали ремонт для 1287 клиентов».
- Подарок на финале. «Получите бесплатный 3D-эскиз планировки».
- Адаптивность. На мобильном — отдельная вёрстка с большими кнопками.
Частые ошибки
- Слишком много шагов. Больше 5-6 — устают, бросают. Оптимум 3-4.
- Контакты в начале. Снижает конверсию в начале формы. Только в конце.
- Нет валидации по шагам. Пропускают пустые поля — данные неполные.
- Невозможно вернуться. Кнопка «Назад» обязательна.
- Нет прогресса. Пользователь не понимает, сколько осталось.
- Сложные вопросы. «Какой тип утеплителя?» — посетитель не знает.
- Не сохраняется прогресс. Случайно закрыл — начинай заново. Используйте localStorage.
FAQ
3-5 шагов. До 3 — может не оправдать сложности. Больше 5 — устают. Главное — каждый шаг должен давать ценность.
В последнем. Психология: ответил на 3 вопроса → вложился → даст контакт. В начале — пугает, бросает.
На каждом шаге отправляйте цель в Метрику: form_step_1, form_step_2, form_complete. В отчёте увидите воронку — где отваливаются.
Если полей < 5 — одна форма. Если 5+ полей — многошаговая. Если форма требует выбора из вариантов (квиз-стиль) — многошаговая в любом случае.
Только если шаг необязательный — например, «Дополнительные пожелания». Обязательные данные пропускать нельзя.
Стоит. До 15% пользователей возвращаются. Если форма с нуля — большая часть бросает повторно. Если с сохранённым прогрессом — заканчивают.
Да, для радио-кнопок (HTML5 required не всегда работает корректно в многошаговой) и для перехода между шагами. Иначе кликнул «Далее» с пустым полем — перешёл.
Чек-лист многошаговой формы
- ☐ Форма разбита на 3-5 шагов
- ☐ Шаги от простого к сложному
- ☐ Контакты на последнем шаге
- ☐ Прогресс-бар отображает текущий шаг
- ☐ Кнопки «Далее» и «Назад» на каждом шаге
- ☐ Валидация полей на каждом шаге
- ☐ Прогресс сохраняется в localStorage
- ☐ Отправка данных через Telegram/Email/CRM
- ☐ Цели в Метрике на каждый шаг
- ☐ Адаптивность на мобильных
- ☐ Понятный CTA на финальной кнопке
- ☐ Страница «Спасибо» после отправки
Заключение
Многошаговая форма — мощный инструмент роста конверсии в нишах со сложным продуктом и длинными формами. 3-4 коротких шага вместо одной длинной формы дают в полтора-два раза больше заявок. Реализуется на чистом HTML+JS за несколько часов, не требует библиотек и сервисов.
Готовые HTML-шаблоны Zettabyte часто содержат заготовки многошаговых форм — остаётся подключить обработчик и адаптировать вопросы. А для размещения лендинга подойдёт самый недорогой тариф из подборщика хостингов.