On this page
Output
<output> is the result of a user action. Optional
src/behaviors/count.js fills
<output data-controls> with how many checkboxes
in that container are checked. It is not a pe-*
element. A dropdown recipe that uses the same contract lives on
Composed examples.
| What runs it | JavaScript | |
|---|---|---|
| Bootstrap 5.3 | No equivalent. A badge or span updated from a change listener. | Not in bootstrap.min.js |
| This repo | `<output>`. Optional `src/behaviors/count.js` for `data-controls` | 0 KB. Optional src/behaviors/count.js |
| Avoid |
|
|---|
How it works
-
data-controlsis a container id, with no#— the same shape ascommandfor. The script queriesinput[type=checkbox]inside that node. -
forlists the contributing control ids. That is the accessible association. The live group isdata-controls. -
The module listens to
change, not a MutationObserver. Observer sees thecheckedattribute, so a click andel.checked = truewould miss. -
Visible checkboxes can use a CSS
counterinstead. A closedpopoverisdisplay: none, so that path fails there — load the module for that case. - Without the script the controls still work. The output stays at whatever was in the markup.
On a fieldset
Toggle the boxes. The number in the legend updates. There is no dropdown.
<script type="module" src="./node_modules/bootstrap-html/src/behaviors/count.js"></script>
<fieldset>
<legend>
Notify me
<output id="output-notify-count" class="ms-1 badge rounded-pill text-bg-secondary" data-controls="output-notify" for="output-notify-email output-notify-sms">1<span class="visually-hidden"> selected</span></output>
</legend>
<div id="output-notify">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="email" id="output-notify-email" checked>
<label class="form-check-label" for="output-notify-email">Email</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="sms" id="output-notify-sms">
<label class="form-check-label" for="output-notify-sms">SMS</label>
</div>
</div>
</fieldset> Accessibility
<output> is a status live region. Keep it beside the control, not inside a button name.
for lists the contributing control ids. data-controls is the live group count.js queries.
On a dropdown toggle, aria-describedby points at the output so the button name stays the action.
Browser support
| No script | Polyfill | No fallback |
|---|---|---|
<output> is Baseline Widely available. Without count.js the text stays at whatever was in the markup. | None | A closed popover is display: none, so a CSS counter inside that menu stays 0. count.js is the exception for that case. Visible checkboxes can use :has() and counter() without it. |