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

Квиз для подбора ремонта под бюджет

Четыре шага: тип объекта, площадь, желаемый уровень отделки, сроки. На выходе — вилка бюджета и форма, в которую уже подставлены ответы.

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

Код блока

<section class="vbkpr">
  <div class="vbkpr-wrap">
    <div class="vbkpr-side">
      <h2 class="vbkpr-h2">Соберём смету под ваш бюджет</h2>
      <p class="vbkpr-lead">Четыре вопроса — и вы увидите реальную вилку, а не «от 3 000 ₽ за метр». Займёт меньше минуты.</p>
      <ul class="vbkpr-facts">
        <li><b>218</b><span>объектов с 2019 года</span></li>
        <li><b>3 года</b><span>гарантии на работы</span></li>
      </ul>
    </div>

    <div class="vbkpr-box">
      <div class="vbkpr-top">
        <span class="vbkpr-step" id="vbkpr-step">Шаг 1 из 4</span>
        <div class="vbkpr-bar"><i id="vbkpr-fill" style="width:25%"></i></div>
      </div>

      <div class="vbkpr-stage" id="vbkpr-stage" aria-live="polite"></div>

      <div class="vbkpr-nav">
        <button type="button" class="vbkpr-back" id="vbkpr-back" hidden>Назад</button>
      </div>
    </div>
  </div>
</section>

<style>
.vbkpr, .vbkpr *, .vbkpr *::before, .vbkpr *::after { box-sizing: border-box; }
.vbkpr {
  --acc: #e8622a; --acc-dark: #cf5119; --ink: #1b1b1b; --muted: #6f6f6f; --line: #e6e3df; --bg: #f6f4f1;
  --f: var(--t-text-font, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif);
  --fh: var(--t-headline-font, var(--f));
  background: var(--bg); color: var(--ink); font-family: var(--f); padding: clamp(36px, 5vw, 80px) 20px;
}
.vbkpr-wrap { max-width: 1240px; margin: 0 auto; padding: 0 clamp(0px, 2vw, 40px);
  display: grid; grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); gap: clamp(24px, 4vw, 56px); align-items: center; }
.vbkpr-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 14px; }
.vbkpr-lead { font-size: 16px; line-height: 1.6; color: var(--muted); margin: 0 0 26px; }
.vbkpr-facts { list-style: none; margin: 0; padding: 0; display: flex; gap: 28px; }
.vbkpr-facts b { display: block; font-family: var(--fh); font-size: 26px; font-weight: 700; color: var(--acc); }
.vbkpr-facts span { font-size: 13px; color: var(--muted); }

.vbkpr-box { background: #fff; border: 1px solid var(--line); border-radius: 24px; padding: clamp(22px, 2.6vw, 34px); min-height: 420px; display: flex; flex-direction: column; }
.vbkpr-top { margin-bottom: 24px; }
.vbkpr-step { display: block; font-size: 13px; color: var(--muted); margin-bottom: 10px; }
.vbkpr-bar { height: 4px; border-radius: 4px; background: #eae6e1; overflow: hidden; }
.vbkpr-bar i { display: block; height: 100%; background: var(--acc); border-radius: 4px; transition: width .35s cubic-bezier(.22,1,.36,1); }
.vbkpr-stage { flex: 1; }
.vbkpr-q { font-family: var(--fh); font-size: clamp(19px, 2vw, 25px); line-height: 1.25; font-weight: 600; margin: 0 0 20px; }
.vbkpr-opts { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; }
.vbkpr-opt { 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: 14px; padding: 16px 18px; text-align: left; transition: .18s ease; }
.vbkpr-opt:hover { border-color: var(--acc); background: #fff8f4 !important; }
.vbkpr-opt b { display: block; font-size: 16px; font-weight: 600; }
.vbkpr-opt i { display: block; font-style: normal; font-size: 13px; color: var(--muted); margin-top: 4px; }
.vbkpr-nav { padding-top: 18px; }
.vbkpr-back { border: 0; margin: 0; -webkit-appearance: none; appearance: none; background: none !important; cursor: pointer;
  font: inherit; font-size: 14px; color: var(--muted) !important; text-decoration: underline; padding: 0; }
.vbkpr-back:hover { color: var(--acc) !important; }

.vbkpr-res__ttl { font-family: var(--fh); font-size: clamp(19px, 2vw, 25px); font-weight: 600; margin: 0 0 6px; }
.vbkpr-res__sum { font-family: var(--fh); font-size: clamp(28px, 3.2vw, 40px); line-height: 1.1; font-weight: 700; color: var(--acc); margin: 10px 0 6px; }
.vbkpr-res__sub { font-size: 14px; color: var(--muted); margin: 0 0 18px; }
.vbkpr-res__list { list-style: none; margin: 0 0 22px; padding: 16px 0 0; border-top: 1px solid var(--line); display: grid; gap: 8px; }
.vbkpr-res__list li { display: flex; justify-content: space-between; gap: 14px; font-size: 14px; color: var(--muted); }
.vbkpr-res__list b { color: var(--ink); font-weight: 600; text-align: right; }
.vbkpr-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 8px; }
.vbkpr-inp { width: 100%; height: 52px; padding: 0 16px; font: inherit; font-size: 16px; -webkit-appearance: none; appearance: none;
  border: 1px solid var(--line); border-radius: 10px; background: #fff; color: var(--ink); }
.vbkpr-inp:focus { outline: 2px solid var(--acc); outline-offset: -2px; }
.vbkpr-consent { display: flex; align-items: flex-start; gap: 9px; margin: 12px 0 14px; cursor: pointer; font-size: 12px; line-height: 1.45; color: var(--muted); }
.vbkpr-consent input { position: absolute; opacity: 0; width: 0; height: 0; }
.vbkpr-consent__box { flex: 0 0 18px; width: 18px; height: 18px; margin-top: 1px; border: 1.5px solid #c9c5c0; border-radius: 5px; background: #fff; position: relative; }
.vbkpr-consent input:checked + .vbkpr-consent__box { background: var(--acc); border-color: var(--acc); }
.vbkpr-consent input:checked + .vbkpr-consent__box::after { content: ''; position: absolute; left: 5px; top: 1px; width: 5px; height: 10px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.vbkpr-consent a, .vbkpr-consent a:link, .vbkpr-consent a:visited, .vbkpr-consent a:hover, .vbkpr-consent a:active, .vbkpr-consent a:focus { color: var(--ink) !important; text-decoration: underline !important; }
.vbkpr-submit { width: 100%; min-height: 54px; border: 0; margin: 0; -webkit-appearance: none; appearance: none; font: inherit; font-size: 16px;
  font-weight: 600; cursor: pointer; border-radius: 10px; background: var(--acc) !important; color: #fff !important; transition: background .2s ease; }
.vbkpr-submit:hover { background: var(--acc-dark) !important; }
.vbkpr-done { text-align: center; padding: 40px 10px; }
.vbkpr-done b { display: block; font-family: var(--fh); font-size: 21px; margin-bottom: 8px; }
.vbkpr-done span { font-size: 14px; color: var(--muted); }

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

<script>
(function () {
  /* ── ВОПРОСЫ КВИЗА: k — коэффициент к базовой цене, add — разовая надбавка ── */
  var STEPS = [
    { q: 'Что ремонтируем?', name: 'Объект', opts: [
      { t: 'Квартира',        s: 'вторичка или новостройка', k: 1 },
      { t: 'Дом или таунхаус', s: 'частный сектор',           k: 1.15 },
      { t: 'Офис',            s: 'коммерческое помещение',   k: 1.1 }
    ]},
    { q: 'Какая площадь?', name: 'Площадь', opts: [
      { t: 'До 40 м²',   s: 'студия, однушка', area: 35 },
      { t: '40–70 м²',   s: 'двушка',          area: 55 },
      { t: '70–110 м²',  s: 'трёшка',          area: 90 },
      { t: 'Больше 110 м²', s: 'просторное жильё', area: 140 }
    ]},
    { q: 'Какой уровень отделки нужен?', name: 'Уровень', opts: [
      { t: 'Освежить',    s: 'обои, покраска, полы',        rate: 8500 },
      { t: 'Капитально',  s: 'всё под замену, без переносов', rate: 15000 },
      { t: 'С дизайном',  s: 'проект, перепланировка',       rate: 24000 }
    ]},
    { q: 'Когда планируете начать?', name: 'Сроки', opts: [
      { t: 'В этом месяце', s: 'работаем в две смены', k: 1.18 },
      { t: 'Через 1–3 месяца', s: 'обычный график',    k: 1 },
      { t: 'Пока просто считаю', s: 'без сроков',      k: 0.97 }
    ]}
  ];

  var roots = document.querySelectorAll('.vbkpr');
  for (var i = 0; i < roots.length; i++) init(roots[i]);

  function init(root) {
    if (root.__vb) return; root.__vb = 1;
    var idx = 0, answers = [];
    var stage = root.querySelector('#vbkpr-stage'), fill = root.querySelector('#vbkpr-fill');
    var label = root.querySelector('#vbkpr-step'), back = root.querySelector('#vbkpr-back');

    function fmt(n) { return String(Math.round(n / 1000) * 1000).replace(/\B(?=(\d{3})+(?!\d))/g, ' '); }

    function calcResult() {
      var area = 55, rate = 15000, k = 1;
      answers.forEach(function (a) {
        if (a.area) area = a.area;
        if (a.rate) rate = a.rate;
        if (a.k) k *= a.k;
      });
      var base = area * rate * k;
      return { area: area, min: base, max: base * 1.28 };
    }

    function drawStep() {
      var s = STEPS[idx];
      label.textContent = 'Шаг ' + (idx + 1) + ' из ' + STEPS.length;
      fill.style.width = ((idx + 1) / (STEPS.length + 1) * 100) + '%';
      back.hidden = idx === 0;
      var html = '<h3 class="vbkpr-q">' + s.q + '<\/h3><div class="vbkpr-opts">';
      s.opts.forEach(function (o, i) {
        html += '<button type="button" class="vbkpr-opt" data-i="' + i + '"><b>' + o.t + '<\/b><i>' + o.s + '<\/i><\/button>';
      });
      stage.innerHTML = html + '<\/div>';
      stage.querySelectorAll('.vbkpr-opt').forEach(function (b) {
        b.addEventListener('click', function () {
          var o = s.opts[+b.dataset.i];
          answers[idx] = { name: s.name, value: o.t, area: o.area, rate: o.rate, k: o.k };
          idx++;
          if (idx < STEPS.length) drawStep(); else drawResult();
        });
      });
    }

    function drawResult() {
      var r = calcResult();
      label.textContent = 'Готово';
      fill.style.width = '100%';
      back.hidden = false;
      var summary = answers.map(function (a) {
        return '<li><span>' + a.name + '<\/span><b>' + a.value + '<\/b><\/li>';
      }).join('');
      stage.innerHTML =
        '<div class="vbkpr-res"><p class="vbkpr-res__ttl">Ориентировочный бюджет<\/p>' +
        '<p class="vbkpr-res__sum">' + fmt(r.min) + ' — ' + fmt(r.max) + ' ₽<\/p>' +
        '<p class="vbkpr-res__sub">Работы под ключ на ' + r.area + ' м². Материалы считаются отдельно по спецификации.<\/p>' +
        '<ul class="vbkpr-res__list">' + summary + '<\/ul>' +
        '<form class="vbkpr-form t-form js-form-proccess" role="form" action="#" method="POST" ' +
        'data-vibeblock-form="true" data-formactiontype="2" data-error-popup="y" data-success-popup="y" ' +
        'data-success-callback="vbkprSuccess" data-inputbox=".vbkpr-inp, .vbkpr-consent-inp" novalidate>' +
        '<input type="hidden" name="formservices[]" value="HASH_EMAIL" class="js-formaction-services">' +
        '<input type="hidden" name="form_source" value="Квиз — подбор ремонта">' +
        '<input type="hidden" name="Otvety" value="' + answers.map(function (a) { return a.name + ': ' + a.value; }).join('; ') +
        '; Бюджет: ' + fmt(r.min) + '-' + fmt(r.max) + ' ₽">' +
        '<div class="vbkpr-fields">' +
        '<input type="text" name="Name" class="vbkpr-inp js-tilda-rule" data-tilda-req="1" data-tilda-rule="name" placeholder="Как вас зовут">' +
        '<input type="tel" name="Phone" class="vbkpr-inp js-tilda-rule js-tilda-mask" data-tilda-req="1" data-tilda-rule="phone" ' +
        'data-tilda-mask="+7 (999) 999-99-99" inputmode="tel" placeholder="+7 (___) ___-__-__">' +
        '<\/div>' +
        '<label class="vbkpr-consent"><input type="checkbox" name="Privacy" value="Da" class="vbkpr-consent-inp js-tilda-rule" data-tilda-req="1">' +
        '<span class="vbkpr-consent__box"><\/span><span>Согласен с <a href="/policy" target="_blank" rel="noopener">политикой конфиденциальности<\/a><\/span><\/label>' +
        '<button type="submit" class="vbkpr-submit t-submit">Получить точный расчёт<\/button><\/form><\/div>';
      bindForm();
    }

    function bindForm() {
      var form = root.querySelector('.vbkpr-form');
      if (!form || form.__b) return;
      form.__b = 1;
      form.addEventListener('submit', function (e) {
        e.preventDefault();
        var btn = form.querySelector('button[type="submit"], .t-submit');
        if (btn && typeof window.t_forms__initBtnClick === 'function') {
          try { window.t_forms__initBtnClick({ target: btn, srcElement: btn, preventDefault: function () {} }); } catch (_) {}
        }
      });
    }

    back.addEventListener('click', function () {
      if (idx > 0) { idx--; drawStep(); }
    });

    if (!window.vbkprSuccess) {
      window.vbkprSuccess = function (f) {
        try { f.innerHTML = '<div class="vbkpr-done"><b>Расчёт у нас<\/b><span>Сметчик соберёт точную смету и перезвонит в течение рабочего дня.<\/span><\/div>'; } catch (e) {}
      };
    }

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

Вставляется целиком в блок T123 «HTML-код». Внутри уже есть стили и скрипт, подключать ничего не нужно. В форме замените HASH_EMAIL на хеш приёмника из Tilda → Site Settings → Forms.

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

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

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

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

Где в кодеЗа что отвечает
массив STEPS в скриптевопросы, варианты ответов и их вес в расчёте
функция calcResultформула итоговой вилки бюджета
--accцвет прогресс-бара и выбранных вариантов
formservices[]приёмники заявок из настроек Tilda

Квиз «Подбор ремонта под бюджет»: зачем он нужен

Квиз выигрывает у формы «оставьте телефон», потому что человек сначала вкладывается в ответы, а телефон оставляет уже на инерции. Здесь на это работают прогресс-бар и возможность вернуться на шаг назад — ощущение контроля снижает отказы.

Результат считается по ответам и показывается до формы: посетитель видит вилку и понимает, за чем оставляет контакт. Все ответы уходят вместе с заявкой отдельной строкой, менеджеру не приходится переспрашивать.

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

  • Допишите объект в массив STEPS: заголовок вопроса и массив вариантов. Прогресс-бар и навигация пересчитаются автоматически, разметку трогать не нужно.

  • Да, все выбранные варианты складываются в скрытое поле формы и приходят в заявке вместе с именем и телефоном.

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

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

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

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

Другие квизы

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

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

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