Connection lost. Reconnecting… attempt 1 of 8
Paused. Your work is held on the server.
Could not reconnect.
This session has expired on the server.
DR.Simple_UI
Showing main. This can be ahead of the version your app has installed — check what a class says it needs before copying it. Releases (opens in a new tab)

Button groups

tier 2 — classes

Two or more buttons that act on the same thing, joined so they read as one control. The variants of a single button — icon-only, ghost, small, the FAB — are on the Buttons page.

A group is not a way to pick one of several. That is .segmented, which is built from radios and is therefore announced as a choice. A group is several actions. Wrap it in role="group" with an aria-label saying what they act on.

Button group

One shared border between neighbours rather than two adjacent ones, which is what makes it read as one control instead of a row. The hovered or focused button paints above its neighbour, or half its ring and its darker border edge would be covered.

<div class="dr-col">
    <div class="btn-group" role="group" aria-label="Order actions">
        <button class="btn" type="button"><i class="ri-arrow-left-line"></i> Previous</button>
        <button class="btn" type="button">Next <i class="ri-arrow-right-line"></i></button>
    </div>
    <div class="btn-group" role="group" aria-label="Zoom">
        <button class="btn btn-icon" type="button" aria-label="Zoom out">&minus;</button>
        <button class="btn" type="button">100%</button>
        <button class="btn btn-icon" type="button" aria-label="Zoom in">+</button>
    </div>
</div>

Split button

A primary action plus a menu of its variants. Two real buttons, not one with a hit-test: the main action must be operable without ever opening the menu, and the caret needs its own accessible name and its own aria-expanded.

Between two filled buttons of the same colour the shared edge disappears, so the split is drawn as a lighter inset line instead.

<div class="dr-row-wrap">
    <div class="split-btn">
        <button class="btn btn-go" type="button"><i class="ri-send-plane-line"></i> Send reply</button>
        <button class="btn btn-go" type="button" aria-label="More send options" aria-expanded="false">
            <i class="ri-arrow-down-s-line"></i>
        </button>
    </div>
    <div class="split-btn">
        <button class="btn" type="button">Export</button>
        <button class="btn" type="button" aria-label="More export formats" aria-expanded="false">
            <i class="ri-arrow-down-s-line"></i>
        </button>
    </div>
</div>

A split button that opens a menu

Live — open it. Wrap the split button and its panel in .menu-anchor, put data-menu-toggle on the caret, and DR.Simple_UI.js handles the rest: one menu open at a time, a click outside or Escape closes it, and focus returns to the caret. The hidden attribute is the closed state, so the panel is out of the tab order while it is shut.

The primary action stays operable without ever opening the menu. Put the destructive variant in the panel with .menu-item--danger, never as the caret's neighbour.

The panel carries .menu--start because the trigger is at the leading edge of its row. A panel is 220px at its narrowest and hangs off the anchor's trailing edge by default, so without the modifier it overhangs into whatever is to the left of the split button. Leave it off for a trigger at the trailing end of a row.

<div class="menu-anchor">
    <div class="split-btn">
        <button class="btn btn-go" type="button"><i class="ri-send-plane-line"></i> Dispatch</button>
        <button class="btn btn-go" type="button" data-menu-toggle
                aria-label="More dispatch options" aria-expanded="false">
            <i class="ri-arrow-down-s-line"></i>
        </button>
    </div>
    <div class="menu menu--start" hidden>
        <span class="menu-label">Dispatch as</span>
        <button class="menu-item" type="button">
            <i class="ri-truck-line"></i> Standard
            <span class="menu-item-note">3–5 days</span>
        </button>
        <button class="menu-item" type="button">
            <i class="ri-flashlight-line"></i> Express
            <span class="menu-item-note">Next day</span>
        </button>
        <hr class="menu-sep" />
        <button class="menu-item menu-item--danger" type="button">
            <i class="ri-close-circle-line"></i> Cancel the order
        </button>
    </div>
</div>

Three sizes

Add .btn-sm or .btn-lg to every button in the group — the group itself carries no tier. Each button then takes the matching control height, so a group lines up with the chip, field or button beside it at the same size.

4 of 128
4 of 128
<div class="dr-col dr-gap-2">
    <div class="dr-row-wrap">
        <div class="btn-group" role="group" aria-label="Small — page through the order">
            <button class="btn btn-sm" type="button"><i class="ri-arrow-left-line"></i> Previous</button>
            <button class="btn btn-sm" type="button">Next <i class="ri-arrow-right-line"></i></button>
        </div>
        <span class="chip"><span class="chip-label">4 of 128</span></span>
    </div>
    <div class="dr-row-wrap">
        <div class="btn-group" role="group" aria-label="Page through the order">
            <button class="btn" type="button"><i class="ri-arrow-left-line"></i> Previous</button>
            <button class="btn" type="button">Next <i class="ri-arrow-right-line"></i></button>
        </div>
        <span class="chip chip-lg"><span class="chip-label">4 of 128</span></span>
    </div>
    <div class="dr-row-wrap">
        <div class="btn-group" role="group" aria-label="Large — page through the order">
            <button class="btn btn-lg" type="button"><i class="ri-arrow-left-line"></i> Previous</button>
            <button class="btn btn-lg" type="button">Next <i class="ri-arrow-right-line"></i></button>
        </div>
        <input class="form-input form-input-lg" type="text" value="ORD-4209" aria-label="Order number" style="max-width:140px" />
    </div>
</div>