Skip to content

Documentation

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.

Sizes are minified and gzip. A plugin figure includes the Bootstrap runtime that plugin imports. Shipping every plugin is bootstrap.bundle.min.js at 23.3 KB gzip, not the sum of these rows.
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
Markup this component accepts. The full inventory is /components.json.
Avoid
  • Do not add a pe-count or pe-checked element. The output is already a status live region.
  • data-controls is a container id, with no # and no CSS selector. :checked does not belong in the attribute.
  • Do not watch the checked attribute with a MutationObserver. Listen to change.
  • Do not lift .form-check-input out of a closed popover to feed a CSS counter. Closed popovers are not in the tab order.
  • Do not put the output inside a toggle button. The count would be announced twice.

How it works

  • data-controls is a container id, with no # — the same shape as commandfor. The script queries input[type=checkbox] inside that node.
  • for lists the contributing control ids. That is the accessible association. The live group is data-controls.
  • The module listens to change, not a MutationObserver. Observer sees the checked attribute, so a click and el.checked = true would miss.
  • Visible checkboxes can use a CSS counter instead. A closed popover is display: 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.

Notify me 1 selected
HTML
<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

Three columns, not one baseline. The same row is on the overview.
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.