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

Калькулятор стоимости сайта для Tilda

Тип сайта, количество страниц, набор работ и срочность. На выходе — вилка бюджета и срок в неделях, а не одна цифра «от».

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

Код блока

<section class="vbkss">
  <div class="vbkss-wrap">
    <div class="vbkss-head">
      <h2 class="vbkss-h2">Калькулятор стоимости сайта</h2>
      <p class="vbkss-lead">Соберите конфигурацию — увидите вилку бюджета и срок. Каждая галочка двигает и деньги, и сроки, так что видно, за что вы платите.</p>
    </div>

    <div class="vbkss-grid">
      <div class="vbkss-panel">
        <div class="vbkss-ctl">
          <span class="vbkss-ctl__lbl">Что делаем</span>
          <div class="vbkss-types" id="vbkss-types" role="radiogroup" aria-label="Тип сайта"></div>
        </div>

        <div class="vbkss-ctl">
          <div class="vbkss-ctl__top"><span>Уникальных шаблонов страниц</span><b id="vbkss-pages">6</b></div>
          <input type="range" id="vbkss-range" min="1" max="30" step="1" value="6" aria-label="Количество уникальных шаблонов страниц">
        </div>

        <div class="vbkss-ctl">
          <span class="vbkss-ctl__lbl">Что ещё нужно</span>
          <div class="vbkss-opts" id="vbkss-opts"></div>
        </div>

        <label class="vbkss-rush">
          <input type="checkbox" id="vbkss-rushinp">
          <span class="vbkss-rush__box"></span>
          <span>Нужно срочно — команда работает параллельно<i>цена +30%, срок −35%</i></span>
        </label>
      </div>

      <aside class="vbkss-out">
        <span class="vbkss-out__lbl">Бюджет проекта</span>
        <strong class="vbkss-out__sum" id="vbkss-sum"></strong>
        <div class="vbkss-term"><span>Срок</span><b id="vbkss-term"></b></div>
        <ul class="vbkss-rows" id="vbkss-rows"></ul>

        <form class="vbkss-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="vbkssSuccess" data-inputbox=".vbkss-inp, .vbkss-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="Konfiguratsiya" id="vbkss-hidden" value="">
          <input type="tel" name="Phone" class="vbkss-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 (___) ___-__-__">
          <label class="vbkss-consent">
            <input type="checkbox" name="Privacy" value="Da" class="vbkss-consent-inp js-tilda-rule" data-tilda-req="1">
            <span class="vbkss-consent__box"></span>
            <span>Согласен с <a href="/policy" target="_blank" rel="noopener">политикой конфиденциальности</a></span>
          </label>
          <button type="submit" class="vbkss-submit t-submit">Прислать расчёт</button>
        </form>
        <p class="vbkss-note">Вилка предварительная. Точная смета считается после брифа и фиксируется договором.</p>
      </aside>
    </div>
  </div>
</section>

<style>
.vbkss, .vbkss *, .vbkss *::before, .vbkss *::after { box-sizing: border-box; }
.vbkss {
  --acc: #6ee787; --acc-dark: #52cf6c; --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;
}
.vbkss-wrap { max-width: 1240px; margin: 0 auto; padding: 0 clamp(0px, 2vw, 40px); }
.vbkss-head { max-width: 44em; margin-bottom: clamp(24px, 3vw, 40px); }
.vbkss-h2 { font-family: var(--fh); font-size: clamp(26px, 3.4vw, 42px); line-height: 1.1; font-weight: 700; letter-spacing: -.025em; margin: 0 0 12px; }
.vbkss-lead { font-size: 16px; line-height: 1.6; color: var(--muted); margin: 0; }

.vbkss-grid { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, .8fr); gap: 18px; align-items: start; }
.vbkss-panel { background: var(--panel); border: 1px solid var(--line); border-radius: 22px; padding: clamp(20px, 2.6vw, 32px); }
.vbkss-ctl { margin-bottom: 26px; }
.vbkss-ctl__top { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 12px; font-size: 15px; color: var(--muted); }
.vbkss-ctl__top b { font-family: var(--fh); font-size: 21px; color: var(--ink); }
.vbkss-ctl__lbl { display: block; font-size: 15px; color: var(--muted); margin-bottom: 12px; }
.vbkss input[type=range] { -webkit-appearance: none; appearance: none; width: 100%; height: 4px; border-radius: 4px; background: #2f3540; outline: none; }
.vbkss input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 24px; height: 24px; border-radius: 50%;
  background: var(--acc); border: 4px solid var(--panel); box-shadow: 0 1px 6px rgba(0,0,0,.5); cursor: pointer; }
.vbkss input[type=range]::-moz-range-thumb { width: 18px; height: 18px; border-radius: 50%; background: var(--acc); border: 3px solid var(--panel); cursor: pointer; }

.vbkss-types { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 8px; }
.vbkss-types button { border: 1.5px solid var(--line); margin: 0; -webkit-appearance: none; appearance: none; font: inherit; cursor: pointer;
  background: transparent !important; color: var(--ink) !important; border-radius: 12px; padding: 13px 14px; text-align: left; transition: .18s ease; }
.vbkss-types button b { display: block; font-size: 15px; font-weight: 600; }
.vbkss-types button i { display: block; font-style: normal; font-size: 12.5px; color: var(--muted); margin-top: 3px; }
.vbkss-types button:hover { border-color: #3a424f; }
.vbkss-types button[aria-checked="true"] { border-color: var(--acc); background: rgba(110,231,135,.07) !important; }

.vbkss-opts { display: grid; gap: 8px; }
.vbkss-chk { display: flex; align-items: center; gap: 11px; border: 1.5px solid var(--line); border-radius: 12px; padding: 12px 14px;
  cursor: pointer; font-size: 14.5px; transition: border-color .18s ease; }
.vbkss-chk:hover { border-color: #3a424f; }
.vbkss-chk input { position: absolute; opacity: 0; width: 0; height: 0; }
.vbkss-chk__box, .vbkss-rush__box, .vbkss-consent__box { flex: 0 0 18px; width: 18px; height: 18px; border: 1.5px solid #3a424f; border-radius: 5px; position: relative; }
.vbkss-chk input:checked + .vbkss-chk__box, .vbkss-rush input:checked + .vbkss-rush__box,
.vbkss-consent input:checked + .vbkss-consent__box { background: var(--acc); border-color: var(--acc); }
.vbkss-chk input:checked + .vbkss-chk__box::after, .vbkss-rush input:checked + .vbkss-rush__box::after,
.vbkss-consent input:checked + .vbkss-consent__box::after { content: ''; position: absolute; left: 5px; top: 1px; width: 5px; height: 10px;
  border: solid #0f1116; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.vbkss-chk__p { margin-left: auto; font-size: 13px; color: var(--muted); white-space: nowrap; }
.vbkss-rush { display: flex; align-items: flex-start; gap: 11px; cursor: pointer; font-size: 14.5px; }
.vbkss-rush input { position: absolute; opacity: 0; width: 0; height: 0; }
.vbkss-rush__box { margin-top: 2px; }
.vbkss-rush i { display: block; font-style: normal; font-size: 12.5px; color: var(--acc); margin-top: 3px; }

.vbkss-out { background: var(--panel); border: 1px solid var(--line); border-radius: 22px; padding: clamp(20px, 2.6vw, 30px); position: sticky; top: 20px; }
.vbkss-out__lbl { display: block; font-size: 13px; color: var(--muted); }
.vbkss-out__sum { display: block; font-family: var(--fh); font-size: clamp(24px, 2.6vw, 30px); line-height: 1.15; font-weight: 700; color: var(--acc); margin: 6px 0 14px; }
.vbkss-term { display: flex; justify-content: space-between; align-items: baseline; padding: 12px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); font-size: 14px; color: var(--muted); }
.vbkss-term b { font-family: var(--fh); font-size: 17px; color: var(--ink); }
.vbkss-rows { list-style: none; margin: 16px 0 20px; padding: 0; display: grid; gap: 9px; }
.vbkss-rows li { display: flex; justify-content: space-between; gap: 12px; font-size: 13.5px; color: var(--muted); }
.vbkss-rows b { color: var(--ink); font-weight: 600; white-space: nowrap; }
.vbkss-inp { width: 100%; height: 50px; padding: 0 16px; font: inherit; font-size: 16px; -webkit-appearance: none; appearance: none;
  border: 1px solid var(--line); border-radius: 10px; background: rgba(255,255,255,.04); color: var(--ink); }
.vbkss-inp::placeholder { color: #6c7684; }
.vbkss-inp:focus { outline: 2px solid var(--acc); outline-offset: -2px; }
.vbkss-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); }
.vbkss-consent input { position: absolute; opacity: 0; width: 0; height: 0; }
.vbkss-consent__box { margin-top: 1px; }
.vbkss-consent a, .vbkss-consent a:link, .vbkss-consent a:visited, .vbkss-consent a:hover, .vbkss-consent a:active, .vbkss-consent a:focus { color: var(--ink) !important; text-decoration: underline !important; }
.vbkss-submit { width: 100%; min-height: 52px; border: 0; margin: 0; -webkit-appearance: none; appearance: none; font: inherit; font-size: 15.5px;
  font-weight: 600; cursor: pointer; border-radius: 10px; background: var(--acc) !important; color: #0f1116 !important; transition: background .2s ease; }
.vbkss-submit:hover { background: var(--acc-dark) !important; }
.vbkss-note { margin: 14px 0 0; font-size: 11.5px; line-height: 1.5; color: #6c7684; }
.vbkss-done { text-align: center; padding: 20px 4px; }
.vbkss-done b { display: block; font-size: 17px; margin-bottom: 6px; }
.vbkss-done span { font-size: 13px; color: var(--muted); }

@media (max-width: 900px) { .vbkss-grid { grid-template-columns: minmax(0, 1fr); } .vbkss-out { position: static; } }
@media (prefers-reduced-motion: reduce) { .vbkss * { transition: none !important; } }
</style>

<script>
(function () {
  /* ── ТИПЫ САЙТОВ: base — база, perPage — за шаблон, weeks — база недель ── */
  var TYPES = [
    { id: 'land', name: 'Лендинг',      hint: 'одна услуга',      base: 120000, perPage: 22000, weeks: 2 },
    { id: 'corp', name: 'Корпоративный', hint: 'услуги и блог',    base: 260000, perPage: 26000, weeks: 5 },
    { id: 'shop', name: 'Магазин',       hint: 'каталог и оплата', base: 420000, perPage: 30000, weeks: 8 },
    { id: 'app',  name: 'Веб-сервис',    hint: 'кабинеты, логика', base: 680000, perPage: 38000, weeks: 12 }
  ];
  /* ── ДОП-РАБОТЫ: price — рубли, weeks — недель к сроку ── */
  var OPTIONS = [
    { id: 'design', name: 'Уникальный дизайн вместо шаблона', price: 140000, weeks: 2 },
    { id: 'crm',    name: 'Интеграция с CRM и телефонией',     price: 68000,  weeks: 1 },
    { id: 'seo',    name: 'Техническое SEO и скорость',        price: 54000,  weeks: 1 },
    { id: 'text',   name: 'Тексты и фотосъёмка',               price: 96000,  weeks: 2 },
    { id: 'multi',  name: 'Вторая языковая версия',            price: 78000,  weeks: 1 }
  ];
  var RUSH_PRICE = 0.30, RUSH_TIME = 0.35, VILKA = 0.22;

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

  function init(root) {
    if (root.__vb) return; root.__vb = 1;
    var st = { type: 'corp', pages: 6, opts: {}, rush: false };
    var $ = function (s) { return root.querySelector(s); };
    function fmt(n) { return String(Math.round(n / 1000) * 1000).replace(/\B(?=(\d{3})+(?!\d))/g, ' '); }
    function weeksWord(n) { var m = n % 100, k = n % 10; return m > 10 && m < 20 ? 'недель' : k === 1 ? 'неделя' : k > 1 && k < 5 ? 'недели' : 'недель'; }

    var tBox = $('#vbkss-types');
    TYPES.forEach(function (t) {
      var b = document.createElement('button');
      b.type = 'button'; b.setAttribute('role', 'radio');
      b.setAttribute('aria-checked', t.id === st.type ? 'true' : 'false');
      b.innerHTML = '<b>' + t.name + '<\/b><i>' + t.hint + '<\/i>';
      b.addEventListener('click', function () {
        st.type = t.id;
        tBox.querySelectorAll('button').forEach(function (x) { x.setAttribute('aria-checked', 'false'); });
        b.setAttribute('aria-checked', 'true');
        render();
      });
      tBox.appendChild(b);
    });

    var oBox = $('#vbkss-opts');
    OPTIONS.forEach(function (o) {
      var l = document.createElement('label');
      l.className = 'vbkss-chk';
      l.innerHTML = '<input type="checkbox"><span class="vbkss-chk__box"><\/span><span>' + o.name + '<\/span>' +
        '<span class="vbkss-chk__p">+' + fmt(o.price) + ' ₽<\/span>';
      l.querySelector('input').addEventListener('change', function () { st.opts[o.id] = this.checked; render(); });
      oBox.appendChild(l);
    });

    $('#vbkss-range').addEventListener('input', function () { st.pages = +this.value; render(); });
    $('#vbkss-rushinp').addEventListener('change', function () { st.rush = this.checked; render(); });

    function render() {
      var t = TYPES.filter(function (x) { return x.id === st.type; })[0];
      var pagesCost = t.perPage * Math.max(0, st.pages - 1);
      var extras = 0, extraWeeks = 0, chosen = [];
      OPTIONS.forEach(function (o) {
        if (st.opts[o.id]) { extras += o.price; extraWeeks += o.weeks; chosen.push(o.name); }
      });
      var sum = t.base + pagesCost + extras;
      var weeks = t.weeks + Math.ceil(st.pages / 4) + extraWeeks;
      if (st.rush) { sum = sum * (1 + RUSH_PRICE); weeks = Math.ceil(weeks * (1 - RUSH_TIME)); }

      $('#vbkss-pages').textContent = st.pages;
      $('#vbkss-sum').textContent = fmt(sum) + ' — ' + fmt(sum * (1 + VILKA)) + ' ₽';
      $('#vbkss-term').textContent = weeks + ' ' + weeksWord(weeks);

      var rows = [['Базовая часть · ' + t.name, t.base], ['Шаблоны страниц, ' + st.pages + ' шт.', pagesCost]];
      if (extras) rows.push(['Дополнительные работы', extras]);
      if (st.rush) rows.push(['Надбавка за срочность', (t.base + pagesCost + extras) * RUSH_PRICE]);
      $('#vbkss-rows').innerHTML = rows.map(function (r) {
        return '<li><span>' + r[0] + '<\/span><b>' + fmt(r[1]) + ' ₽<\/b><\/li>';
      }).join('');

      var hid = $('#vbkss-hidden');
      if (hid) hid.value = t.name + ', ' + st.pages + ' шаблонов' + (chosen.length ? ', ' + chosen.join(', ') : '') +
        (st.rush ? ', срочно' : '') + ' — от ' + fmt(sum) + ' ₽, ' + weeks + ' нед.';
    }
    render();

    var form = root.querySelector('.vbkss-form');
    if (form && !form.__b) {
      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 (_) {}
        }
      });
    }
    if (!window.vbkssSuccess) {
      window.vbkssSuccess = function (f) {
        try { f.innerHTML = '<div class="vbkss-done"><b>Расчёт отправлен<\/b><span>Свяжемся в течение рабочего дня и уточним детали проекта.<\/span><\/div>'; } catch (e) {}
      };
    }
  }
})();
</script>

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

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

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

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

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

Где в кодеЗа что отвечает
объект TYPESтипы сайтов, базовая цена и срок
массив OPTIONSдополнительные работы, их цена и влияние на срок
RUSHкоэффициент срочности
formservices[]приёмники заявок Tilda

Калькулятор стоимости сайта: зачем он нужен

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

Срок считается параллельно с деньгами — это редкая, но важная деталь: половина возражений в разработке не про цену, а про «когда будет готово».

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

  • Вилка отсекает нецелевые заявки и экономит время на созвонах. Если боитесь конкурентов, показывайте диапазон пошире и обязательно оставьте формулировку о том, что точная смета считается после брифа.

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

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

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

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

Другие калькуляторы

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

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

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