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

Блок тарифов на онлайн-курс с переключателем оплаты

Самостоятельно, с куратором и с трудоустройством в одном ряду. Переключатель «Полная оплата / Рассрочка» пересчитывает цифры в карточках и показывает разницу между двумя способами оплаты.

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

Код блока

<section class="vbtnc">
  <div class="vbtnc-wrap">
    <div class="vbtnc-head">
      <h2 class="vbtnc-h2">Три формата одной программы</h2>
      <p class="vbtnc-lead">Уроки у всех одинаковые, отличается сопровождение: сколько с вами работает куратор и доводим ли до первого предложения о работе.</p>
    </div>

    <div class="vbtnc-bar">
      <div class="vbtnc-pay" id="vbtnc-pay" role="group" aria-label="Способ оплаты"></div>
      <p class="vbtnc-hint" id="vbtnc-hint"></p>
    </div>

    <div class="vbtnc-grid" id="vbtnc-grid"></div>
    <p class="vbtnc-note">Рассрочку оформляет банк-партнёр за один день, первый платёж списывается через месяц после старта потока. Цена фиксируется договором на весь срок обучения.</p>
  </div>
</section>

<style>
.vbtnc, .vbtnc *, .vbtnc *::before, .vbtnc *::after { box-sizing: border-box; }
.vbtnc {
  --acc: #4b56d2; --acc-dark: #3d47b5; --ink: #191b2e; --muted: #5f6280; --line: #e3e4ef; --soft: #f4f4fb;
  --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;
}
.vbtnc-wrap { max-width: 1160px; margin: 0 auto; padding: 0 clamp(0px, 2vw, 40px); }
.vbtnc-head { max-width: 44em; margin-bottom: clamp(20px, 2.6vw, 30px); }
.vbtnc-h2 { font-family: var(--fh); font-size: clamp(26px, 3.4vw, 40px); line-height: 1.12; font-weight: 700; letter-spacing: -.02em; margin: 0 0 12px; }
.vbtnc-lead { font-size: 16px; line-height: 1.65; color: var(--muted); margin: 0; }

.vbtnc-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 20px; margin-bottom: clamp(20px, 2.6vw, 28px); }
.vbtnc-pay { display: inline-flex; gap: 6px; padding: 5px; background: var(--soft); border-radius: 14px; }
.vbtnc-pbtn { border: 0; margin: 0; -webkit-appearance: none; appearance: none; font: inherit; font-size: 15px; cursor: pointer;
  padding: 11px 20px; border-radius: 10px; background: none !important; color: var(--muted) !important; transition: .2s ease; white-space: nowrap; }
.vbtnc-pbtn:hover { color: var(--acc) !important; }
.vbtnc-pbtn[aria-pressed="true"] { background: #fff !important; color: var(--ink) !important; font-weight: 600; box-shadow: 0 1px 3px rgba(25, 27, 46, .12); }
.vbtnc-hint { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--muted); }

.vbtnc-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(272px, 1fr)); gap: 16px; align-items: stretch; }
.vbtnc-card { display: flex; flex-direction: column; background: #fff; border: 1px solid var(--line); border-radius: 18px;
  padding: clamp(22px, 2.4vw, 30px); }
.vbtnc-card--hot { background: var(--soft); border-color: var(--soft); }
.vbtnc-top { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.vbtnc-name { font-family: var(--fh); font-size: 19px; font-weight: 700; margin: 0; }
.vbtnc-badge { font-size: 11.5px; font-weight: 600; color: #fff; background: var(--acc); border-radius: 999px; padding: 5px 11px; }
.vbtnc-for { font-size: 13.5px; line-height: 1.55; color: var(--muted); margin: 0 0 20px; min-height: 4.3em; }

.vbtnc-price { min-height: 84px; margin-bottom: 18px; transition: opacity .18s ease; }
.vbtnc-price.is-swap { opacity: 0; }
.vbtnc-price b { font-family: var(--fh); font-size: clamp(27px, 2.8vw, 34px); line-height: 1.05; font-weight: 700; letter-spacing: -.02em; }
.vbtnc-price i { font-style: normal; font-size: 14px; color: var(--muted); margin-left: 6px; }
.vbtnc-price span { display: block; font-size: 12.5px; line-height: 1.5; color: var(--muted); margin-top: 9px; }
.vbtnc-price span u { text-decoration: none; color: var(--acc); font-weight: 600; }

.vbtnc-meta { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 0 0 18px; padding: 16px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.vbtnc-card--hot .vbtnc-meta { border-color: #e0e0ee; }
.vbtnc-meta div span { display: block; font-size: 11.5px; color: var(--muted); margin-bottom: 3px; }
.vbtnc-meta div b { font-size: 14.5px; font-weight: 600; }

.vbtnc-inc { list-style: none; margin: 0 0 22px; padding: 0; flex: 1; display: grid; gap: 10px; align-content: start; }
.vbtnc-inc li { position: relative; padding-left: 26px; font-size: 14px; line-height: 1.5; }
.vbtnc-inc li::before { content: ''; position: absolute; left: 0; top: 2px; width: 17px; height: 17px; border-radius: 50%; background: rgba(75, 86, 210, .13); }
.vbtnc-inc li::after { content: ''; position: absolute; left: 6px; top: 5px; width: 4px; height: 9px;
  border: 2px solid var(--acc); border-top: 0; border-left: 0; transform: rotate(42deg); }

.vbtnc-cta, .vbtnc-cta:link, .vbtnc-cta:visited, .vbtnc-cta:active, .vbtnc-cta:focus { display: flex; align-items: center; justify-content: center;
  margin-top: auto; min-height: 54px; border-radius: 12px; font-size: 16px; font-weight: 600;
  background: var(--soft); color: var(--ink) !important; text-decoration: none !important; transition: .18s ease; }
.vbtnc-cta:hover { background: #e8e8f6; color: var(--ink) !important; }
.vbtnc-card--hot .vbtnc-cta { background: var(--acc); color: #fff !important; }
.vbtnc-card--hot .vbtnc-cta:hover { background: var(--acc-dark); color: #fff !important; }
.vbtnc-note { margin: clamp(18px, 2.2vw, 26px) 0 0; font-size: 13.5px; line-height: 1.6; color: var(--muted); max-width: 54em; }

@media (max-width: 560px) { .vbtnc-for { min-height: 0; } .vbtnc-price { min-height: 0; } }
@media (prefers-reduced-motion: reduce) { .vbtnc * { transition: none !important; } }
</style>

<script>
(function () {
  var CTA_HREF = '#zapis-na-potok';
  var PARTS = 12;          /* число платежей в рассрочке */

  /* ── ФОРМАТЫ ОБУЧЕНИЯ ── */
  var PLANS = [
    { name: 'Самостоятельно', hot: false,
      forWho: 'Подойдёт, если вы уже пробовали учиться сами и вам нужна последовательность тем и доступ к материалам.',
      full: 39900, month: 3700, term: '4 месяца', load: '6 часов в неделю',
      inc: ['Доступ к урокам на два года', '12 заданий с автопроверкой', 'Чат потока и разборы в записи', 'Сертификат после итоговой работы'] },
    { name: 'С куратором', hot: true,
      forWho: 'Подойдёт, если нужны внешние сроки и живой разбор работ, чтобы дойти до конца программы.',
      full: 79900, month: 7400, term: '6 месяцев', load: '8 часов в неделю',
      inc: ['Всё из формата «Самостоятельно»', 'Проверка заданий за два рабочих дня', 'Созвон с куратором раз в две недели', 'Три проекта в портфолио', 'Разбор итоговой работы голосом'] },
    { name: 'С трудоустройством', hot: false,
      forWho: 'Подойдёт, если вы выходите на рынок впервые и хотите пройти путь до первого предложения о работе с сопровождением.',
      full: 129900, month: 12000, term: '9 месяцев', load: '10 часов в неделю',
      inc: ['Всё из формата «С куратором»', 'Резюме и профиль на площадках вакансий', 'Пять тренировочных собеседований', 'Карьерный консультант до выхода на работу', 'Возврат оплаты, если работы нет через полгода'] }
  ];

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

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

  function init(root) {
    if (root.__vb) return; root.__vb = 1;
    var grid = root.querySelector('#vbtnc-grid'), pay = root.querySelector('#vbtnc-pay'), hint = root.querySelector('#vbtnc-hint');
    var mode = 'full';

    pay.innerHTML =
      '<button type="button" class="vbtnc-pbtn" data-m="full" aria-pressed="true">Полная оплата<\/button>' +
      '<button type="button" class="vbtnc-pbtn" data-m="split" aria-pressed="false">Рассрочка<\/button>';

    grid.innerHTML = PLANS.map(function (p, n) {
      return '<article class="vbtnc-card' + (p.hot ? ' vbtnc-card--hot' : '') + '">' +
        '<div class="vbtnc-top"><h3 class="vbtnc-name">' + p.name + '<\/h3>' +
        (p.hot ? '<span class="vbtnc-badge">Выбирают чаще всего<\/span>' : '') + '<\/div>' +
        '<p class="vbtnc-for">' + p.forWho + '<\/p>' +
        '<div class="vbtnc-price" data-n="' + n + '"><\/div>' +
        '<div class="vbtnc-meta"><div><span>Срок<\/span><b>' + p.term + '<\/b><\/div>' +
        '<div><span>Нагрузка<\/span><b>' + p.load + '<\/b><\/div><\/div>' +
        '<ul class="vbtnc-inc">' + p.inc.map(function (x) { return '<li>' + x + '<\/li>'; }).join('') + '<\/ul>' +
        '<a class="vbtnc-cta" href="' + CTA_HREF + '">Записаться на поток<\/a><\/article>';
    }).join('');

    var boxes = grid.querySelectorAll('.vbtnc-price');

    function priceHTML(p) {
      if (mode === 'split') {
        return '<b>' + fmt(p.month) + '<\/b><i>в месяц<\/i>' +
          '<span>' + PARTS + ' платежей, всего ' + fmt(p.month * PARTS) + '<\/span>';
      }
      var save = p.month * PARTS - p.full;
      return '<b>' + fmt(p.full) + '<\/b><i>сразу<\/i>' +
        '<span>дешевле рассрочки на <u>' + fmt(save) + '<\/u><\/span>';
    }

    function draw(animate) {
      hint.textContent = mode === 'split'
        ? 'Рассрочку оформляет банк, справка о доходах не нужна.'
        : 'При оплате целиком место на потоке держим 5 дней.';
      for (var i = 0; i < boxes.length; i++) {
        (function (box) {
          var p = PLANS[+box.getAttribute('data-n')];
          if (!animate) { box.innerHTML = priceHTML(p); return; }
          box.className = 'vbtnc-price is-swap';
          setTimeout(function () { box.innerHTML = priceHTML(p); box.className = 'vbtnc-price'; }, 170);
        })(boxes[i]);
      }
    }

    pay.addEventListener('click', function (e) {
      var b = e.target.closest ? e.target.closest('.vbtnc-pbtn') : null;
      if (!b || b.getAttribute('data-m') === mode) return;
      mode = b.getAttribute('data-m');
      var all = pay.querySelectorAll('.vbtnc-pbtn');
      for (var i = 0; i < all.length; i++) all[i].setAttribute('aria-pressed', all[i] === b ? 'true' : 'false');
      draw(true);
    });

    draw(false);
  }
})();
</script>

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

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

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

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

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

Где в кодеЗа что отвечает
массив PLANS в начале скриптаназвания форматов, цены, срок, нагрузка и состав
поля full и month у форматацена целиком и платёж в месяц, разница считается сама
переменная PARTSчисло платежей в рассрочке, по умолчанию 12
поле hot у форматакакая карточка получает бейдж и подложку
переменная CTA_HREFякорь кнопки: куда ведёт запись на поток
--acc и --acc-darkцвет бейджа, галочек и кнопки среднего формата

Тарифы на курс: зачем он нужен

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

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

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

  • Скрипт умножает месячный платёж на число платежей и вычитает цену при полной оплате. Если разницу показывать не нужно, удалите строку с классом vbtnc-price span в функции priceHTML.

  • Допишите объект в массив PLANS. Сетка построена на auto-fit с минимальной шириной 272 пикселя, поэтому карточка встанет в ряд или перенесётся на вторую строку без правки стилей.

  • Удалите блок с идентификатором vbtnc-pay из разметки и оставьте в функции priceHTML только нужную ветку. Остальная карточка продолжит работать, скрипт переключатель не ищет обязательным.

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

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

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

Другие блоки тарифов

Ещё блоки для онлайн-школ и курсов

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

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