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

Блок тарифов на лечение для сайта клиники

Разовый приём, годовая и семейная программа в одном ряду. Тумблер вверху переключает цены и один пункт состава между взрослым и детским приёмом, снизу меняется пояснение.

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

Код блока

<section class="vbtnl">
  <div class="vbtnl-wrap">
    <div class="vbtnl-head">
      <div class="vbtnl-head__txt">
        <h2 class="vbtnl-h2">Как оплачивать наблюдение</h2>
        <p class="vbtnl-lead">Три способа: прийти один раз с конкретной жалобой, взять программу на год или подключить к ней вторую половину семьи. Цены меняются при переключении на детский приём.</p>
      </div>
      <div class="vbtnl-switch" id="vbtnl-switch" role="group" aria-label="Кому подбираем программу"></div>
    </div>

    <div class="vbtnl-grid" id="vbtnl-grid"></div>
    <p class="vbtnl-note" id="vbtnl-note"></p>
  </div>
</section>

<style>
.vbtnl, .vbtnl *, .vbtnl *::before, .vbtnl *::after { box-sizing: border-box; }
.vbtnl {
  --acc: #1c7f8c; --acc-dark: #166874; --ink: #1d2b2e; --muted: #5f7276; --line: #dfe8e9; --soft: #f2f7f7;
  --f: var(--t-text-font, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif);
  --fh: var(--t-headline-font, var(--f));
  background: var(--soft); color: var(--ink); font-family: var(--f); padding: clamp(36px, 5vw, 80px) 20px;
}
.vbtnl-wrap { max-width: 1160px; margin: 0 auto; padding: 0 clamp(0px, 2vw, 40px); }
.vbtnl-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 22px; margin-bottom: clamp(24px, 3vw, 38px); }
.vbtnl-head__txt { max-width: 44em; }
.vbtnl-h2 { font-family: var(--fh); font-size: clamp(26px, 3.4vw, 40px); line-height: 1.12; font-weight: 600; letter-spacing: -.02em; margin: 0 0 12px; }
.vbtnl-lead { font-size: 16px; line-height: 1.65; color: var(--muted); margin: 0; }
.vbtnl-switch { display: inline-flex; gap: 4px; padding: 4px; background: #fff; border: 1px solid var(--line); border-radius: 999px; }
.vbtnl-sw { border: 0; margin: 0; -webkit-appearance: none; appearance: none; font: inherit; font-size: 15px; cursor: pointer;
  padding: 11px 22px; border-radius: 999px; background: none !important; color: var(--muted) !important; transition: .2s ease; white-space: nowrap; }
.vbtnl-sw:hover { color: var(--acc) !important; }
.vbtnl-sw[aria-pressed="true"] { background: var(--acc) !important; color: #fff !important; font-weight: 600; }

.vbtnl-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(275px, 1fr)); gap: 18px; align-items: stretch; }
.vbtnl-card { position: relative; display: flex; flex-direction: column; background: #fff; border: 1px solid var(--line);
  border-radius: 20px; padding: clamp(22px, 2.4vw, 30px); }
.vbtnl-card--hot { border-color: var(--acc); box-shadow: 0 0 0 1px var(--acc); }
.vbtnl-badge { position: absolute; top: -11px; left: clamp(22px, 2.4vw, 30px); background: var(--acc); color: #fff;
  font-size: 11.5px; font-weight: 600; border-radius: 999px; padding: 5px 12px; }
.vbtnl-name { font-family: var(--fh); font-size: 19px; font-weight: 600; margin: 0 0 8px; }
.vbtnl-for { font-size: 13.5px; line-height: 1.55; color: var(--muted); margin: 0 0 20px; min-height: 3.4em; }
.vbtnl-price { min-height: 76px; margin-bottom: 14px; transition: opacity .2s ease; }
.vbtnl-price b { display: block; font-family: var(--fh); font-size: clamp(26px, 2.8vw, 34px); line-height: 1.1; font-weight: 600; letter-spacing: -.02em; }
.vbtnl-price span { display: block; font-size: 12.5px; line-height: 1.5; color: var(--muted); margin-top: 7px; }
.vbtnl-price.is-swap { opacity: 0; }
.vbtnl-term { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--acc); background: var(--soft);
  border-radius: 999px; padding: 7px 13px; margin: 0 0 18px; align-self: flex-start; }
.vbtnl-inc { list-style: none; margin: 0 0 22px; padding: 18px 0 0; border-top: 1px solid var(--line); flex: 1; display: grid; gap: 10px; align-content: start; }
.vbtnl-inc li { position: relative; padding-left: 22px; font-size: 14px; line-height: 1.5; }
.vbtnl-inc li::before { content: ''; position: absolute; left: 0; top: 7px; width: 12px; height: 2px; border-radius: 2px; background: var(--acc); }
.vbtnl-inc li.vbtnl-inc--mode { color: var(--acc); }
.vbtnl-cta, .vbtnl-cta:link, .vbtnl-cta:visited, .vbtnl-cta:active, .vbtnl-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; }
.vbtnl-cta:hover { background: #e3eeef; color: var(--ink) !important; }
.vbtnl-card--hot .vbtnl-cta { background: var(--acc); color: #fff !important; }
.vbtnl-card--hot .vbtnl-cta:hover { background: var(--acc-dark); color: #fff !important; }
.vbtnl-note { margin: clamp(20px, 2.4vw, 30px) 0 0; font-size: 14px; line-height: 1.6; color: var(--muted); max-width: 52em; }

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

<script>
(function () {
  var CTA_HREF = '#zapis';

  /* ── РЕЖИМЫ: между ними переключает верхний тумблер ── */
  var MODES = [
    { id: 'adult', label: 'Взрослым', note: 'Цены указаны для пациентов старше 18 лет. Приём ведёт терапевт, при необходимости подключает профильных врачей клиники без доплаты за консилиум.' },
    { id: 'kid', label: 'Детям', note: 'Детские программы рассчитаны на возраст от года до 17 лет. Приём ведёт педиатр, прививки по календарю входят в годовую и семейную программу.' }
  ];

  /* ── ПАКЕТЫ: price, sub и extra задаются отдельно для взрослых и детей ── */
  var PACKS = [
    { name: 'Разовый приём', forWho: 'Разобраться с одной жалобой и получить назначения на руки', term: 'приём 40 минут', popular: false,
      price: { adult: '2 400 ₽', kid: '2 100 ₽' },
      sub: { adult: 'за приём, повторный в течение 14 дней входит в цену', kid: 'за приём, осмотр перед садиком входит в цену' },
      inc: ['Осмотр и разбор жалобы', 'Назначения в письменном виде', 'Расшифровка анализов на повторном приёме'],
      extra: { adult: 'Направление к профильному врачу', kid: 'Справка для сада или школы' } },
    { name: 'Годовая программа', forWho: 'Наблюдаться весь год у одного врача и не считать каждый визит', term: '12 месяцев', popular: true,
      price: { adult: '32 000 ₽', kid: '27 500 ₽' },
      sub: { adult: 'за год или 2 900 ₽ в месяц при помесячной оплате', kid: 'за год или 2 500 ₽ в месяц при помесячной оплате' },
      inc: ['Приёмы врача без ограничения по числу', 'Плановое обследование один раз в год', 'Анализы по программе наблюдения', 'Электронная карта с историей приёмов'],
      extra: { adult: 'Три вызова врача на дом', kid: 'Прививки по национальному календарю' } },
    { name: 'Семейная программа', forWho: 'Подключить двоих и вести карты в одном месте', term: '12 месяцев на двоих', popular: false,
      price: { adult: '58 000 ₽', kid: '49 000 ₽' },
      sub: { adult: 'за двоих взрослых, третий участник добавляется за 24 000 ₽', kid: 'за двоих детей, третий участник добавляется за 20 000 ₽' },
      inc: ['Всё, что входит в годовую программу', 'Общий кабинет с картами участников', 'Запись на смежное время одним звонком'],
      extra: { adult: 'Ведёт один терапевт на семью', kid: 'Ведёт один педиатр на обоих детей' } }
  ];

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

  function init(root) {
    if (root.__vb) return; root.__vb = 1;
    var sw = root.querySelector('#vbtnl-switch'), grid = root.querySelector('#vbtnl-grid'), note = root.querySelector('#vbtnl-note');
    var mode = MODES[0].id;

    sw.innerHTML = MODES.map(function (m) {
      return '<button type="button" class="vbtnl-sw" data-m="' + m.id + '" aria-pressed="' + (m.id === mode) + '">' + m.label + '<\/button>';
    }).join('');

    grid.innerHTML = PACKS.map(function (p) {
      return '<article class="vbtnl-card' + (p.popular ? ' vbtnl-card--hot' : '') + '">' +
        (p.popular ? '<span class="vbtnl-badge">Берут чаще всего<\/span>' : '') +
        '<h3 class="vbtnl-name">' + p.name + '<\/h3>' +
        '<p class="vbtnl-for">' + p.forWho + '<\/p>' +
        '<div class="vbtnl-price"><b><\/b><span><\/span><\/div>' +
        '<p class="vbtnl-term">Срок: ' + p.term + '<\/p>' +
        '<ul class="vbtnl-inc">' + p.inc.map(function (x) { return '<li>' + x + '<\/li>'; }).join('') +
        '<li class="vbtnl-inc--mode"><\/li><\/ul>' +
        '<a class="vbtnl-cta" href="' + CTA_HREF + '">Записаться<\/a><\/article>';
    }).join('');

    var cards = root.querySelectorAll('.vbtnl-card');

    function paint(animate) {
      for (var i = 0; i < cards.length; i++) {
        var p = PACKS[i], box = cards[i].querySelector('.vbtnl-price');
        box.querySelector('b').textContent = p.price[mode];
        box.querySelector('span').textContent = p.sub[mode];
        cards[i].querySelector('.vbtnl-inc--mode').textContent = p.extra[mode];
        if (animate) {
          box.classList.add('is-swap');
          (function (b) { setTimeout(function () { b.classList.remove('is-swap'); }, 30); })(box);
        }
      }
      for (var k = 0; k < MODES.length; k++) if (MODES[k].id === mode) note.textContent = MODES[k].note;
    }

    var btns = sw.querySelectorAll('.vbtnl-sw');
    for (var b = 0; b < btns.length; b++) {
      btns[b].addEventListener('click', function () {
        mode = this.getAttribute('data-m');
        for (var j = 0; j < btns.length; j++) btns[j].setAttribute('aria-pressed', btns[j].getAttribute('data-m') === mode ? 'true' : 'false');
        var boxes = root.querySelectorAll('.vbtnl-price');
        for (var q = 0; q < boxes.length; q++) boxes[q].classList.add('is-swap');
        setTimeout(function () { paint(true); }, 170);
      });
    }

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

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

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

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

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

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

Где в кодеЗа что отвечает
массив MODES в начале скриптаназвания режимов тумблера и пояснение под сеткой
массив PACKSназвания пакетов, состав, срок и признак популярного
поля price и sub у пакетацена и подпись под ней отдельно для взрослых и детей
поле extra у пакетапункт списка, который меняется вместе с режимом
переменная CTA_HREFякорь или адрес, куда ведёт кнопка «Записаться»

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

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

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

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

  • Да, режимы задаются массивом MODES. Поменяйте подписи и ключи, а в полях price, sub и extra используйте те же ключи, что стоят в id режима.

  • Допишите объект в массив PACKS с обоими вариантами цены. Сетка на auto-fit сама поставит карточку в ряд, на узком экране пакеты идут один под другим.

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

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

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

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

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

Ещё блоки для медицины и стоматологии

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

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