{"id":2408,"date":"2026-02-11T00:04:55","date_gmt":"2026-02-10T22:04:55","guid":{"rendered":"https:\/\/bio-me.bio\/?page_id=2408"},"modified":"2026-02-17T20:55:50","modified_gmt":"2026-02-17T18:55:50","slug":"heart-rate-zones-calculator","status":"publish","type":"page","link":"https:\/\/bio-me.bio\/?page_id=2408","title":{"rendered":"Heart Rate Zones Calculator"},"content":{"rendered":"\n<div class=\"eco-tool wp-block-group\" id=\"eco-tool-hrz-9c3d0\">\n  <div class=\"eco-tool__header\">\n    <h2 class=\"eco-tool__title\">Heart Rate Zones Calculator<\/h2>\n    <p class=\"eco-tool__lead\">\n      Estimate heart rate training zones using either a simple max HR formula or the Karvonen (HRR) method.\n    <\/p>\n  <\/div>\n\n  <form class=\"eco-tool__form\" id=\"eco-hrz-form-9c3d0\" novalidate>\n    <div class=\"eco-tool__grid3\">\n      <!-- Method -->\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"eco-hrz-method-9c3d0\">\n          Method<br>type\n        <\/label>\n        <select class=\"eco-tool__input\" id=\"eco-hrz-method-9c3d0\">\n          <option value=\"simple\" selected>Simple (220 \u2212 age)<\/option>\n          <option value=\"karvonen\">Karvonen (HRR)<\/option>\n        <\/select>\n        <div class=\"eco-tool__hint\">Karvonen uses resting heart rate for a more individualized estimate.<\/div>\n      <\/div>\n\n      <!-- Age -->\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"eco-hrz-age-9c3d0\">\n          Age<br>(years)\n        <\/label>\n        <input class=\"eco-tool__input\" id=\"eco-hrz-age-9c3d0\" type=\"number\" min=\"5\" max=\"110\" step=\"1\" placeholder=\"e.g., 30\" inputmode=\"numeric\" \/>\n        <div class=\"eco-tool__hint\">Used to estimate max heart rate.<\/div>\n      <\/div>\n\n      <!-- Resting HR -->\n      <div class=\"eco-tool__field\" id=\"eco-hrz-rest-wrap-9c3d0\" style=\"display:none;\">\n        <label class=\"eco-tool__label\" for=\"eco-hrz-rest-9c3d0\">\n          Resting HR<br>(bpm)\n        <\/label>\n        <input class=\"eco-tool__input\" id=\"eco-hrz-rest-9c3d0\" type=\"number\" min=\"30\" max=\"120\" step=\"1\" placeholder=\"e.g., 60\" inputmode=\"numeric\" \/>\n        <div class=\"eco-tool__hint\">Required for Karvonen (measure at rest).<\/div>\n      <\/div>\n    <\/div>\n\n    <div class=\"eco-tool__actions\">\n      <button type=\"button\" class=\"wp-element-button eco-tool__btn\" id=\"eco-hrz-calc-9c3d0\">Calculate<\/button>\n      <button type=\"button\" class=\"wp-element-button eco-tool__btn eco-tool__btn--ghost\" id=\"eco-hrz-reset-9c3d0\">Reset<\/button>\n      <div class=\"eco-tool__error\" id=\"eco-hrz-error-9c3d0\" aria-live=\"polite\"><\/div>\n    <\/div>\n  <\/form>\n\n  <div class=\"eco-tool__result\" id=\"eco-hrz-result-9c3d0\" hidden>\n    <h3 class=\"eco-tool__subtitle\">Training zones<\/h3>\n\n    <div class=\"eco-tool__cards\">\n      <div class=\"eco-tool__card\">\n        <div class=\"eco-tool__metric-label\">Estimated max HR<\/div>\n        <div class=\"eco-tool__metric-value\" id=\"eco-hrz-max-9c3d0\">\u2014<\/div>\n        <div class=\"eco-tool__metric-sub\" id=\"eco-hrz-maxnote-9c3d0\">\u2014<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__card\">\n        <div class=\"eco-tool__metric-label\">Method details<\/div>\n        <div class=\"eco-tool__metric-sub\" id=\"eco-hrz-detail-9c3d0\">\u2014<\/div>\n        <div class=\"eco-tool__metric-sub eco-tool__muted\">Zones are approximate.<\/div>\n      <\/div>\n    <\/div>\n\n    <div class=\"eco-tool__tableWrap\">\n      <table class=\"eco-tool__table\" aria-label=\"Heart rate zones table\">\n        <thead>\n          <tr>\n            <th>Zone<\/th>\n            <th>Intensity<\/th>\n            <th>Range (bpm)<\/th>\n          <\/tr>\n        <\/thead>\n        <tbody id=\"eco-hrz-tbody-9c3d0\"><\/tbody>\n      <\/table>\n    <\/div>\n\n    <p class=\"eco-tool__note\">\n      This tool provides an estimate only. Individual max HR varies.\n    <\/p>\n  <\/div>\n<\/div>\n\n<style>\n.eco-tool{border:1px solid rgba(0,0,0,.12);border-radius:12px;padding:16px}\n.eco-tool__grid3{display:grid;grid-template-columns:1fr;gap:16px}\n@media (min-width:860px){.eco-tool__grid3{grid-template-columns:1fr 1fr 1fr}}\n.eco-tool__field{display:flex;flex-direction:column;gap:6px}\n.eco-tool__label{font-weight:600}\n.eco-tool__input{height:44px;padding:0 12px;border:1px solid rgba(0,0,0,.2);border-radius:10px;background:#fff;font:inherit;box-sizing:border-box}\n.eco-tool__hint{font-size:.92em;opacity:.78;min-height:38px}\n\n.eco-tool__actions{display:flex;gap:10px;margin-top:16px;align-items:center;flex-wrap:wrap}\n.eco-tool__btn{padding:10px 22px}\n.eco-tool__btn--ghost{background:transparent!important;border:1px solid rgba(0,0,0,.2)!important}\n.eco-tool__btn--ghost:hover,.eco-tool__btn--ghost:focus{background:rgba(0,0,0,.06)!important;border-color:rgba(0,0,0,.35)!important}\n.eco-tool__error{font-weight:600;min-height:1.2em;flex:1 1 240px}\n\n.eco-tool__result{margin-top:16px}\n.eco-tool__subtitle{margin:0 0 10px}\n.eco-tool__cards{display:grid;gap:10px;grid-template-columns:1fr}\n@media (min-width:860px){.eco-tool__cards{grid-template-columns:1fr 1fr}}\n.eco-tool__card{border:1px solid rgba(0,0,0,.12);border-radius:12px;padding:12px}\n.eco-tool__metric-label{opacity:.85;font-weight:600}\n.eco-tool__metric-value{font-size:1.6em;font-weight:800;margin-top:6px;line-height:1.1}\n.eco-tool__metric-sub{opacity:.85;margin-top:6px}\n.eco-tool__muted{opacity:.8}\n.eco-tool__note{margin-top:10px;opacity:.9}\n\n.eco-tool__tableWrap{margin-top:12px;overflow:auto;border:1px solid rgba(0,0,0,.12);border-radius:12px}\n.eco-tool__table{width:100%;border-collapse:collapse;min-width:520px}\n.eco-tool__table th,.eco-tool__table td{padding:10px 12px;border-bottom:1px solid rgba(0,0,0,.08);text-align:left}\n.eco-tool__table thead th{background:rgba(0,0,0,.03);font-weight:700}\n.eco-tool__table tbody tr:last-child td{border-bottom:none}\n<\/style>\n\n<script>\n(function(){\n  const S=\"9c3d0\";\n  const el=(id)=>document.getElementById(id+\"-\"+S);\n\n  const methodEl=el(\"eco-hrz-method\");\n  const ageEl=el(\"eco-hrz-age\");\n  const restWrap=el(\"eco-hrz-rest-wrap\");\n  const restEl=el(\"eco-hrz-rest\");\n\n  const calcBtn=el(\"eco-hrz-calc\");\n  const resetBtn=el(\"eco-hrz-reset\");\n  const errEl=el(\"eco-hrz-error\");\n\n  const resEl=el(\"eco-hrz-result\");\n  const maxEl=el(\"eco-hrz-max\");\n  const maxNoteEl=el(\"eco-hrz-maxnote\");\n  const detailEl=el(\"eco-hrz-detail\");\n  const tbodyEl=el(\"eco-hrz-tbody\");\n\n  const ZONES = [\n    { z: \"Zone 1\", pctLow: 0.50, pctHigh: 0.60, label: \"Very light\" },\n    { z: \"Zone 2\", pctLow: 0.60, pctHigh: 0.70, label: \"Light\" },\n    { z: \"Zone 3\", pctLow: 0.70, pctHigh: 0.80, label: \"Moderate\" },\n    { z: \"Zone 4\", pctLow: 0.80, pctHigh: 0.90, label: \"Hard\" },\n    { z: \"Zone 5\", pctLow: 0.90, pctHigh: 1.00, label: \"Maximum\" }\n  ];\n\n  function setError(msg){ errEl.textContent = msg || \"\"; }\n  function round(n){ return Math.round(n); }\n\n  function setUI(){\n    const m = methodEl.value;\n    restWrap.style.display = (m === \"karvonen\") ? \"flex\" : \"none\";\n    setError(\"\");\n    resEl.hidden = true;\n  }\n\n  function calculate(){\n    setError(\"\");\n\n    const age = Number(ageEl.value);\n    if(!Number.isFinite(age) || age <= 0){\n      setError(\"Enter a valid age.\");\n      resEl.hidden = true;\n      return;\n    }\n\n    const maxHR = 220 - age; \/\/ simple estimate used for both modes (common)\n    if(maxHR <= 0){\n      setError(\"Age value is not valid for calculation.\");\n      resEl.hidden = true;\n      return;\n    }\n\n    const method = methodEl.value;\n\n    let resting = null;\n    let detail = \"\";\n\n    if(method === \"karvonen\"){\n      resting = Number(restEl.value);\n      if(!Number.isFinite(resting) || resting <= 0){\n        setError(\"Enter a valid resting heart rate (bpm) for Karvonen.\");\n        resEl.hidden = true;\n        return;\n      }\n      if(resting >= maxHR){\n        setError(\"Resting HR must be lower than estimated max HR.\");\n        resEl.hidden = true;\n        return;\n      }\n      detail = `Karvonen method: Target HR = resting + (max \u2212 resting) \u00d7 intensity`;\n    } else {\n      detail = `Simple method: Zone ranges are % of estimated max HR`;\n    }\n\n    maxEl.textContent = `${round(maxHR)} bpm`;\n    maxNoteEl.textContent = `Estimated as 220 \u2212 ${round(age)} = ${round(maxHR)} bpm`;\n    detailEl.textContent = detail;\n\n    \/\/ Build table\n    tbodyEl.innerHTML = \"\";\n\n    for(const z of ZONES){\n      let low, high;\n\n      if(method === \"karvonen\"){\n        const hrr = maxHR - resting;\n        low = resting + hrr * z.pctLow;\n        high = resting + hrr * z.pctHigh;\n      } else {\n        low = maxHR * z.pctLow;\n        high = maxHR * z.pctHigh;\n      }\n\n      const tr = document.createElement(\"tr\");\n      tr.innerHTML = `\n        <td><strong>${z.z}<\/strong><\/td>\n        <td>${z.label}<\/td>\n        <td>${round(low)} \u2013 ${round(high)} bpm<\/td>\n      `;\n      tbodyEl.appendChild(tr);\n    }\n\n    resEl.hidden = false;\n  }\n\n  function reset(){\n    methodEl.value = \"simple\";\n    ageEl.value = \"\";\n    restEl.value = \"\";\n    setError(\"\");\n    resEl.hidden = true;\n    setUI();\n  }\n\n  methodEl.addEventListener(\"change\", setUI);\n  calcBtn.addEventListener(\"click\", calculate);\n  resetBtn.addEventListener(\"click\", reset);\n\n  setUI();\n})();\n<\/script>\n\n","protected":false},"excerpt":{"rendered":"<p>Heart Rate Zones Calculator Estimate heart rate training zones using either a simple max HR formula or the Karvonen (HRR) method. Methodtype Simple (220 \u2212 age)Karvonen (HRR) Karvonen uses resting&hellip;<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":2452,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_sitemap_exclude":false,"_sitemap_priority":"","_sitemap_frequency":"","footnotes":""},"_links":{"self":[{"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/pages\/2408"}],"collection":[{"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bio-me.bio\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2408"}],"version-history":[{"count":1,"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/pages\/2408\/revisions"}],"predecessor-version":[{"id":2409,"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/pages\/2408\/revisions\/2409"}],"up":[{"embeddable":true,"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/pages\/2452"}],"wp:attachment":[{"href":"https:\/\/bio-me.bio\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2408"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}