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.
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