Квиз для подбора ухода за кожей
Карточки-варианты с рисованными иконками вместо скучных радиокнопок. На выходе — одна из трёх программ ухода и форма записи.
<section class="vbkuk">
<div class="vbkuk-wrap">
<h2 class="vbkuk-h2">Какой уход подойдёт вашей коже</h2>
<p class="vbkuk-lead">Три вопроса — и вы увидите программу с составом и стоимостью. Без анкеты на двадцать полей.</p>
<div class="vbkuk-box">
<div class="vbkuk-dots" id="vbkuk-dots" aria-hidden="true"></div>
<div class="vbkuk-stage" id="vbkuk-stage" aria-live="polite"></div>
<button type="button" class="vbkuk-back" id="vbkuk-back" hidden>Вернуться назад</button>
</div>
</div>
</section>
<style>
.vbkuk, .vbkuk *, .vbkuk *::before, .vbkuk *::after { box-sizing: border-box; }
.vbkuk {
--acc: #b9705f; --acc-dark: #a25e4e; --ink: #33272a; --muted: #7a6a6c; --line: #ece1dd; --soft: #faf3f1;
--f: var(--t-text-font, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif);
--fh: var(--t-headline-font, var(--f));
background: #fff; color: var(--ink); font-family: var(--f); padding: clamp(36px, 5vw, 80px) 20px;
}
.vbkuk-wrap { max-width: 1000px; margin: 0 auto; padding: 0 clamp(0px, 2vw, 40px); text-align: center; }
.vbkuk-h2 { font-family: var(--fh); font-size: clamp(26px, 3.4vw, 42px); line-height: 1.1; font-weight: 700; letter-spacing: -.02em; margin: 0 0 12px; }
.vbkuk-lead { font-size: 16px; line-height: 1.6; color: var(--muted); margin: 0 auto 32px; max-width: 34em; }
.vbkuk-box { background: var(--soft); border-radius: 28px; padding: clamp(24px, 3vw, 44px); }
.vbkuk-dots { display: flex; justify-content: center; gap: 7px; margin-bottom: 26px; }
.vbkuk-dots i { width: 30px; height: 4px; border-radius: 4px; background: #e0cdc7; transition: background .25s ease; }
.vbkuk-dots i.is-on { background: var(--acc); }
.vbkuk-q { font-family: var(--fh); font-size: clamp(20px, 2.2vw, 27px); line-height: 1.25; font-weight: 600; margin: 0 0 24px; }
.vbkuk-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.vbkuk-card { border: 1.5px solid var(--line); margin: 0; -webkit-appearance: none; appearance: none; font: inherit; cursor: pointer;
background: #fff !important; color: var(--ink) !important; border-radius: 18px; padding: 20px 14px; transition: .2s ease; }
.vbkuk-card:hover { border-color: var(--acc); transform: translateY(-3px); }
.vbkuk-card svg { display: block; width: 52px; height: 52px; margin: 0 auto 12px; color: var(--acc); }
.vbkuk-card b { display: block; font-size: 15px; font-weight: 600; }
.vbkuk-card i { display: block; font-style: normal; font-size: 12.5px; color: var(--muted); margin-top: 4px; line-height: 1.4; }
.vbkuk-back { border: 0; margin: 22px 0 0; -webkit-appearance: none; appearance: none; background: none !important; cursor: pointer;
font: inherit; font-size: 14px; color: var(--muted) !important; text-decoration: underline; }
.vbkuk-back:hover { color: var(--acc) !important; }
.vbkuk-res { text-align: left; }
.vbkuk-res__tag { display: inline-block; font-size: 12px; font-weight: 600; color: var(--acc); background: #fff; border-radius: 999px; padding: 6px 14px; margin-bottom: 14px; }
.vbkuk-res__ttl { font-family: var(--fh); font-size: clamp(22px, 2.6vw, 30px); line-height: 1.2; font-weight: 700; margin: 0 0 10px; }
.vbkuk-res__txt { font-size: 16px; line-height: 1.6; color: var(--muted); margin: 0 0 20px; }
.vbkuk-res__list { list-style: none; margin: 0 0 20px; padding: 0; display: grid; gap: 9px; }
.vbkuk-res__list li { display: flex; align-items: flex-start; gap: 10px; font-size: 15px; }
.vbkuk-res__list li::before { content: ''; flex: 0 0 7px; width: 7px; height: 7px; margin-top: 8px; border-radius: 50%; background: var(--acc); }
.vbkuk-res__price { display: flex; align-items: baseline; gap: 10px; padding: 16px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); margin-bottom: 20px; }
.vbkuk-res__price b { font-family: var(--fh); font-size: 26px; font-weight: 700; }
.vbkuk-res__price span { font-size: 14px; color: var(--muted); }
.vbkuk-acts { display: flex; flex-wrap: wrap; gap: 10px; }
.vbkuk-cta, .vbkuk-cta:link, .vbkuk-cta:visited, .vbkuk-cta:active, .vbkuk-cta:focus { display: inline-flex; align-items: center; justify-content: center;
min-height: 54px; padding: 0 28px; border-radius: 12px; font-size: 16px; font-weight: 600;
background: var(--acc); color: #fff !important; text-decoration: none !important; transition: background .2s ease; }
.vbkuk-cta:hover { background: var(--acc-dark); color: #fff !important; }
.vbkuk-again { min-height: 54px; padding: 0 24px; border: 1.5px solid var(--line); margin: 0; -webkit-appearance: none; appearance: none;
font: inherit; font-size: 16px; cursor: pointer; border-radius: 12px; background: #fff !important; color: var(--ink) !important; }
.vbkuk-again:hover { border-color: var(--acc); }
@media (max-width: 560px) { .vbkuk-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (prefers-reduced-motion: reduce) { .vbkuk * { transition: none !important; transform: none !important; } }
</style>
<script>
(function () {
var GATE = false; /* true — показывать результат только после отправки контакта */
/* ── ИКОНКИ вариантов: обычные контуры, меняются на любые свои ── */
var ICO = {
drop: '<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M24 6s12 13 12 21a12 12 0 0 1-24 0c0-8 12-21 12-21z"/><\/svg>',
sun: '<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="24" cy="24" r="9"/><path d="M24 5v6M24 37v6M5 24h6M37 24h6M11 11l4 4M33 33l4 4M37 11l-4 4M15 33l-4 4"/><\/svg>',
leaf: '<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M38 10c0 16-10 26-24 28C14 22 24 12 38 10z"/><path d="M14 38c6-9 12-14 20-18"/><\/svg>',
mask: '<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 16c0-4 6-7 14-7s14 3 14 7c0 14-6 24-14 24S10 30 10 16z"/><path d="M18 22h2M28 22h2M20 30q4 3 8 0"/><\/svg>',
clock: '<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="24" cy="24" r="17"/><path d="M24 13v11l7 5"/><\/svg>',
spark: '<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M24 6l4 12 12 4-12 4-4 12-4-12-12-4 12-4z"/><\/svg>'
};
/* ── ВОПРОСЫ: p — очки программам (calm / deep / anti) ── */
var QUESTIONS = [
{ q: 'Как кожа ведёт себя к вечеру?', opts: [
{ t: 'Стянутость', s: 'сухость, шелушение', ico: 'drop', p: { calm: 2, deep: 0, anti: 1 } },
{ t: 'Жирный блеск', s: 'т-зона блестит', ico: 'sun', p: { calm: 0, deep: 2, anti: 0 } },
{ t: 'Покраснения', s: 'реагирует на всё', ico: 'leaf', p: { calm: 2, deep: 0, anti: 0 } },
{ t: 'Тусклость', s: 'нет свежести', ico: 'spark', p: { calm: 0, deep: 1, anti: 2 } }
]},
{ q: 'Что хочется исправить в первую очередь?', opts: [
{ t: 'Высыпания', s: 'воспаления, чёрные точки', ico: 'mask', p: { calm: 1, deep: 2, anti: 0 } },
{ t: 'Тонус', s: 'овал, упругость', ico: 'clock', p: { calm: 0, deep: 0, anti: 2 } },
{ t: 'Ровный тон', s: 'пигментация, следы', ico: 'spark', p: { calm: 0, deep: 1, anti: 2 } },
{ t: 'Увлажнение', s: 'обезвоженность', ico: 'drop', p: { calm: 2, deep: 0, anti: 1 } }
]},
{ q: 'Сколько времени готовы уделять уходу?', opts: [
{ t: 'Раз в месяц', s: 'поддержка', ico: 'clock', p: { calm: 2, deep: 1, anti: 0 } },
{ t: 'Раз в 2 недели', s: 'курс', ico: 'leaf', p: { calm: 0, deep: 2, anti: 1 } },
{ t: 'Готова на курс', s: '8–10 процедур', ico: 'spark', p: { calm: 0, deep: 1, anti: 2 } }
]}
];
/* ── РЕЗУЛЬТАТЫ: три программы ── */
var RESULTS = {
calm: { tag: 'Ваша программа', ttl: 'Восстановление и увлажнение',
txt: 'Коже не хватает влаги и защитного барьера. Задача — не чистить агрессивно, а восстановить: тогда уходят и стянутость, и реактивные покраснения.',
list: ['Ультразвуковая чистка без травматизации', 'Альгинатная маска с гиалуроновой кислотой', 'Массаж по лимфодренажным линиям', 'Подбор домашнего ухода на 2 месяца'],
price: 'от 4 200 ₽', per: 'за процедуру, курс из 4 — со скидкой 15%' },
deep: { tag: 'Ваша программа', ttl: 'Глубокое очищение',
txt: 'Работаем с себумом и закупоркой пор. Сначала снимаем воспаления, потом нормализуем работу сальных желёз — иначе высыпания возвращаются через месяц.',
list: ['Комбинированная чистка лица', 'Пилинг с салициловой кислотой', 'Себорегулирующая маска', 'Протокол домашнего ухода без пересушивания'],
price: 'от 3 800 ₽', per: 'за процедуру, курс из 6 — со скидкой 20%' },
anti: { tag: 'Ваша программа', ttl: 'Тонус и ровный тон',
txt: 'Плотность кожи и пигментация меняются курсом, а не за один визит. Программа собрана так, чтобы результат был виден к третьей процедуре и держался.',
list: ['Срединный пилинг по показаниям', 'Микротоковая терапия', 'Курс сывороток с витамином C', 'Домашний протокол с SPF'],
price: 'от 5 600 ₽', per: 'за процедуру, курс из 8 — по абонементу' }
};
var CTA_HREF = '#zapis'; /* куда ведёт кнопка записи */
var roots = document.querySelectorAll('.vbkuk');
for (var i = 0; i < roots.length; i++) init(roots[i]);
function init(root) {
if (root.__vb) return; root.__vb = 1;
var idx = 0, score = { calm: 0, deep: 0, anti: 0 };
var stage = root.querySelector('#vbkuk-stage'), dots = root.querySelector('#vbkuk-dots'), back = root.querySelector('#vbkuk-back');
var history = [];
for (var d = 0; d < QUESTIONS.length; d++) dots.appendChild(document.createElement('i'));
function marks() {
dots.querySelectorAll('i').forEach(function (el, i) { el.classList.toggle('is-on', i <= idx && idx < QUESTIONS.length || idx >= QUESTIONS.length); });
}
function drawStep() {
var s = QUESTIONS[idx];
back.hidden = idx === 0;
marks();
var html = '<h3 class="vbkuk-q">' + s.q + '<\/h3><div class="vbkuk-cards">';
s.opts.forEach(function (o, i) {
html += '<button type="button" class="vbkuk-card" data-i="' + i + '">' + ICO[o.ico] + '<b>' + o.t + '<\/b><i>' + o.s + '<\/i><\/button>';
});
stage.innerHTML = html + '<\/div>';
stage.querySelectorAll('.vbkuk-card').forEach(function (b) {
b.addEventListener('click', function () {
var o = s.opts[+b.dataset.i];
history.push(o.p);
Object.keys(o.p).forEach(function (k) { score[k] += o.p[k]; });
idx++;
if (idx < QUESTIONS.length) drawStep(); else drawResult();
});
});
}
function drawResult() {
marks();
back.hidden = false;
var win = Object.keys(score).sort(function (a, b) { return score[b] - score[a]; })[0];
var r = RESULTS[win];
stage.innerHTML =
'<div class="vbkuk-res"><span class="vbkuk-res__tag">' + r.tag + '<\/span>' +
'<h3 class="vbkuk-res__ttl">' + r.ttl + '<\/h3>' +
'<p class="vbkuk-res__txt">' + r.txt + '<\/p>' +
'<ul class="vbkuk-res__list">' + r.list.map(function (x) { return '<li>' + x + '<\/li>'; }).join('') + '<\/ul>' +
'<div class="vbkuk-res__price"><b>' + r.price + '<\/b><span>' + r.per + '<\/span><\/div>' +
'<div class="vbkuk-acts"><a class="vbkuk-cta" href="' + CTA_HREF + '">Записаться на консультацию<\/a>' +
'<button type="button" class="vbkuk-again">Пройти заново<\/button><\/div><\/div>';
var again = stage.querySelector('.vbkuk-again');
if (again) again.addEventListener('click', restart);
}
function restart() {
idx = 0; score = { calm: 0, deep: 0, anti: 0 }; history = [];
drawStep();
}
back.addEventListener('click', function () {
if (idx === 0) return;
idx--;
var p = history.pop();
if (p) Object.keys(p).forEach(function (k) { score[k] -= p[k]; });
drawStep();
});
if (GATE) { /* при включённом GATE результат прячется за формой — см. описание блока */ }
drawStep();
}
})();
</script> Вставляется целиком в блок T123 «HTML-код». Внутри уже есть стили и скрипт, подключать ничего не нужно.
Как вставить блок в Tilda
- Скопируйте кодКнопка «Скопировать код» выше кладёт всё содержимое в буфер обмена.
- Добавьте блок T123В редакторе страницы: «Библиотека блоков» → «Другое» → T123 «HTML-код».
- Вставьте и сохранитеНажмите «Контент», вставьте код в поле, сохраните и обновите страницу.
- ОпубликуйтеВ превью скрипты Tilda работают не всегда — проверяйте на опубликованной странице.
Подробная инструкция с граблями — как вставить вайб-блок в Tilda.
Что менять под себя
| Где в коде | За что отвечает |
|---|---|
массив QUESTIONS | вопросы, варианты и очки, которые они дают программам |
объект RESULTS | три итоговые программы: название, описание, состав |
SVG в карточках | иллюстрации вариантов — простые контуры |
Квиз «Подбор ухода за кожей»: зачем он нужен
Подбор ухода — тот случай, когда квиз не выглядит навязанным: человек и правда хочет понять, что ему подходит. Варианты сделаны карточками с иллюстрациями, поэтому шаг проходится глазами, а не чтением.
Логика ветвления простая и читаемая: каждый ответ добавляет очки трём программам, побеждает та, что набрала больше. Правится в одной функции — можно переделать под свои услуги за десять минут.
Вопросы по этому блоку
-
Все три программы лежат в объекте RESULTS: заголовок, описание, список процедур и цена. Добавить четвёртую — дописать ключ и указать его в очках вариантов.
-
В базовой версии — нет, результат показывается сразу, а форма идёт под ним. Если хотите закрыть результат за контактом, в скрипте есть флаг GATE, переключите его в true.
-
Да. Код на этой странице копируется целиком, без регистрации и подписки. Указывать авторство не нужно, использовать можно в коммерческих проектах.
-
Нет. Все классы внутри имеют собственный префикс vbkuk, поэтому не пересекаются ни со стилями Tilda, ни с другими блоками. Скрипт привязан к своему элементу и запускается один раз, даже если блок вставлен дважды.
-
Раскладка перестраивается под узкие экраны, размеры заданы через clamp, поля ввода имеют шрифт 16 пикселей — iOS не будет зумить страницу при фокусе. Отдельной мобильной версии подключать не нужно.
Другие квизы
Ещё блоки для салонов красоты
Собрать сайт целиком, а не по блокам
Дровосеки делают сайты на Tilda под ключ: структура, тексты, дизайн, вёрстка и вайб-блоки под задачи бизнеса.