Accessibility / Structure & Headings / Fieldset Legend Checker
The Fieldset/Legend Checker bookmarklet validates that groups of related radio and checkbox inputs are properly wrapped in fieldset elements with descriptive legends. Finds all radio and checkbox inputs, groups them by name attribute, checks if each group is wrapped in a fieldset, and verifies the presence of a legend element with descriptive text. Displays a panel showing each group's statusāpassing groups (fieldset + legend) in green, failing groups in red. Click any group to highlight its inputs on the page. Run again to remove.
WCAG SC 1.3.1: Info and RelationshipsWCAG SC 3.3.2: Labels or Instructions
Run Fieldset Legend Checker
Test run or drag to
bookmarklets bar to install
javascript:%21function()%7B%22use%20strict%22%3Btry%7Bconst%20e%3Ddocument.getElementById(%22fieldset-checker-host%22)%3Be%26%26e.remove()%3Bconst%20n%3Ddocument.getElementById(%22fsc-highlight-style%22)%3Bn%26%26n.remove()%3Bdocument.querySelectorAll(%22.fsc-highlight%2C%20.fsc-missing%2C%20.fsc-good%22).forEach(e%3D%3E%7Be.classList.remove(%22fsc-highlight%22%2C%22fsc-missing%22%2C%22fsc-good%22)%7D)%3Bconst%20t%3DArray.from(document.querySelectorAll(%27input%5Btype%3D%22radio%22%5D%2C%20input%5Btype%3D%22checkbox%22%5D%27))%3Bif(0%3D%3D%3Dt.length)return%20void%20alert(%22No%20radio%20or%20checkbox%20inputs%20found%20on%20this%20page.%22)%3Bconst%20s%3Ddocument.createElement(%22div%22)%3Bs.id%3D%22fieldset-checker-host%22%2Cs.style.cssText%3D%22position%3Afixed%3Btop%3A10px%3Bright%3A10px%3Bz-index%3A999999%3Bwidth%3A450px%3Bmax-height%3A85vh%3B%22%2Cdocument.body.appendChild(s)%3Bconst%20o%3Ds.attachShadow(%7Bmode%3A%22open%22%7D)%2Ci%3Ddocument.createElement(%22style%22)%3Bi.textContent%3D%22%5Cn%20%20%20%20%20%20*%20%7B%20box-sizing%3A%20border-box%3B%20%7D%5Cn%20%20%20%20%20%20.fsc-panel%20%7B%5Cn%20%20%20%20%20%20%20%20font-family%3A%20-apple-system%2C%20BlinkMacSystemFont%2C%20%27Segoe%20UI%27%2C%20Roboto%2C%20sans-serif%3B%5Cn%20%20%20%20%20%20%20%20background%3A%20white%3B%5Cn%20%20%20%20%20%20%20%20border%3A%202px%20solid%20%23333%3B%5Cn%20%20%20%20%20%20%20%20border-radius%3A%208px%3B%5Cn%20%20%20%20%20%20%20%20box-shadow%3A%200%204px%2020px%20rgba(0%2C0%2C0%2C0.3)%3B%5Cn%20%20%20%20%20%20%20%20display%3A%20flex%3B%5Cn%20%20%20%20%20%20%20%20flex-direction%3A%20column%3B%5Cn%20%20%20%20%20%20%20%20max-height%3A%2085vh%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-header%20%7B%5Cn%20%20%20%20%20%20%20%20background%3A%20%23333%3B%5Cn%20%20%20%20%20%20%20%20color%3A%20white%3B%5Cn%20%20%20%20%20%20%20%20padding%3A%2012px%2016px%3B%5Cn%20%20%20%20%20%20%20%20display%3A%20flex%3B%5Cn%20%20%20%20%20%20%20%20justify-content%3A%20space-between%3B%5Cn%20%20%20%20%20%20%20%20align-items%3A%20center%3B%5Cn%20%20%20%20%20%20%20%20border-radius%3A%206px%206px%200%200%3B%5Cn%20%20%20%20%20%20%20%20flex-shrink%3A%200%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-title%20%7B%5Cn%20%20%20%20%20%20%20%20font-weight%3A%20600%3B%5Cn%20%20%20%20%20%20%20%20font-size%3A%200.875rem%3B%5Cn%20%20%20%20%20%20%20%20margin%3A%200%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-close%20%7B%5Cn%20%20%20%20%20%20%20%20background%3A%20none%3B%5Cn%20%20%20%20%20%20%20%20border%3A%20none%3B%5Cn%20%20%20%20%20%20%20%20color%3A%20white%3B%5Cn%20%20%20%20%20%20%20%20font-size%3A%201.25rem%3B%5Cn%20%20%20%20%20%20%20%20cursor%3A%20pointer%3B%5Cn%20%20%20%20%20%20%20%20padding%3A%200%3B%5Cn%20%20%20%20%20%20%20%20width%3A%2028px%3B%5Cn%20%20%20%20%20%20%20%20height%3A%2028px%3B%5Cn%20%20%20%20%20%20%20%20display%3A%20flex%3B%5Cn%20%20%20%20%20%20%20%20align-items%3A%20center%3B%5Cn%20%20%20%20%20%20%20%20justify-content%3A%20center%3B%5Cn%20%20%20%20%20%20%20%20border-radius%3A%204px%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-close%3Ahover%20%7B%5Cn%20%20%20%20%20%20%20%20background%3A%20rgba(255%2C255%2C255%2C0.2)%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-content%20%7B%5Cn%20%20%20%20%20%20%20%20padding%3A%2016px%3B%5Cn%20%20%20%20%20%20%20%20overflow-y%3A%20auto%3B%5Cn%20%20%20%20%20%20%20%20flex%3A%201%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-summary%20%7B%5Cn%20%20%20%20%20%20%20%20background%3A%20%23f5f5f5%3B%5Cn%20%20%20%20%20%20%20%20padding%3A%2012px%3B%5Cn%20%20%20%20%20%20%20%20border-radius%3A%206px%3B%5Cn%20%20%20%20%20%20%20%20margin-bottom%3A%2016px%3B%5Cn%20%20%20%20%20%20%20%20font-size%3A%200.8125rem%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-summary%20strong%20%7B%5Cn%20%20%20%20%20%20%20%20display%3A%20block%3B%5Cn%20%20%20%20%20%20%20%20margin-bottom%3A%208px%3B%5Cn%20%20%20%20%20%20%20%20font-size%3A%200.875rem%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-group%20%7B%5Cn%20%20%20%20%20%20%20%20background%3A%20white%3B%5Cn%20%20%20%20%20%20%20%20border%3A%201px%20solid%20%23ddd%3B%5Cn%20%20%20%20%20%20%20%20border-radius%3A%206px%3B%5Cn%20%20%20%20%20%20%20%20padding%3A%2012px%3B%5Cn%20%20%20%20%20%20%20%20margin-bottom%3A%2012px%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-group-header%20%7B%5Cn%20%20%20%20%20%20%20%20font-weight%3A%20600%3B%5Cn%20%20%20%20%20%20%20%20font-size%3A%200.8125rem%3B%5Cn%20%20%20%20%20%20%20%20margin-bottom%3A%208px%3B%5Cn%20%20%20%20%20%20%20%20padding-bottom%3A%208px%3B%5Cn%20%20%20%20%20%20%20%20border-bottom%3A%201px%20solid%20%23eee%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-group-item%20%7B%5Cn%20%20%20%20%20%20%20%20padding%3A%206px%208px%3B%5Cn%20%20%20%20%20%20%20%20margin%3A%202px%200%3B%5Cn%20%20%20%20%20%20%20%20border-radius%3A%204px%3B%5Cn%20%20%20%20%20%20%20%20font-size%3A%200.75rem%3B%5Cn%20%20%20%20%20%20%20%20display%3A%20flex%3B%5Cn%20%20%20%20%20%20%20%20align-items%3A%20center%3B%5Cn%20%20%20%20%20%20%20%20cursor%3A%20pointer%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-group-item%3Ahover%20%7B%5Cn%20%20%20%20%20%20%20%20background%3A%20%23f5f5f5%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-group-item.pass%20%7B%5Cn%20%20%20%20%20%20%20%20background%3A%20%23e6ffed%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-group-item.fail%20%7B%5Cn%20%20%20%20%20%20%20%20background%3A%20%23ffe6e6%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-label%20%7B%5Cn%20%20%20%20%20%20%20%20flex%3A%201%3B%5Cn%20%20%20%20%20%20%20%20white-space%3A%20nowrap%3B%5Cn%20%20%20%20%20%20%20%20overflow%3A%20hidden%3B%5Cn%20%20%20%20%20%20%20%20text-overflow%3A%20ellipsis%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-status%20%7B%5Cn%20%20%20%20%20%20%20%20font-weight%3A%20600%3B%5Cn%20%20%20%20%20%20%20%20margin-left%3A%208px%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-status.pass%20%7B%20color%3A%20%2328a745%3B%20%7D%5Cn%20%20%20%20%20%20.fsc-status.fail%20%7B%20color%3A%20%23dc3545%3B%20%7D%5Cn%20%20%20%20%20%20.fsc-legend-text%20%7B%5Cn%20%20%20%20%20%20%20%20font-size%3A%200.6875rem%3B%5Cn%20%20%20%20%20%20%20%20color%3A%20%23666%3B%5Cn%20%20%20%20%20%20%20%20margin-left%3A%204px%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-empty-section%20%7B%5Cn%20%20%20%20%20%20%20%20color%3A%20%23999%3B%5Cn%20%20%20%20%20%20%20%20font-style%3A%20italic%3B%5Cn%20%20%20%20%20%20%20%20padding%3A%2012px%3B%5Cn%20%20%20%20%20%20%20%20text-align%3A%20center%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-highlight-group%20%7B%5Cn%20%20%20%20%20%20%20%20cursor%3A%20pointer%3B%5Cn%20%20%20%20%20%20%20%20transition%3A%20background%200.2s%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20.fsc-highlight-group%3Ahover%20%7B%5Cn%20%20%20%20%20%20%20%20background%3A%20%23f0f0f0%3B%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%22%2Co.appendChild(i)%3Bconst%20l%3Ddocument.createElement(%22div%22)%3Bl.className%3D%22fsc-panel%22%2Co.appendChild(l)%3Bconst%20r%3D%7B%7D%3Bt.forEach(e%3D%3E%7Bconst%20n%3De.getAttribute(%22name%22)%7C%7C%22__unnamed__%22%3Br%5Bn%5D%7C%7C(r%5Bn%5D%3D%7Bname%3An%2Ctype%3Ae.type%2Cinputs%3A%5B%5D%2ChasFieldset%3A%211%2ChasLegend%3A%211%2ClegendText%3Anull%2CfieldsetElement%3Anull%7D)%2Cr%5Bn%5D.inputs.push(e)%7D)%3Blet%20c%3D0%2Cd%3D0%2Ca%3D0%3Bconst%20p%3D%5B%5D%3BObject.values(r).forEach(e%3D%3E%7Bc%2B%2B%3Blet%20n%3De.inputs%5B0%5D.closest(%22fieldset%22)%3Bif(n)%7Be.hasFieldset%3D%210%2Ce.fieldsetElement%3Dn%2Cd%2B%2B%3Bconst%20t%3Dn.querySelector(%22legend%22)%3Bt%26%26t.textContent.trim()%26%26(e.hasLegend%3D%210%2Ce.legendText%3Dt.textContent.trim()%2Ca%2B%2B)%7Dp.push(%7B...e%2Cpassed%3Ae.hasFieldset%26%26e.hasLegend%7D)%7D)%3Bp.filter(e%3D%3Ee.passed).length%2Cp.filter(e%3D%3E%21e.passed).length%3Blet%20f%3D%60%5Cn%20%20%20%20%20%20%3Cdiv%20class%3D%22fsc-header%22%3E%5Cn%20%20%20%20%20%20%20%20%3Ch2%20class%3D%22fsc-title%22%3EFieldset%2FLegend%20Checker%3C%2Fh2%3E%5Cn%20%20%20%20%20%20%20%20%3Cbutton%20class%3D%22fsc-close%22%20aria-label%3D%22Close%22%20onclick%3D%22cleanupAndClose()%22%3E%26times%3B%3C%2Fbutton%3E%5Cn%20%20%20%20%20%20%3C%2Fdiv%3E%5Cn%20%20%20%20%20%20%3Cdiv%20class%3D%22fsc-content%22%3E%5Cn%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22fsc-summary%22%3E%5Cn%20%20%20%20%20%20%20%20%20%20%3Cstrong%3ESummary%3A%3C%2Fstrong%3E%5Cn%20%20%20%20%20%20%20%20%20%20Found%20%24%7Bt.length%7D%20input(s)%20in%20%24%7Bc%7D%20group(s)%3Cbr%3E%5Cn%20%20%20%20%20%20%20%20%20%20%3Cspan%20style%3D%22color%3A%24%7Bd%3D%3D%3Dc%3F%22%2328a745%22%3A%22%23dc3545%22%7D%22%3E%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%24%7Bd%7D%2F%24%7Bc%7D%20groups%20have%20fieldset%5Cn%20%20%20%20%20%20%20%20%20%20%3C%2Fspan%3E%3Cbr%3E%5Cn%20%20%20%20%20%20%20%20%20%20%3Cspan%20style%3D%22color%3A%24%7Ba%3D%3D%3Dc%3F%22%2328a745%22%3A%22%23dc3545%22%7D%22%3E%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%24%7Ba%7D%2F%24%7Bc%7D%20groups%20have%20legend%5Cn%20%20%20%20%20%20%20%20%20%20%3C%2Fspan%3E%5Cn%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%5Cn%20%20%20%20%60%3Bp.length%3E0%26%26p.forEach((e%2Cn)%3D%3E%7Bconst%20t%3De.passed%3F%22pass%22%3A%22fail%22%2Cs%3De.passed%3F%22%5Cu2713%20PASS%22%3A%22%5Cu2717%20FAIL%22%2Co%3De.passed%3F%22pass%22%3A%22fail%22%3Bf%2B%3D%60%5Cn%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22fsc-group%20fsc-highlight-group%22%20data-group-index%3D%22%24%7Bn%7D%22%20onclick%3D%22highlightGroup(%24%7Bn%7D)%22%3E%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22fsc-group-header%22%3E%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%7B%22__unnamed__%22%3D%3D%3De.name%3F%22(unnamed%20group)%22%3A%27Group%3A%20%22%27%2Be.name%2B%27%22%27%7D%20(%24%7Be.inputs.length%7D%20%24%7Be.type%7D%24%7Be.inputs.length%3E1%3F%22s%22%3A%22%22%7D)%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%5Cn%20%20%20%20%20%20%20%20%60%2Ce.inputs.forEach(e%3D%3E%7Bconst%20n%3Dh(e)%3Bf%2B%3D%60%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22fsc-group-item%20%24%7Bt%7D%22%3E%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class%3D%22fsc-label%22%3E%24%7Bn%7C%7C%22(no%20label)%22%7D%3C%2Fspan%3E%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class%3D%22fsc-status%20%24%7Bo%7D%22%3E%24%7Bs%7D%3C%2Fspan%3E%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%5Cn%20%20%20%20%20%20%20%20%20%20%60%7D)%2Ce.hasFieldset%3Ff%2B%3D%60%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20style%3D%22font-size%3A0.6875rem%3Bcolor%3A%2328a745%3Bmargin-top%3A4px%3Bpadding%3A4px%208px%3Bbackground%3A%23e6ffed%3Bborder-radius%3A4px%22%3E%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5Cu2713%20Wrapped%20in%20fieldset%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24%7Be.hasLegend%3F%60%3Cbr%3E%5Cu2713%20Legend%3A%20%22%24%7Be.legendText%7D%22%60%3A%22%3Cbr%3E%5Cu2717%20Missing%20legend%22%7D%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%5Cn%20%20%20%20%20%20%20%20%20%20%60%3Af%2B%3D%27%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20style%3D%22font-size%3A0.6875rem%3Bcolor%3A%23dc3545%3Bmargin-top%3A4px%3Bpadding%3A4px%208px%3Bbackground%3A%23ffe6e6%3Bborder-radius%3A4px%22%3E%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5Cu2717%20Not%20wrapped%20in%20fieldset%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%5Cn%20%20%20%20%20%20%20%20%20%20%27%2Cf%2B%3D%22%3C%2Fdiv%3E%22%7D)%2Cf%2B%3D%22%3C%2Fdiv%3E%22%2Cl.innerHTML%3Df%3Bconst%20g%3Ddocument.createElement(%22style%22)%3Bfunction%20h(e)%7Bif(e.id)%7Bconst%20n%3Ddocument.querySelector(%60label%5Bfor%3D%22%24%7Be.id%7D%22%5D%60)%3Bif(n)return%20n.textContent.trim()%7Dconst%20n%3De.closest(%22label%22)%3Breturn%20n%3Fn.textContent.trim()%3Ae.getAttribute(%22aria-label%22)%3Fe.getAttribute(%22aria-label%22)%3Ae.getAttribute(%22placeholder%22)%3Fe.getAttribute(%22placeholder%22)%3Ae.value%3Fe.value%3A%60(input%20%24%7Be.type%7D)%60%7Dg.id%3D%22fsc-highlight-style%22%2Cg.textContent%3D%22%5Cn%20%20%20%20%20%20.fsc-highlight%20%7B%20outline%3A%203px%20solid%20%23ffc107%20%21important%3B%20outline-offset%3A%202px%20%21important%3B%20%7D%5Cn%20%20%20%20%20%20.fsc-missing%20%7B%20outline%3A%203px%20solid%20%23dc3545%20%21important%3B%20outline-offset%3A%202px%20%21important%3B%20%7D%5Cn%20%20%20%20%20%20.fsc-good%20%7B%20outline%3A%203px%20solid%20%2328a745%20%21important%3B%20outline-offset%3A%202px%20%21important%3B%20%7D%5Cn%20%20%20%20%22%2Cdocument.head.appendChild(g)%2Cwindow.fscGroups%3Dp%2Cwindow.highlightGroup%3Dfunction(e)%7Bdocument.querySelectorAll(%22.fsc-highlight%2C%20.fsc-missing%2C%20.fsc-good%22).forEach(e%3D%3E%7Be.classList.remove(%22fsc-highlight%22%2C%22fsc-missing%22%2C%22fsc-good%22)%7D)%3Bconst%20n%3Dwindow.fscGroups%5Be%5D%3Bn%26%26(n.inputs.forEach((e%2Ct)%3D%3E%7Bn.passed%3Fe.classList.add(%22fsc-good%22)%3Ae.classList.add(%22fsc-missing%22)%2C0%3D%3D%3Dt%26%26e.scrollIntoView(%7Bbehavior%3A%22smooth%22%2Cblock%3A%22center%22%7D)%7D)%2Cn.fieldsetElement%26%26n.fieldsetElement.classList.add(%22fsc-highlight%22)%2CsetTimeout(()%3D%3E%7Bdocument.querySelectorAll(%22.fsc-highlight%2C%20.fsc-missing%2C%20.fsc-good%22).forEach(e%3D%3E%7Be.classList.remove(%22fsc-highlight%22%2C%22fsc-missing%22%2C%22fsc-good%22)%7D)%7D%2C3e3))%7D%2Cwindow.cleanupAndClose%3Dfunction()%7Bdocument.getElementById(%22fieldset-checker-host%22)%3F.remove()%2Cdocument.getElementById(%22fsc-highlight-style%22)%3F.remove()%2Cdocument.querySelectorAll(%22.fsc-highlight%2C%20.fsc-missing%2C%20.fsc-good%22).forEach(e%3D%3E%7Be.classList.remove(%22fsc-highlight%22%2C%22fsc-missing%22%2C%22fsc-good%22)%7D)%2Cdelete%20window.fscGroups%2Cdelete%20window.highlightGroup%2Cdelete%20window.cleanupAndClose%7D%2Cconsole.log(%22%5BFieldset%2FLegend%20Checker%5D%20-%20Analysis%20complete%22)%7Dcatch(u)%7Balert(%22Bookmarklet%20Error%3A%20%22%2Bu.message)%7D%7D()%2Cconsole.log(%22%5CnSource%3A%20https%3A%2F%2Fgithub.com%2Fpattespatte%2Fpublic-bookmarklets%2F%5CnBookmarklet%20name%3A%20Fieldset%2FLegend%20Checker%5Cn%22)%3B
ā Back to all bookmarklets