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

Квиз «Какой сайт вам нужен» для сайта студии

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

  • ТипКвиз
  • НишаIT и digital
  • Вес кода13.6 КБ
  • Заголовок H1нет, только H2
  • Форма Tildaнет
  • Интерактив
Живое демо — блок работает прямо здесь

Код блока

<section class="vbksn">
  <div class="vbksn-wrap">
    <div class="vbksn-head">
      <h2 class="vbksn-h2">Какой сайт нужен под вашу задачу</h2>
      <p class="vbksn-lead">Четыре вопроса про задачу, материалы и сроки. В конце покажем тип сайта, вилку срока и состав работ.</p>
    </div>

    <div class="vbksn-box">
      <div class="vbksn-bar" id="vbksn-bar" aria-hidden="true"></div>
      <div class="vbksn-stage" id="vbksn-stage" aria-live="polite"></div>
      <div class="vbksn-foot">
        <button type="button" class="vbksn-back" id="vbksn-back" hidden>К прошлому вопросу</button>
        <span class="vbksn-num" id="vbksn-num"></span>
      </div>
    </div>
  </div>
</section>

<style>
.vbksn, .vbksn *, .vbksn *::before, .vbksn *::after { box-sizing: border-box; }
.vbksn {
  --acc: #6ee787; --bg: #0f1116; --panel: #171a21; --ink: #e9edf2; --muted: #8b95a5; --line: #262b34;
  --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, 84px) 20px;
}
.vbksn-wrap { max-width: 900px; margin: 0 auto; padding: 0 clamp(0px, 2vw, 40px); }
.vbksn-head { margin-bottom: clamp(20px, 2.6vw, 30px); max-width: 42em; }
.vbksn-h2 { font-family: var(--fh); font-size: clamp(25px, 3.2vw, 38px); line-height: 1.14; font-weight: 700; letter-spacing: -.02em; margin: 0 0 12px; }
.vbksn-lead { font-size: 16px; line-height: 1.65; color: var(--muted); margin: 0; }

.vbksn-box { background: var(--panel); border: 1px solid var(--line); border-radius: 22px; padding: clamp(22px, 3vw, 40px); }
.vbksn-bar { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 6px; margin-bottom: clamp(22px, 2.6vw, 30px); }
.vbksn-bar i { display: block; height: 4px; border-radius: 4px; background: var(--line); transition: background .3s ease; }
.vbksn-bar i.is-done { background: var(--acc); }
.vbksn-bar i.is-now { background: rgba(110, 231, 135, .45); }

.vbksn-q { font-family: var(--fh); font-size: clamp(19px, 2.1vw, 25px); line-height: 1.28; font-weight: 700; letter-spacing: -.01em; margin: 0 0 18px; }
.vbksn-opts { display: grid; gap: 10px; }
.vbksn-opt { display: flex; align-items: flex-start; gap: 14px; width: 100%; text-align: left; border: 1px solid var(--line); margin: 0;
  -webkit-appearance: none; appearance: none; font: inherit; cursor: pointer;
  background: #12151a !important; color: var(--ink) !important; border-radius: 14px; padding: 16px 18px; transition: .18s ease; }
.vbksn-opt:hover { border-color: var(--acc); background: #141a17 !important; }
.vbksn-dot { flex: 0 0 18px; width: 18px; height: 18px; margin-top: 2px; border-radius: 50%; border: 2px solid #39404b; transition: .18s ease; }
.vbksn-opt:hover .vbksn-dot { border-color: var(--acc); box-shadow: inset 0 0 0 4px var(--acc); }
.vbksn-opt b { display: block; font-size: 15.5px; font-weight: 600; line-height: 1.4; }
.vbksn-opt span span { display: block; font-size: 13px; line-height: 1.5; color: var(--muted); margin-top: 4px; }

.vbksn-foot { display: flex; align-items: center; gap: 16px; margin-top: 22px; }
.vbksn-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; }
.vbksn-back:hover { color: var(--acc) !important; }
.vbksn-num { margin-left: auto; font-size: 13px; color: var(--muted); white-space: nowrap; }

.vbksn-tag { display: inline-block; font-size: 11.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--acc); border: 1px solid rgba(110, 231, 135, .35); border-radius: 999px; padding: 6px 13px; margin-bottom: 14px; }
.vbksn-ttl { font-family: var(--fh); font-size: clamp(23px, 2.8vw, 32px); line-height: 1.15; font-weight: 700; letter-spacing: -.02em; margin: 0 0 12px; }
.vbksn-txt { font-size: 16px; line-height: 1.65; color: var(--muted); margin: 0 0 20px; }
.vbksn-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; margin-bottom: 20px; }
.vbksn-facts div { background: #12151a; border: 1px solid var(--line); border-radius: 14px; padding: 15px 16px; }
.vbksn-facts b { display: block; font-family: var(--fh); font-size: 18px; font-weight: 700; line-height: 1.2; }
.vbksn-facts span { display: block; font-size: 12px; color: var(--muted); margin-top: 5px; }
.vbksn-hint { font-size: 13.5px; line-height: 1.55; background: rgba(110, 231, 135, .08); border-left: 2px solid var(--acc);
  border-radius: 0 10px 10px 0; padding: 12px 15px; margin: 0 0 20px; }
.vbksn-acts { display: flex; flex-wrap: wrap; gap: 10px; }
.vbksn-cta, .vbksn-cta:link, .vbksn-cta:visited, .vbksn-cta:active, .vbksn-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: #0f1116 !important; text-decoration: none !important; transition: .18s ease; }
.vbksn-cta:hover { background: #8bf0a1; color: #0f1116 !important; }
.vbksn-again { min-height: 54px; padding: 0 24px; border: 1px solid var(--line); margin: 0; -webkit-appearance: none; appearance: none;
  font: inherit; font-size: 16px; cursor: pointer; border-radius: 12px; background: none !important; color: var(--ink) !important; transition: .18s ease; }
.vbksn-again:hover { border-color: var(--acc); color: var(--acc) !important; }

@media (prefers-reduced-motion: reduce) { .vbksn * { transition: none !important; } }
</style>

<script>
(function () {
  var CTA_HREF = '#obsudit-proekt';

  /* ── ШАГИ КВИЗА: p задаёт очки типам сайта, note добавляет строку в результат ── */
  var STEPS = [
    { q: 'Что сайт должен делать для бизнеса?', opts: [
      { t: 'Продавать одну услугу', s: 'Реклама ведёт на страницу с заявкой', p: { land: 3 } },
      { t: 'Показывать компанию целиком', s: 'Услуги, цены, проекты, контакты', p: { multi: 3 } },
      { t: 'Продавать товары', s: 'Витрина, корзина, оплата', p: { cat: 3 } },
      { t: 'Заменить ручную работу', s: 'Расчёты и статусы внутри кабинета', p: { serv: 3 } }
    ]},
    { q: 'Что уже готово из материалов?', opts: [
      { t: 'Тексты и фотографии на руках', s: 'Верстаем сразу после макета', p: { land: 1, multi: 1 },
        note: 'Материалы готовы, срок идёт по нижней границе вилки.' },
      { t: 'Старый сайт и черновики', s: 'Часть переносим, часть пишем', p: { multi: 2 },
        note: 'Перенос со старого сайта считаем отдельным этапом.' },
      { t: 'Пока только идея', s: 'Тексты и съёмка нужны с нуля', p: { land: 1, serv: 1 },
        note: 'Тексты и съёмку добавляем в план, плюс две недели.' }
    ]},
    { q: 'Нужен ли каталог и какой он?', opts: [
      { t: 'Каталог не нужен', s: 'Одна услуга и понятная цена', p: { land: 3 } },
      { t: 'Список услуг', s: 'От 10 до 20 позиций с описанием', p: { multi: 2 } },
      { t: 'Каталог с фильтрами', s: 'Сотни позиций, поиск, корзина', p: { cat: 3 } },
      { t: 'Каталог с кабинетом', s: 'Цена зависит от клиента, нужен вход', p: { serv: 3, cat: 1 } }
    ]},
    { q: 'К какому сроку сайт должен работать?', opts: [
      { t: 'Через две недели', s: 'Реклама оплачена и ждёт', p: { land: 2 },
        note: 'Срок сжатый: первой запускаем главную, остальное дособираем.' },
      { t: 'Через полтора месяца', s: 'Есть время на согласование', p: { multi: 1 } },
      { t: 'Срок гибкий', s: 'Важнее собрать всё как надо', p: { serv: 1, cat: 1 },
        note: 'Свободный срок даёт проверять каждый этап на живых людях.' }
    ]}
  ];

  /* ── ТИПЫ САЙТОВ ── */
  var KINDS = {
    land: { ttl: 'Одностраничный сайт',
      txt: 'Одна страница, один продукт, одно целевое действие. Запускается быстро и хорошо держит платную рекламу: путь посетителя виден за пару прокруток.',
      facts: [['2-3 недели', 'срок работы'], ['1 страница', 'объём'], ['от 90 000 ₽', 'бюджет']] },
    multi: { ttl: 'Многостраничный сайт',
      txt: 'Раздел под каждую услугу, страницы о компании и проектах, общая навигация. Такой сайт собирает поиск и отвечает на вопросы до звонка.',
      facts: [['4-6 недель', 'срок работы'], ['6-12 страниц', 'объём'], ['от 180 000 ₽', 'бюджет']] },
    cat: { ttl: 'Каталог с корзиной',
      txt: 'Витрина с фильтрами, карточка товара, корзина и оплата. Основная работа тут в структуре данных: свойства, остатки, цены и обмен с учётной системой.',
      facts: [['8-12 недель', 'срок работы'], ['от 200 позиций', 'объём'], ['от 420 000 ₽', 'бюджет']] },
    serv: { ttl: 'Сервис с личным кабинетом',
      txt: 'Вход по паролю, расчёты внутри и своя панель управления. Идём этапами: сначала запускаем то, что закрывает главную боль, дальше добавляем разделы.',
      facts: [['от 3 месяцев', 'срок работы'], ['кабинет и панель', 'объём'], ['от 650 000 ₽', 'бюджет']] }
  };

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

  function init(root) {
    if (root.__vb) return; root.__vb = 1;
    var stage = root.querySelector('#vbksn-stage'), bar = root.querySelector('#vbksn-bar');
    var back = root.querySelector('#vbksn-back'), num = root.querySelector('#vbksn-num');
    var idx = 0, score, trail;

    bar.innerHTML = new Array(STEPS.length + 1).join('<i><\/i>');
    var segs = bar.querySelectorAll('i');

    function reset() { idx = 0; score = { land: 0, multi: 0, cat: 0, serv: 0 }; trail = []; }

    function marks(done) {
      for (var i = 0; i < segs.length; i++) segs[i].className = i < done ? 'is-done' : (i === done ? 'is-now' : '');
    }

    function drawStep() {
      var s = STEPS[idx];
      marks(idx);
      num.textContent = 'Вопрос ' + (idx + 1) + ' из ' + STEPS.length;
      back.hidden = idx === 0;
      stage.innerHTML = '<h3 class="vbksn-q">' + s.q + '<\/h3><div class="vbksn-opts">' +
        s.opts.map(function (o, i) {
          return '<button type="button" class="vbksn-opt" data-i="' + i + '"><span class="vbksn-dot"><\/span>' +
            '<span><b>' + o.t + '<\/b><span>' + o.s + '<\/span><\/span><\/button>';
        }).join('') + '<\/div>';

      var btns = stage.querySelectorAll('.vbksn-opt');
      for (var i = 0; i < btns.length; i++) {
        btns[i].addEventListener('click', function () {
          var o = s.opts[+this.getAttribute('data-i')], k;
          trail.push(o);
          for (k in o.p) { if (score.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 = 'land', k;
      for (k in score) { if (score[k] > score[win]) win = k; }
      var d = KINDS[win], notes = [];
      for (var i = 0; i < trail.length; i++) if (trail[i].note) notes.push(trail[i].note);

      stage.innerHTML = '<span class="vbksn-tag">Вам подходит<\/span>' +
        '<h3 class="vbksn-ttl">' + d.ttl + '<\/h3><p class="vbksn-txt">' + d.txt + '<\/p>' +
        '<div class="vbksn-facts">' + d.facts.map(function (f) {
          return '<div><b>' + f[0] + '<\/b><span>' + f[1] + '<\/span><\/div>';
        }).join('') + '<\/div>' +
        (notes.length ? '<p class="vbksn-hint">' + notes.join(' ') + '<\/p>' : '') +
        '<div class="vbksn-acts"><a class="vbksn-cta" href="' + CTA_HREF + '">Обсудить проект<\/a>' +
        '<button type="button" class="vbksn-again">Пройти заново<\/button><\/div>';

      var again = stage.querySelector('.vbksn-again');
      if (again) again.addEventListener('click', function () { reset(); drawStep(); });
    }

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

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

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

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

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

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

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

Где в кодеЗа что отвечает
массив STEPS в начале скриптавопросы, варианты ответа и очки типам сайта
поле note у вариантаподсказка, которая попадёт в строку под цифрами
объект KINDSназвания типов сайта, описания и вилки срока и бюджета
переменная CTA_HREFкуда ведёт кнопка «Обсудить проект»
--acc в стиляхцвет полосы шагов, точек в вариантах и кнопки

Квиз «Какой сайт нужен»: зачем он нужен

Человек редко приходит в студию со словами «мне нужен многостраничный сайт», он приходит с задачей бизнеса. Квиз переводит задачу в тип проекта и сразу показывает порядок цифр, чтобы разговор начинался с общего понимания бюджета. По дороге он собирает то, что менеджер всё равно спросит на первом созвоне: есть ли материалы, нужен ли каталог, к какому сроку нужен запуск. Итог читается как ответ специалиста, без рекламного напора.

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

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

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

  • Да, допишите объекты в массив STEPS. Полоса шагов рисуется по длине массива, счётчик «Вопрос 1 из 4» тоже пересчитывается автоматически.

  • Форма Tilda на странице обычно уже есть, и вторая с ней конфликтует. Кнопка результата ведёт ссылкой: поставьте в CTA_HREF якорь своей формы или адрес страницы с брифом.

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

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

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

Другие квизы

Ещё блоки для IT и digital-услуг

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

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