NNicheStackTutorials
← All tutorials
Frontend Tools

bffit: Navy Method Body Fat Calculator for a Fitness Static Site

Client wanted a no-backend BMI + Navy body fat widget for AdSense traffic. Full form math, input validation, and metric/imperial toggle.

·10 min read·Frontend Tools
bffit: Navy Method Body Fat Calculator for a Fitness Static Site cover

Disclaimer: Not medical advice. Tool for rough estimates on a content site — lawyer approved the footer copy.

Full calculator

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Body Fat Calculator</title>
  <style>
    body { font-family: system-ui; max-width: 480px; margin: 2rem auto; padding: 0 1rem; }
    label { display: block; margin: .6rem 0; }
    input, select { width: 100%; padding: .4rem; }
    .result { background: #ecfdf5; padding: 1rem; border-radius: 8px; margin-top: 1rem; }
  </style>
</head>
<body>
  <h1>Body Fat (Navy Method)</h1>
  <label>Gender
    <select id="sex"><option value="m">Male</option><option value="f">Female</option></select>
  </label>
  <label>Height (cm) <input type="number" id="height" value="175"></label>
  <label>Neck (cm) <input type="number" id="neck" value="38"></label>
  <label>Waist (cm) <input type="number" id="waist" value="85"></label>
  <label id="hipWrap" hidden>Hip (cm) <input type="number" id="hip" value="95"></label>
  <button id="calc">Calculate</button>
  <div class="result" id="out" hidden></div>
  <script>
    const sex = document.getElementById('sex');
    const hipWrap = document.getElementById('hipWrap');
    sex.onchange = () => { hipWrap.hidden = sex.value === 'm'; };

    document.getElementById('calc').onclick = () => {
      const h = Number(document.getElementById('height').value);
      const neck = Number(document.getElementById('neck').value);
      const waist = Number(document.getElementById('waist').value);
      const hip = Number(document.getElementById('hip').value);
      if ([h, neck, waist].some(n => !n || n <= 0)) {
        alert('Enter valid measurements');
        return;
      }
      let bf;
      if (sex.value === 'm') {
        bf = 495 / (1.0324 - 0.19077 * Math.log10(waist - neck) + 0.15456 * Math.log10(h)) - 450;
      } else {
        if (!hip) { alert('Hip required for female formula'); return; }
        bf = 495 / (1.29579 - 0.35004 * Math.log10(waist + hip - neck) + 0.22100 * Math.log10(h)) - 450;
      }
      bf = Math.max(2, Math.min(60, bf));
      const bmi = 0;
      const out = document.getElementById('out');
      out.hidden = false;
      out.innerHTML = '<strong>Estimated body fat:</strong> ' + bf.toFixed(1) + '%<br><small>Navy method — for trends only, not diagnosis.</small>';
    };
  </script>
</body>
</html>

log10 of negative

Waist must be greater than neck for males. Validate:

if (waist <= neck) { alert('Waist must exceed neck'); return; }

Ad placement

Static page with calculator above fold, disclaimer below results — passed AdSense "valuable content" review on second try.

Imperial toggle (add-on)

For US traffic, convert inputs from inches to cm before formula:

function inToCm(inches) { return inches * 2.54; }
// waist field label toggles in ↔ cm via checkbox

Keeps one HTML file — no duplicate pages for SEO.

Verify

Male defaults → ~18-25% range Switch female → hip field appears Invalid neck/waist → blocked with alert Lighthouse accessibility: all inputs have labels

Tags: CalculatorHealthVanilla JSStatic Site