Group related toggle buttons using Bootstrap's native checkbox and radio button-check contract.
Use grouped .btn-check inputs with matching .btn labels when related button-like choices need a persistent pressed state. Use radio inputs when exactly one item should stay active, and checkbox inputs when multiple items may be pressed at the same time.
.btn-check
.btn
Group the controls under one accessible label, keep every item the same size and variant, and make the selected state visible without relying on color alone. Give every icon-only toggle its own accessible label because the icon is not a name.
Toggle Group uses Bootstrap's button-check contract: native inputs hold the state while labels render the button surface. Keep values stable for form submission, and choose a normal Button Group when the controls are actions rather than selectable modes.
Independent checkbox items let more than one stay pressed at once.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32<div class="toggle-group d-inline-flex gap-2" role="group" aria-label="Notification channels"> <input type="checkbox" class="btn-check" name="notification-channels" id="notify-email" value="notify-email" autocomplete="off" aria-label="Email"> <label class="btn btn-ghost btn-icon" for="notify-email"> <i class="lucide lucide-mail" data-icon="inline-start" aria-hidden="true"></i> </label> <input type="checkbox" class="btn-check" name="notification-channels" id="notify-sms" value="notify-sms" autocomplete="off" aria-label="SMS" checked> <label class="btn btn-ghost btn-icon" for="notify-sms"> <i class="lucide lucide-message-square" data-icon="inline-start" aria-hidden="true"></i> </label> <input type="checkbox" class="btn-check" name="notification-channels" id="notify-push" value="notify-push" autocomplete="off" aria-label="Push"> <label class="btn btn-ghost btn-icon" for="notify-push"> <i class="lucide lucide-bell" data-icon="inline-start" aria-hidden="true"></i> </label> </div>
<div class="toggle-group d-inline-flex gap-2" role="group" aria-label="Notification channels"> <input type="checkbox" class="btn-check" name="notification-channels" id="notify-email" value="notify-email" autocomplete="off" aria-label="Email"> <label class="btn btn-ghost btn-icon" for="notify-email"> <i class="lucide lucide-mail" data-icon="inline-start" aria-hidden="true"></i> </label> <input type="checkbox" class="btn-check" name="notification-channels" id="notify-sms" value="notify-sms" autocomplete="off" aria-label="SMS" checked> <label class="btn btn-ghost btn-icon" for="notify-sms"> <i class="lucide lucide-message-square" data-icon="inline-start" aria-hidden="true"></i> </label> <input type="checkbox" class="btn-check" name="notification-channels" id="notify-push" value="notify-push" autocomplete="off" aria-label="Push"> <label class="btn btn-ghost btn-icon" for="notify-push"> <i class="lucide lucide-bell" data-icon="inline-start" aria-hidden="true"></i> </label> </div>
Radio items share one name so exactly one method stays pressed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35<div class="toggle-group d-inline-flex gap-2" role="group" aria-label="Shipment method"> <input type="radio" class="btn-check" name="shipment-method" id="shipment-standard" value="shipment-standard" autocomplete="off" checked> <label class="btn btn-outline-secondary" for="shipment-standard"> <i class="lucide lucide-package" data-icon="inline-start" aria-hidden="true"></i> Standard </label> <input type="radio" class="btn-check" name="shipment-method" id="shipment-express" value="shipment-express" autocomplete="off"> <label class="btn btn-outline-secondary" for="shipment-express"> <i class="lucide lucide-zap" data-icon="inline-start" aria-hidden="true"></i> Express </label> <input type="radio" class="btn-check" name="shipment-method" id="shipment-overnight" value="shipment-overnight" autocomplete="off"> <label class="btn btn-outline-secondary" for="shipment-overnight"> <i class="lucide lucide-rocket" data-icon="inline-start" aria-hidden="true"></i> Overnight </label> </div>
<div class="toggle-group d-inline-flex gap-2" role="group" aria-label="Shipment method"> <input type="radio" class="btn-check" name="shipment-method" id="shipment-standard" value="shipment-standard" autocomplete="off" checked> <label class="btn btn-outline-secondary" for="shipment-standard"> <i class="lucide lucide-package" data-icon="inline-start" aria-hidden="true"></i> Standard </label> <input type="radio" class="btn-check" name="shipment-method" id="shipment-express" value="shipment-express" autocomplete="off"> <label class="btn btn-outline-secondary" for="shipment-express"> <i class="lucide lucide-zap" data-icon="inline-start" aria-hidden="true"></i> Express </label> <input type="radio" class="btn-check" name="shipment-method" id="shipment-overnight" value="shipment-overnight" autocomplete="off"> <label class="btn btn-outline-secondary" for="shipment-overnight"> <i class="lucide lucide-rocket" data-icon="inline-start" aria-hidden="true"></i> Overnight </label> </div>
size sets btn-sm/btn-lg directly on each item, the same scale a plain Button uses.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66<div class="d-flex flex-column gap-3 align-items-center"> <div class="toggle-group d-inline-flex gap-2" role="group" aria-label="Task priority"> <input type="radio" class="btn-check" name="task-priority-sm" id="priority-low-sm" value="priority-low-sm" autocomplete="off" aria-label="Low priority"> <label class="btn btn-ghost btn-icon-sm" for="priority-low-sm"> <i class="lucide lucide-arrow-down" data-icon="inline-start" aria-hidden="true"></i> </label> <input type="radio" class="btn-check" name="task-priority-sm" id="priority-medium-sm" value="priority-medium-sm" autocomplete="off" aria-label="Medium priority" checked> <label class="btn btn-ghost btn-icon-sm" for="priority-medium-sm"> <i class="lucide lucide-minus" data-icon="inline-start" aria-hidden="true"></i> </label> <input type="radio" class="btn-check" name="task-priority-sm" id="priority-high-sm" value="priority-high-sm" autocomplete="off" aria-label="High priority"> <label class="btn btn-ghost btn-icon-sm" for="priority-high-sm"> <i class="lucide lucide-arrow-up" data-icon="inline-start" aria-hidden="true"></i> </label> </div> <div class="toggle-group d-inline-flex gap-2" role="group" aria-label="Task priority"> <input type="radio" class="btn-check" name="task-priority-lg" id="priority-low-lg" value="priority-low-lg" autocomplete="off" aria-label="Low priority"> <label class="btn btn-ghost btn-icon-lg" for="priority-low-lg"> <i class="lucide lucide-arrow-down" data-icon="inline-start" aria-hidden="true"></i> </label> <input type="radio" class="btn-check" name="task-priority-lg" id="priority-medium-lg" value="priority-medium-lg" autocomplete="off" aria-label="Medium priority" checked> <label class="btn btn-ghost btn-icon-lg" for="priority-medium-lg"> <i class="lucide lucide-minus" data-icon="inline-start" aria-hidden="true"></i> </label> <input type="radio" class="btn-check" name="task-priority-lg" id="priority-high-lg" value="priority-high-lg" autocomplete="off" aria-label="High priority"> <label class="btn btn-ghost btn-icon-lg" for="priority-high-lg"> <i class="lucide lucide-arrow-up" data-icon="inline-start" aria-hidden="true"></i> </label> </div> </div>
<div class="d-flex flex-column gap-3 align-items-center"> <div class="toggle-group d-inline-flex gap-2" role="group" aria-label="Task priority"> <input type="radio" class="btn-check" name="task-priority-sm" id="priority-low-sm" value="priority-low-sm" autocomplete="off" aria-label="Low priority"> <label class="btn btn-ghost btn-icon-sm" for="priority-low-sm"> <i class="lucide lucide-arrow-down" data-icon="inline-start" aria-hidden="true"></i> </label> <input type="radio" class="btn-check" name="task-priority-sm" id="priority-medium-sm" value="priority-medium-sm" autocomplete="off" aria-label="Medium priority" checked> <label class="btn btn-ghost btn-icon-sm" for="priority-medium-sm"> <i class="lucide lucide-minus" data-icon="inline-start" aria-hidden="true"></i> </label> <input type="radio" class="btn-check" name="task-priority-sm" id="priority-high-sm" value="priority-high-sm" autocomplete="off" aria-label="High priority"> <label class="btn btn-ghost btn-icon-sm" for="priority-high-sm"> <i class="lucide lucide-arrow-up" data-icon="inline-start" aria-hidden="true"></i> </label> </div> <div class="toggle-group d-inline-flex gap-2" role="group" aria-label="Task priority"> <input type="radio" class="btn-check" name="task-priority-lg" id="priority-low-lg" value="priority-low-lg" autocomplete="off" aria-label="Low priority"> <label class="btn btn-ghost btn-icon-lg" for="priority-low-lg"> <i class="lucide lucide-arrow-down" data-icon="inline-start" aria-hidden="true"></i> </label> <input type="radio" class="btn-check" name="task-priority-lg" id="priority-medium-lg" value="priority-medium-lg" autocomplete="off" aria-label="Medium priority" checked> <label class="btn btn-ghost btn-icon-lg" for="priority-medium-lg"> <i class="lucide lucide-minus" data-icon="inline-start" aria-hidden="true"></i> </label> <input type="radio" class="btn-check" name="task-priority-lg" id="priority-high-lg" value="priority-high-lg" autocomplete="off" aria-label="High priority"> <label class="btn btn-ghost btn-icon-lg" for="priority-high-lg"> <i class="lucide lucide-arrow-up" data-icon="inline-start" aria-hidden="true"></i> </label> </div> </div>
A single item can be disabled without affecting its neighbors.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32<div class="toggle-group d-inline-flex gap-2" role="group" aria-label="Notification channels"> <input type="checkbox" class="btn-check" name="notification-channels-disabled" id="notify-email-disabled" value="notify-email-disabled" autocomplete="off" aria-label="Email"> <label class="btn btn-ghost btn-icon" for="notify-email-disabled"> <i class="lucide lucide-mail" data-icon="inline-start" aria-hidden="true"></i> </label> <input type="checkbox" class="btn-check" name="notification-channels-disabled" id="notify-sms-disabled" value="notify-sms-disabled" autocomplete="off" aria-label="SMS" checked> <label class="btn btn-ghost btn-icon" for="notify-sms-disabled"> <i class="lucide lucide-message-square" data-icon="inline-start" aria-hidden="true"></i> </label> <input type="checkbox" class="btn-check" name="notification-channels-disabled" id="notify-push-disabled" value="notify-push-disabled" autocomplete="off" aria-label="Push" disabled> <label class="btn btn-ghost btn-icon" for="notify-push-disabled"> <i class="lucide lucide-bell" data-icon="inline-start" aria-hidden="true"></i> </label> </div>
<div class="toggle-group d-inline-flex gap-2" role="group" aria-label="Notification channels"> <input type="checkbox" class="btn-check" name="notification-channels-disabled" id="notify-email-disabled" value="notify-email-disabled" autocomplete="off" aria-label="Email"> <label class="btn btn-ghost btn-icon" for="notify-email-disabled"> <i class="lucide lucide-mail" data-icon="inline-start" aria-hidden="true"></i> </label> <input type="checkbox" class="btn-check" name="notification-channels-disabled" id="notify-sms-disabled" value="notify-sms-disabled" autocomplete="off" aria-label="SMS" checked> <label class="btn btn-ghost btn-icon" for="notify-sms-disabled"> <i class="lucide lucide-message-square" data-icon="inline-start" aria-hidden="true"></i> </label> <input type="checkbox" class="btn-check" name="notification-channels-disabled" id="notify-push-disabled" value="notify-push-disabled" autocomplete="off" aria-label="Push" disabled> <label class="btn btn-ghost btn-icon" for="notify-push-disabled"> <i class="lucide lucide-bell" data-icon="inline-start" aria-hidden="true"></i> </label> </div>
vertical=true switches the flex container to a column and applies the shared vertical spacing token.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35<div class="toggle-group d-inline-flex gap-1 flex-column" role="group" aria-label="Approval stage"> <input type="radio" class="btn-check" name="approval-stage" id="approval-draft" value="approval-draft" autocomplete="off" checked> <label class="btn btn-ghost" for="approval-draft"> <i class="lucide lucide-pencil" data-icon="inline-start" aria-hidden="true"></i> Draft </label> <input type="radio" class="btn-check" name="approval-stage" id="approval-review" value="approval-review" autocomplete="off"> <label class="btn btn-ghost" for="approval-review"> <i class="lucide lucide-eye" data-icon="inline-start" aria-hidden="true"></i> Review </label> <input type="radio" class="btn-check" name="approval-stage" id="approval-approved" value="approval-approved" autocomplete="off"> <label class="btn btn-ghost" for="approval-approved"> <i class="lucide lucide-circle-check" data-icon="inline-start" aria-hidden="true"></i> Approved </label> </div>
<div class="toggle-group d-inline-flex gap-1 flex-column" role="group" aria-label="Approval stage"> <input type="radio" class="btn-check" name="approval-stage" id="approval-draft" value="approval-draft" autocomplete="off" checked> <label class="btn btn-ghost" for="approval-draft"> <i class="lucide lucide-pencil" data-icon="inline-start" aria-hidden="true"></i> Draft </label> <input type="radio" class="btn-check" name="approval-stage" id="approval-review" value="approval-review" autocomplete="off"> <label class="btn btn-ghost" for="approval-review"> <i class="lucide lucide-eye" data-icon="inline-start" aria-hidden="true"></i> Review </label> <input type="radio" class="btn-check" name="approval-stage" id="approval-approved" value="approval-approved" autocomplete="off"> <label class="btn btn-ghost" for="approval-approved"> <i class="lucide lucide-circle-check" data-icon="inline-start" aria-hidden="true"></i> Approved </label> </div>
Use the same shipment method options across Arabic and Hebrew RTL examples, with English as the LTR comparison.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37<div dir="rtl"> <div class="toggle-group d-inline-flex gap-2" role="group" aria-label="Shipment method"> <input type="radio" class="btn-check" name="shipment-method-rtl-arabic" id="shipment-standard-rtl-arabic" value="shipment-standard-rtl-arabic" autocomplete="off" checked> <label class="btn btn-outline-secondary" for="shipment-standard-rtl-arabic"> <i class="lucide lucide-package" data-icon="inline-start" aria-hidden="true"></i> قياسي </label> <input type="radio" class="btn-check" name="shipment-method-rtl-arabic" id="shipment-express-rtl-arabic" value="shipment-express-rtl-arabic" autocomplete="off"> <label class="btn btn-outline-secondary" for="shipment-express-rtl-arabic"> <i class="lucide lucide-zap" data-icon="inline-start" aria-hidden="true"></i> سريع </label> <input type="radio" class="btn-check" name="shipment-method-rtl-arabic" id="shipment-overnight-rtl-arabic" value="shipment-overnight-rtl-arabic" autocomplete="off"> <label class="btn btn-outline-secondary" for="shipment-overnight-rtl-arabic"> <i class="lucide lucide-rocket" data-icon="inline-start" aria-hidden="true"></i> فوري </label> </div> </div>
<div dir="rtl"> <div class="toggle-group d-inline-flex gap-2" role="group" aria-label="Shipment method"> <input type="radio" class="btn-check" name="shipment-method-rtl-arabic" id="shipment-standard-rtl-arabic" value="shipment-standard-rtl-arabic" autocomplete="off" checked> <label class="btn btn-outline-secondary" for="shipment-standard-rtl-arabic"> <i class="lucide lucide-package" data-icon="inline-start" aria-hidden="true"></i> قياسي </label> <input type="radio" class="btn-check" name="shipment-method-rtl-arabic" id="shipment-express-rtl-arabic" value="shipment-express-rtl-arabic" autocomplete="off"> <label class="btn btn-outline-secondary" for="shipment-express-rtl-arabic"> <i class="lucide lucide-zap" data-icon="inline-start" aria-hidden="true"></i> سريع </label> <input type="radio" class="btn-check" name="shipment-method-rtl-arabic" id="shipment-overnight-rtl-arabic" value="shipment-overnight-rtl-arabic" autocomplete="off"> <label class="btn btn-outline-secondary" for="shipment-overnight-rtl-arabic"> <i class="lucide lucide-rocket" data-icon="inline-start" aria-hidden="true"></i> فوري </label> </div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37<div dir="rtl"> <div class="toggle-group d-inline-flex gap-2" role="group" aria-label="Shipment method"> <input type="radio" class="btn-check" name="shipment-method-rtl-hebrew" id="shipment-standard-rtl-hebrew" value="shipment-standard-rtl-hebrew" autocomplete="off" checked> <label class="btn btn-outline-secondary" for="shipment-standard-rtl-hebrew"> <i class="lucide lucide-package" data-icon="inline-start" aria-hidden="true"></i> רגיל </label> <input type="radio" class="btn-check" name="shipment-method-rtl-hebrew" id="shipment-express-rtl-hebrew" value="shipment-express-rtl-hebrew" autocomplete="off"> <label class="btn btn-outline-secondary" for="shipment-express-rtl-hebrew"> <i class="lucide lucide-zap" data-icon="inline-start" aria-hidden="true"></i> מהיר </label> <input type="radio" class="btn-check" name="shipment-method-rtl-hebrew" id="shipment-overnight-rtl-hebrew" value="shipment-overnight-rtl-hebrew" autocomplete="off"> <label class="btn btn-outline-secondary" for="shipment-overnight-rtl-hebrew"> <i class="lucide lucide-rocket" data-icon="inline-start" aria-hidden="true"></i> דחוף </label> </div> </div>
<div dir="rtl"> <div class="toggle-group d-inline-flex gap-2" role="group" aria-label="Shipment method"> <input type="radio" class="btn-check" name="shipment-method-rtl-hebrew" id="shipment-standard-rtl-hebrew" value="shipment-standard-rtl-hebrew" autocomplete="off" checked> <label class="btn btn-outline-secondary" for="shipment-standard-rtl-hebrew"> <i class="lucide lucide-package" data-icon="inline-start" aria-hidden="true"></i> רגיל </label> <input type="radio" class="btn-check" name="shipment-method-rtl-hebrew" id="shipment-express-rtl-hebrew" value="shipment-express-rtl-hebrew" autocomplete="off"> <label class="btn btn-outline-secondary" for="shipment-express-rtl-hebrew"> <i class="lucide lucide-zap" data-icon="inline-start" aria-hidden="true"></i> מהיר </label> <input type="radio" class="btn-check" name="shipment-method-rtl-hebrew" id="shipment-overnight-rtl-hebrew" value="shipment-overnight-rtl-hebrew" autocomplete="off"> <label class="btn btn-outline-secondary" for="shipment-overnight-rtl-hebrew"> <i class="lucide lucide-rocket" data-icon="inline-start" aria-hidden="true"></i> דחוף </label> </div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37<div dir="ltr"> <div class="toggle-group d-inline-flex gap-2" role="group" aria-label="Shipment method"> <input type="radio" class="btn-check" name="shipment-method-rtl-english" id="shipment-standard-rtl-english" value="shipment-standard-rtl-english" autocomplete="off" checked> <label class="btn btn-outline-secondary" for="shipment-standard-rtl-english"> <i class="lucide lucide-package" data-icon="inline-start" aria-hidden="true"></i> Standard </label> <input type="radio" class="btn-check" name="shipment-method-rtl-english" id="shipment-express-rtl-english" value="shipment-express-rtl-english" autocomplete="off"> <label class="btn btn-outline-secondary" for="shipment-express-rtl-english"> <i class="lucide lucide-zap" data-icon="inline-start" aria-hidden="true"></i> Express </label> <input type="radio" class="btn-check" name="shipment-method-rtl-english" id="shipment-overnight-rtl-english" value="shipment-overnight-rtl-english" autocomplete="off"> <label class="btn btn-outline-secondary" for="shipment-overnight-rtl-english"> <i class="lucide lucide-rocket" data-icon="inline-start" aria-hidden="true"></i> Overnight </label> </div> </div>
<div dir="ltr"> <div class="toggle-group d-inline-flex gap-2" role="group" aria-label="Shipment method"> <input type="radio" class="btn-check" name="shipment-method-rtl-english" id="shipment-standard-rtl-english" value="shipment-standard-rtl-english" autocomplete="off" checked> <label class="btn btn-outline-secondary" for="shipment-standard-rtl-english"> <i class="lucide lucide-package" data-icon="inline-start" aria-hidden="true"></i> Standard </label> <input type="radio" class="btn-check" name="shipment-method-rtl-english" id="shipment-express-rtl-english" value="shipment-express-rtl-english" autocomplete="off"> <label class="btn btn-outline-secondary" for="shipment-express-rtl-english"> <i class="lucide lucide-zap" data-icon="inline-start" aria-hidden="true"></i> Express </label> <input type="radio" class="btn-check" name="shipment-method-rtl-english" id="shipment-overnight-rtl-english" value="shipment-overnight-rtl-english" autocomplete="off"> <label class="btn btn-outline-secondary" for="shipment-overnight-rtl-english"> <i class="lucide lucide-rocket" data-icon="inline-start" aria-hidden="true"></i> Overnight </label> </div> </div>
For Bootstrap's source behavior and the shared checkbox/radio toggle button contract, see the Bootstrap Button group documentation.
No matching pages.
Restore the default appearance.