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

Калькулятор калорий и КБЖУ для сайта

Считает норму калорий по формуле Миффлина — Сан Жеора и раскладывает её на белки, жиры и углеводы под выбранную цель.

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

Код блока

<section class="vbkkb">
  <div class="vbkkb-wrap">
    <div class="vbkkb-head">
      <h2 class="vbkkb-h2">Калькулятор калорий и КБЖУ</h2>
      <p class="vbkkb-lead">Считаем по формуле Миффлина — Сан Жеора: она точнее устаревшей Харриса — Бенедикта и учитывает возраст, рост и вес.</p>
    </div>

    <div class="vbkkb-grid">
      <div class="vbkkb-panel">
        <div class="vbkkb-two">
          <div class="vbkkb-field">
            <span class="vbkkb-lbl">Пол</span>
            <div class="vbkkb-seg" id="vbkkb-sex" role="radiogroup" aria-label="Пол">
              <button type="button" data-v="m" aria-checked="true" role="radio">Мужской</button>
              <button type="button" data-v="f" aria-checked="false" role="radio">Женский</button>
            </div>
          </div>
          <div class="vbkkb-field">
            <label class="vbkkb-lbl" for="vbkkb-age">Возраст, лет</label>
            <input type="number" id="vbkkb-age" class="vbkkb-inp" value="32" min="14" max="90" inputmode="numeric">
          </div>
          <div class="vbkkb-field">
            <label class="vbkkb-lbl" for="vbkkb-h">Рост, см</label>
            <input type="number" id="vbkkb-h" class="vbkkb-inp" value="178" min="130" max="220" inputmode="numeric">
          </div>
          <div class="vbkkb-field">
            <label class="vbkkb-lbl" for="vbkkb-w">Вес, кг</label>
            <input type="number" id="vbkkb-w" class="vbkkb-inp" value="82" min="35" max="220" inputmode="numeric">
          </div>
        </div>

        <div class="vbkkb-field">
          <label class="vbkkb-lbl" for="vbkkb-act">Активность</label>
          <select id="vbkkb-act" class="vbkkb-sel"></select>
        </div>

        <div class="vbkkb-field">
          <span class="vbkkb-lbl">Цель</span>
          <div class="vbkkb-goals" id="vbkkb-goals" role="radiogroup" aria-label="Цель"></div>
        </div>
      </div>

      <aside class="vbkkb-out">
        <span class="vbkkb-out__lbl">Норма в день</span>
        <strong class="vbkkb-out__sum" id="vbkkb-kcal"></strong>
        <span class="vbkkb-out__sub" id="vbkkb-basal"></span>

        <div class="vbkkb-macros" id="vbkkb-macros"></div>

        <a class="vbkkb-cta" href="#trener">Разобрать питание с тренером</a>
        <p class="vbkkb-note">Расчёт справочный. При хронических заболеваниях, беременности и после операций нормы подбирает врач.</p>
      </aside>
    </div>
  </div>
</section>

<style>
.vbkkb, .vbkkb *, .vbkkb *::before, .vbkkb *::after { box-sizing: border-box; }
.vbkkb {
  --acc: #57a83f; --acc-dark: #468a32; --ink: #1b2118; --muted: #5f6b5b; --line: #e0e6dd; --soft: #f4f7f2;
  --p: #4f8ed6; --f2: #e0a13a; --c: #57a83f;
  --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;
}
.vbkkb-wrap { max-width: 1140px; margin: 0 auto; padding: 0 clamp(0px, 2vw, 40px); }
.vbkkb-head { max-width: 44em; margin-bottom: clamp(22px, 3vw, 36px); }
.vbkkb-h2 { font-family: var(--fh); font-size: clamp(26px, 3.4vw, 40px); line-height: 1.1; font-weight: 700; letter-spacing: -.02em; margin: 0 0 12px; }
.vbkkb-lead { font-size: 16px; line-height: 1.6; color: var(--muted); margin: 0; }

.vbkkb-grid { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); gap: 18px; align-items: start; }
.vbkkb-panel { background: var(--soft); border-radius: 20px; padding: clamp(20px, 2.6vw, 30px); }
.vbkkb-two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin-bottom: 20px; }
.vbkkb-field { margin-bottom: 20px; }
.vbkkb-two .vbkkb-field { margin-bottom: 0; }
.vbkkb-lbl { display: block; font-size: 14px; color: var(--muted); margin-bottom: 9px; }
.vbkkb-inp, .vbkkb-sel { width: 100%; height: 52px; padding: 0 15px; font: inherit; font-size: 16px; -webkit-appearance: none; appearance: none;
  border: 1.5px solid var(--line); border-radius: 10px; background: #fff; color: var(--ink); }
.vbkkb-inp:focus, .vbkkb-sel:focus { outline: 2px solid var(--acc); outline-offset: -2px; }
.vbkkb-sel { padding-right: 38px;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 19px) 23px, calc(100% - 13px) 23px; background-size: 6px 6px, 6px 6px; background-repeat: no-repeat; }
.vbkkb-seg { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
.vbkkb-seg button, .vbkkb-goals button { 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: 10px; height: 52px; font-size: 15px; transition: .18s ease; }
.vbkkb-seg button:hover, .vbkkb-goals button:hover { border-color: #bfcfb8; }
.vbkkb-seg button[aria-checked="true"], .vbkkb-goals button[aria-checked="true"] { border-color: var(--acc); background: #eef6ea !important; font-weight: 600; }
.vbkkb-goals { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }

.vbkkb-out { background: var(--ink); color: #fff; border-radius: 20px; padding: clamp(20px, 2.6vw, 30px); position: sticky; top: 20px; }
.vbkkb-out__lbl { display: block; font-size: 13px; color: #9daa98; }
.vbkkb-out__sum { display: block; font-family: var(--fh); font-size: clamp(34px, 4vw, 48px); line-height: 1.05; font-weight: 700; color: #d8ef9f; margin: 6px 0 4px; }
.vbkkb-out__sub { display: block; font-size: 13px; color: #9daa98; margin-bottom: 22px; }
.vbkkb-macros { display: grid; gap: 16px; padding-top: 20px; border-top: 1px solid rgba(255,255,255,.14); margin-bottom: 24px; }
.vbkkb-macro__top { display: flex; justify-content: space-between; align-items: baseline; font-size: 14px; color: #b8c2b4; margin-bottom: 7px; }
.vbkkb-macro__top b { font-family: var(--fh); font-size: 18px; color: #fff; }
.vbkkb-macro__top i { font-style: normal; font-size: 12px; color: #9daa98; margin-left: 6px; }
.vbkkb-macro__bar { height: 6px; border-radius: 6px; background: rgba(255,255,255,.1); overflow: hidden; }
.vbkkb-macro__bar span { display: block; height: 100%; border-radius: 6px; transition: width .45s cubic-bezier(.22,1,.36,1); }
.vbkkb-cta, .vbkkb-cta:link, .vbkkb-cta:visited, .vbkkb-cta:active, .vbkkb-cta:focus { display: flex; align-items: center; justify-content: center;
  width: 100%; min-height: 54px; border-radius: 10px; font-size: 16px; font-weight: 600;
  background: var(--acc); color: #fff !important; text-decoration: none !important; transition: background .2s ease; }
.vbkkb-cta:hover { background: var(--acc-dark); color: #fff !important; }
.vbkkb-note { margin: 14px 0 0; font-size: 11.5px; line-height: 1.5; color: #7d8a79; }

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

<script>
(function () {
  /* ── КОЭФФИЦИЕНТЫ АКТИВНОСТИ ── */
  var ACTIVITY = [
    { t: 'Сидячий образ жизни, без тренировок', k: 1.2 },
    { t: 'Лёгкая активность, 1–2 тренировки в неделю', k: 1.375 },
    { t: 'Средняя, 3–4 тренировки в неделю', k: 1.55 },
    { t: 'Высокая, 5–6 тренировок в неделю', k: 1.725 },
    { t: 'Очень высокая, спорт и физический труд', k: 1.9 }
  ];
  /* ── ЦЕЛИ: adj — поправка калорий, доли БЖУ должны давать 1 ── */
  var GOALS = [
    { id: 'cut',  t: 'Снизить вес', adj: -0.18, p: 0.32, f: 0.28, c: 0.40 },
    { id: 'keep', t: 'Удержать',    adj: 0,     p: 0.25, f: 0.30, c: 0.45 },
    { id: 'gain', t: 'Набрать',     adj: 0.14,  p: 0.28, f: 0.25, c: 0.47 }
  ];
  var KCAL = { p: 4, f: 9, c: 4 };
  var COLORS = { p: '#4f8ed6', f: '#e0a13a', c: '#8ac765' };
  var NAMES = { p: 'Белки', f: 'Жиры', c: 'Углеводы' };

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

  function init(root) {
    if (root.__vb) return; root.__vb = 1;
    var $ = function (s) { return root.querySelector(s); };
    var st = { sex: 'm', age: 32, h: 178, w: 82, act: 2, goal: 'keep' };

    $('#vbkkb-act').innerHTML = ACTIVITY.map(function (a, i) {
      return '<option value="' + i + '"' + (i === st.act ? ' selected' : '') + '>' + a.t + '<\/option>';
    }).join('');
    $('#vbkkb-goals').innerHTML = GOALS.map(function (g) {
      return '<button type="button" role="radio" data-v="' + g.id + '" aria-checked="' + (g.id === st.goal) + '">' + g.t + '<\/button>';
    }).join('');

    function seg(sel, key) {
      root.querySelectorAll(sel + ' button').forEach(function (b) {
        b.addEventListener('click', function () {
          st[key] = b.dataset.v;
          root.querySelectorAll(sel + ' button').forEach(function (x) { x.setAttribute('aria-checked', 'false'); });
          b.setAttribute('aria-checked', 'true');
          render();
        });
      });
    }
    seg('#vbkkb-sex', 'sex');
    seg('#vbkkb-goals', 'goal');

    ['age', 'h', 'w'].forEach(function (k) {
      $('#vbkkb-' + k).addEventListener('input', function () { st[k] = +this.value || 0; render(); });
    });
    $('#vbkkb-act').addEventListener('change', function () { st.act = +this.value; render(); });

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

    function render() {
      /* Миффлин — Сан Жеор: 10*вес + 6.25*рост − 5*возраст + (5 для мужчин, −161 для женщин) */
      var basal = 10 * st.w + 6.25 * st.h - 5 * st.age + (st.sex === 'm' ? 5 : -161);
      var goal = GOALS.filter(function (g) { return g.id === st.goal; })[0];
      var total = basal * ACTIVITY[st.act].k * (1 + goal.adj);

      $('#vbkkb-kcal').textContent = fmt(total) + ' ккал';
      $('#vbkkb-basal').textContent = 'Базовый обмен — ' + fmt(basal) + ' ккал, ниже него опускаться нельзя';

      $('#vbkkb-macros').innerHTML = ['p', 'f', 'c'].map(function (k) {
        var share = goal[k];
        var grams = total * share / KCAL[k];
        return '<div class="vbkkb-macro"><div class="vbkkb-macro__top"><span>' + NAMES[k] + '<\/span>' +
          '<span><b>' + Math.round(grams) + ' г<\/b><i>' + Math.round(share * 100) + '%<\/i><\/span><\/div>' +
          '<div class="vbkkb-macro__bar"><span style="width:' + (share * 100) + '%;background:' + COLORS[k] + '"><\/span><\/div><\/div>';
      }).join('');
    }
    render();
  }
})();
</script>

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

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

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

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

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

Где в кодеЗа что отвечает
объект ACTIVITYкоэффициенты активности
объект GOALSпоправка калорий и раскладка КБЖУ под цель
--accцвет результата и полос макронутриентов

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

Калькулятор КБЖУ — один из самых востребованных инструментов в фитнес-тематике: его ищут напрямую в поиске, и он приводит на сайт холодный трафик, который потом греется тренировками и абонементом.

Используется формула Миффлина — Сан Жеора, признанная точнее устаревшей Харриса — Бенедикта. Коэффициенты активности и распределение по целям вынесены в отдельные объекты и меняются под свою методику.

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

  • По Миффлину — Сан Жеора: она учитывает вес, рост, возраст и пол, а затем умножается на коэффициент активности. Формула записана в скрипте в две строки, её видно и можно сверить.

  • Да, в объекте GOALS у каждой цели заданы доли трёх нутриентов. Сумма долей должна давать единицу, в остальном значения любые.

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

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

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

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

Ещё блоки для фитнеса и спорта

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

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