Задать вопрос директору
Telegram
VK
Звонок

Квиз подбора проекта дома для Tilda

Четыре вопроса о будущем доме и подбор типового проекта по сумме очков. В результате посетитель видит название проекта, вилку цены под ключ, срок стройки и типовую площадь.

Живое демо — блок работает прямо здесь

Код блока

<section class="vbkpd">
  <div class="vbkpd-wrap">
    <div class="vbkpd-head">
      <h2 class="vbkpd-h2">Какой дом вам подойдёт</h2>
      <p class="vbkpd-lead">Четыре вопроса про этажность, площадь, материал стен и бюджет. В ответ покажем тип проекта, вилку цены и срок стройки.</p>
    </div>

    <div class="vbkpd-box">
      <div class="vbkpd-bar" id="vbkpd-bar"></div>
      <div class="vbkpd-stage" id="vbkpd-stage" aria-live="polite"></div>
      <div class="vbkpd-foot">
        <button type="button" class="vbkpd-back" id="vbkpd-back" hidden>Вернуться к прошлому вопросу</button>
        <span class="vbkpd-num" id="vbkpd-num"></span>
      </div>
    </div>
  </div>
</section>

<style>
.vbkpd, .vbkpd *, .vbkpd *::before, .vbkpd *::after { box-sizing: border-box; }
.vbkpd {
  --acc: #4d6b4a; --acc-dark: #3d5739; --ink: #1f2320; --muted: #656d63; --line: #dde2da; --soft: #f2f5f0;
  --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;
}
.vbkpd-wrap { max-width: 920px; margin: 0 auto; padding: 0 clamp(0px, 2vw, 40px); }
.vbkpd-head { max-width: 40em; margin-bottom: clamp(22px, 3vw, 34px); }
.vbkpd-h2 { font-family: var(--fh); font-size: clamp(26px, 3.4vw, 40px); line-height: 1.1; font-weight: 700; letter-spacing: -.022em; margin: 0 0 12px; }
.vbkpd-lead { font-size: 16px; line-height: 1.6; color: var(--muted); margin: 0; }

.vbkpd-box { border: 1px solid var(--line); border-radius: 24px; padding: clamp(22px, 3vw, 40px); background: var(--soft); }
.vbkpd-bar { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin-bottom: 26px; }
.vbkpd-bar i { display: block; height: 5px; border-radius: 5px; background: #dfe4dc; transition: background .3s ease; }
.vbkpd-bar i.vbkpd-bar--on { background: var(--acc); }

.vbkpd-q { font-family: var(--fh); font-size: clamp(19px, 2.1vw, 25px); line-height: 1.28; font-weight: 600; margin: 0 0 6px; }
.vbkpd-hint { font-size: 14px; line-height: 1.55; color: var(--muted); margin: 0 0 18px; }
.vbkpd-opts { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 10px; }
.vbkpd-opt { display: block; width: 100%; text-align: left; border: 1.5px solid var(--line); margin: 0; padding: 16px 18px;
  -webkit-appearance: none; appearance: none; font: inherit; cursor: pointer; border-radius: 14px;
  background: #fff !important; color: var(--ink) !important; transition: border-color .18s ease, transform .18s ease; }
.vbkpd-opt:hover { border-color: var(--acc); transform: translateY(-2px); }
.vbkpd-opt b { display: block; font-size: 15.5px; font-weight: 600; line-height: 1.35; }
.vbkpd-opt span { display: block; font-size: 13px; line-height: 1.45; color: var(--muted); margin-top: 5px; }

.vbkpd-foot { display: flex; align-items: center; gap: 16px; margin-top: 22px; }
.vbkpd-back { border: 0; margin: 0; padding: 0; -webkit-appearance: none; appearance: none; background: none !important; cursor: pointer;
  font: inherit; font-size: 14px; color: var(--muted) !important; text-decoration: underline; text-underline-offset: 3px; }
.vbkpd-back:hover { color: var(--acc) !important; }
.vbkpd-num { margin-left: auto; font-size: 13px; color: var(--muted); }

.vbkpd-res__tag { display: inline-block; font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--acc); background: #fff; border-radius: 999px; padding: 7px 15px; margin-bottom: 14px; }
.vbkpd-res__ttl { font-family: var(--fh); font-size: clamp(22px, 2.8vw, 32px); line-height: 1.14; font-weight: 700; margin: 0 0 12px; }
.vbkpd-res__txt { font-size: 15.5px; line-height: 1.65; color: var(--muted); margin: 0 0 20px; max-width: 42em; }
.vbkpd-res__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; margin-bottom: 22px; }
.vbkpd-res__grid div { background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 15px 17px; }
.vbkpd-res__grid b { display: block; font-family: var(--fh); font-size: 19px; font-weight: 700; line-height: 1.2; }
.vbkpd-res__grid span { display: block; font-size: 12.5px; color: var(--muted); margin-top: 5px; }
.vbkpd-acts { display: flex; flex-wrap: wrap; gap: 10px; }
.vbkpd-cta, .vbkpd-cta:link, .vbkpd-cta:visited, .vbkpd-cta:active, .vbkpd-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; }
.vbkpd-cta:hover { background: var(--acc-dark); color: #fff !important; }
.vbkpd-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; }
.vbkpd-again:hover { border-color: var(--acc); }

@media (max-width: 560px) { .vbkpd-opts { grid-template-columns: minmax(0, 1fr); } }
@media (prefers-reduced-motion: reduce) { .vbkpd * { transition: none !important; transform: none !important; } }
</style>

<script>
(function () {
  /* ── ВОПРОСЫ: в p лежат очки типам проектов ── */
  var STEPS = [
    { q: 'Сколько этажей планируете?', h: 'От этажности зависит площадь фундамента и кровли, а это заметная часть сметы.',
      opts: [
        { t: 'Один этаж', d: 'вся жизнь на одном уровне, без лестницы', p: { dacha: 2, semi: 1, big: 0, wood: 1 } },
        { t: 'Мансардный', d: 'спальни под крышей, экономия на фундаменте', p: { dacha: 1, semi: 2, big: 1, wood: 1 } },
        { t: 'Два полных этажа', d: 'больше площади на том же пятне застройки', p: { dacha: 0, semi: 1, big: 2, wood: 0 } }
      ] },
    { q: 'Какая площадь нужна?', h: 'Считайте по числу спален плюс кухня-гостиная, котельная и санузлы.',
      opts: [
        { t: 'До 100 м²', d: 'две спальни, кухня-гостиная', p: { dacha: 2, semi: 1, big: 0, wood: 2 } },
        { t: 'От 100 до 150 м²', d: 'три спальни, кабинет, две ванные', p: { dacha: 1, semi: 2, big: 1, wood: 1 } },
        { t: 'Больше 150 м²', d: 'четыре спальни, гардеробные, гараж', p: { dacha: 0, semi: 1, big: 2, wood: 0 } }
      ] },
    { q: 'Из чего ставим стены?', h: 'Если ещё не решили, выберите последний вариант и мы сравним по вашему участку.',
      opts: [
        { t: 'Каркас', d: 'быстрая сборка, стройка круглый год', p: { dacha: 2, semi: 2, big: 0, wood: 0 } },
        { t: 'Газобетон', d: 'каменный дом, толстая стена, тишина', p: { dacha: 0, semi: 1, big: 2, wood: 0 } },
        { t: 'Брус', d: 'деревянные стены без внутренней отделки', p: { dacha: 1, semi: 0, big: 0, wood: 3 } },
        { t: 'Пока сравниваю', d: 'подберём материал под бюджет и участок', p: { dacha: 1, semi: 1, big: 1, wood: 1 } }
      ] },
    { q: 'На какую сумму рассчитываете?', h: 'Речь про дом с фундаментом, кровлей и окнами, без мебели и участка.',
      opts: [
        { t: 'До 4 млн ₽', d: 'компактный дом с базовой комплектацией', p: { dacha: 3, semi: 1, big: 0, wood: 1 } },
        { t: 'От 4 до 7 млн ₽', d: 'дом для круглогодичной жизни', p: { dacha: 1, semi: 3, big: 1, wood: 2 } },
        { t: 'Больше 7 млн ₽', d: 'просторный дом с инженерией и отделкой', p: { dacha: 0, semi: 1, big: 3, wood: 1 } }
      ] }
  ];

  /* ── ТИПЫ ПРОЕКТОВ ── */
  var PLANS = {
    dacha: { ttl: 'Компактный одноэтажный дом', href: '#proekty-odnoetazhnye',
      txt: 'Прямоугольная коробка без выступов, свайно-ростверковый фундамент, простая двускатная кровля. Такой дом дешевле в стройке и в отоплении, а строительная готовность наступает до конца сезона.',
      facts: [['от 3,4 до 4,6 млн ₽', 'цена под ключ'], ['3,5 месяца', 'срок стройки'], ['86 м²', 'типовая площадь']] },
    semi: { ttl: 'Полутораэтажный дом для семьи', href: '#proekty-mansardnye',
      txt: 'Спальни выносим под кровлю, первый этаж отдаём под кухню-гостиную и гостевую комнату. Фундамент и кровля почти те же, что у одноэтажного, а жилой площади получается в полтора раза больше.',
      facts: [['от 5,2 до 7,1 млн ₽', 'цена под ключ'], ['5 месяцев', 'срок стройки'], ['134 м²', 'типовая площадь']] },
    big: { ttl: 'Двухэтажный дом из газобетона', href: '#proekty-dvuhetazhnye',
      txt: 'Плитный фундамент, стена из блока 375 мм, перекрытие по монолиту. Дом держит тепло сутками и позволяет заложить гараж, котельную и второй санузел без потери жилой площади.',
      facts: [['от 8,4 до 11,9 млн ₽', 'цена под ключ'], ['8 месяцев', 'срок стройки'], ['186 м²', 'типовая площадь']] },
    wood: { ttl: 'Дом из профилированного бруса', href: '#proekty-brus',
      txt: 'Брус камерной сушки 195 мм, стены остаются готовыми изнутри и снаружи. Первый год дом даёт усадку до 2 см, поэтому чистовые работы начинаем через шесть месяцев после сборки коробки.',
      facts: [['от 4,1 до 6,3 млн ₽', 'цена под ключ'], ['6 месяцев', 'срок стройки'], ['108 м²', 'типовая площадь']] }
  };

  var roots = document.querySelectorAll('.vbkpd');
  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 = { dacha: 0, semi: 0, big: 0, wood: 0 }, trail = [];
    var stage = root.querySelector('#vbkpd-stage'), bar = root.querySelector('#vbkpd-bar');
    var back = root.querySelector('#vbkpd-back'), num = root.querySelector('#vbkpd-num');

    function marks(n) {
      var out = '';
      for (var m = 0; m < STEPS.length; m++) out += (m < n ? '<i class="vbkpd-bar--on"><\/i>' : '<i><\/i>');
      bar.innerHTML = out;
    }

    function reset() {
      idx = 0; score = { dacha: 0, semi: 0, big: 0, wood: 0 }; trail = []; drawStep();
    }

    function drawStep() {
      var s = STEPS[idx];
      marks(idx);
      num.textContent = 'Шаг ' + (idx + 1) + ' из ' + STEPS.length;
      back.hidden = idx === 0;
      var html = '<h3 class="vbkpd-q">' + s.q + '<\/h3><p class="vbkpd-hint">' + s.h + '<\/p><div class="vbkpd-opts">';
      for (var o = 0; o < s.opts.length; o++) {
        html += '<button type="button" class="vbkpd-opt" data-i="' + o + '"><b>' + s.opts[o].t + '<\/b><span>' + s.opts[o].d + '<\/span><\/button>';
      }
      stage.innerHTML = html + '<\/div>';
      var btns = stage.querySelectorAll('.vbkpd-opt');
      for (var b = 0; b < btns.length; b++) bind(btns[b], s);
    }

    function bind(btn, s) {
      btn.addEventListener('click', function () {
        var o = s.opts[parseInt(btn.getAttribute('data-i'), 10)];
        trail.push(o.p);
        for (var k in o.p) { if (o.p.hasOwnProperty(k)) score[k] += o.p[k]; }
        idx++;
        if (idx < STEPS.length) drawStep(); else drawResult();
      });
    }

    function drawResult() {
      marks(STEPS.length);
      num.textContent = 'Готово';
      back.hidden = false;
      var win = 'dacha', keys = ['dacha', 'semi', 'big', 'wood'];
      for (var k = 1; k < keys.length; k++) { if (score[keys[k]] > score[win]) win = keys[k]; }
      var p = PLANS[win], html = '<div class="vbkpd-res"><span class="vbkpd-res__tag">Подходящий проект<\/span>' +
        '<h3 class="vbkpd-res__ttl">' + p.ttl + '<\/h3><p class="vbkpd-res__txt">' + p.txt + '<\/p><div class="vbkpd-res__grid">';
      for (var f = 0; f < p.facts.length; f++) html += '<div><b>' + p.facts[f][0] + '<\/b><span>' + p.facts[f][1] + '<\/span><\/div>';
      html += '<\/div><div class="vbkpd-acts"><a class="vbkpd-cta" href="' + p.href + '">Смотреть планировки<\/a>' +
        '<button type="button" class="vbkpd-again">Пройти заново<\/button><\/div><\/div>';
      stage.innerHTML = html;
      var again = stage.querySelector('.vbkpd-again');
      if (again) again.addEventListener('click', reset);
    }

    back.addEventListener('click', function () {
      if (idx === 0) return;
      if (idx >= STEPS.length) idx = STEPS.length;
      idx--;
      var p = trail.pop();
      if (p) { for (var k in p) { if (p.hasOwnProperty(k)) score[k] -= p[k]; } }
      drawStep();
    });

    drawStep();
  }
})();
</script>

Вставляется целиком в блок T123 «HTML-код». Внутри уже есть стили и скрипт, подключать ничего не нужно.

Как вставить блок в Tilda

  1. Скопируйте кодКнопка «Скопировать код» выше кладёт всё содержимое в буфер обмена.
  2. Добавьте блок T123В редакторе страницы: «Библиотека блоков» → «Другое» → T123 «HTML-код».
  3. Вставьте и сохранитеНажмите «Контент», вставьте код в поле, сохраните и обновите страницу.
  4. ОпубликуйтеВ превью скрипты Tilda работают не всегда — проверяйте на опубликованной странице.

Подробная инструкция с граблями — как вставить вайб-блок в Tilda.

Что менять под себя

Где в кодеЗа что отвечает
массив STEPS в начале скриптавопросы, подсказки под ними и очки за каждый ответ
объект PLANSтипы проектов: описание, вилка цены, срок стройки, площадь
адреса href внутри PLANSкуда ведёт кнопка результата по каждому типу дома
--accцвет заполненного прогресса, рамок при наведении и кнопки результата

Квиз подбора проекта дома: зачем он нужен

Посетитель редко может сформулировать, какой дом ему нужен, зато легко отвечает на вопросы про этажи, площадь и бюджет. Квиз задаёт четыре таких вопроса и по сумме очков выбирает один из четырёх типовых проектов. В результате человек получает название проекта, вилку цены под ключ, срок стройки и площадь. Это снимает страх перед первым звонком в строительную компанию.

Каждый вопрос дополнен пояснением, зачем он задан: так шаг проходят до конца и меньше людей бросают квиз на середине. Прогресс показан четырьмя сегментами, кнопка возврата пересчитывает очки обратно, поэтому ответ можно изменить. Вопросы и проекты лежат в двух структурах в начале скрипта, добавить пятый шаг это дописать один объект.

Вопросы по этому блоку

  • Допишите объект в массив STEPS: поле q это текст вопроса, h подсказка под ним, opts список ответов. В каждом ответе укажите очки для ключей dacha, semi, big и wood. Прогресс пересчитается сам, сегменты строятся по длине массива.

  • Да. Ключи объекта PLANS должны совпадать с ключами очков в ответах. Если типов станет три или пять, поправьте начальное значение счётчика очков и список ключей в функции вывода результата.

  • Ответы остаются в браузере и наружу не уходят, блок работает без запросов к сторонним сервисам. Если нужна передача в заявку, поставьте после квиза блок с формой Tilda и подставьте название проекта в скрытое поле.

  • Да. Код на этой странице копируется целиком, без регистрации и подписки. Указывать авторство не нужно, использовать можно в коммерческих проектах.

  • Нет. Все классы внутри имеют собственный префикс vbkpd, поэтому не пересекаются ни со стилями Tilda, ни с другими блоками. Скрипт привязан к своему элементу и запускается один раз, даже если блок вставлен дважды.

  • Раскладка перестраивается под узкие экраны, размеры заданы через clamp, поля ввода имеют шрифт 16 пикселей — iOS не будет зумить страницу при фокусе. Отдельной мобильной версии подключать не нужно.

Другие квизы

Ещё блоки для строительства домов

Собрать сайт целиком, а не по блокам

Дровосеки делают сайты на Tilda под ключ: структура, тексты, дизайн, вёрстка и вайб-блоки под задачи бизнеса.