Mark · Components

Button group vs Bootstrap

Both systems have a class that says "these buttons belong together." They disagree about what saying it should do — and this theme spent years on Bootstrap's side of that disagreement, routing around its own group component with utility wrappers.


The base

Belonging, on most pages, looks like buttons side by side with air between them. That is what mk-btn-group renders, so the semantic name and the common case finally point at the same thing. Bootstrap's btn-group renders a fused segmented control instead — a visual treatment wearing a semantic name — which is why this theme never used it: every grouped pair was a hand-assembled d-flex gap-3, the meaning left in the author's head.

mk-btn-group — say "these belong together" and this is what you get.

btn-group — say the same thing to Bootstrap and the buttons join.

d-flex gap-3 — so this theme said it with utilities instead, four times, by hand.

Asked for

The joined look is real — view switchers want it. Here it is a modifier you request, not the price of grouping. And the name stops at the geometry on purpose: a segmented control is a kind of control — an exclusive choice — and it is drawn joined, but so are plain actions that simply belong tight together. The look is a class; the control is which partial you reach for. When a member carries state, it says aria-pressed, which the stylesheet paints because it is true, where Bootstrap's .active is paint only. The mode control in this site's own header is the joined look on plain actions, live: a toggle and its menu, drawn as one piece, with no exclusive choice anywhere in it.

mk-btn-group--join — the joined look, asked for; the pressed one says so to the platform.

btn-group + .active — the same look; the state is a styling class only Bootstrap can hear.

Axes, not names

Bootstrap mints a name per situation — five classes and a state around one idea, because direction, size, and selection each fuse into the component instead of staying on their own axis.

btn-group The block — and the fused look, inseparably.
btn-group-vertical Direction as a second component name.
btn-group-lg Size restated on the wrapper, though the buttons already have sizes.
btn-toolbar A group of groups, with its own name too.
.active
Selection as a styling class — invisible to assistive tech.

Mark keeps the block on one name with two modifiers. Size is not among them: a group arranges, a button sizes, so size rides the buttons — the partial applies it to every member, and no mk-btn-group--lg needs to exist.

mk-btn-group The block. Belonging, drawn as proximity.
mk-btn-group--join Geometry only: the gap collapses, the seams merge.
mk-btn-group--stack Direction as a modifier of the same block.
aria-pressed
Selection in the platform’s own vocabulary — styled because it is true.

Named or silent

role="group" earns its keep only with an accessible name — an unnamed group is noise in a screen reader, not help. So the partial makes the name the switch: give it a label and it announces itself, omit the label and it stays a plain div. Bootstrap's documentation assigns the same work as homework at every call site, which is how unnamed role="group"s ship.