]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Fix up button group with latest buttons (#41933)
authorMark Otto <markd.otto@gmail.com>
Tue, 16 Dec 2025 19:19:22 +0000 (11:19 -0800)
committerMark Otto <markdotto@gmail.com>
Fri, 9 Jan 2026 04:08:32 +0000 (20:08 -0800)
scss/buttons/_button-group.scss
scss/buttons/_button.scss
site/src/content/docs/components/button-group.mdx
site/src/scss/_component-examples.scss

index 07cc64efb98b721502bd087273cb49ac0255988f..b1b0f22a4411324dc26753caa4f8410df6fc4f47 100644 (file)
@@ -12,8 +12,7 @@
     display: inline-flex;
     vertical-align: middle; // match .btn alignment given font-size hack above
 
-    > .btn,
-    > .btn-check {
+    > [class*="btn-"] {
       position: relative;
       flex: 1 1 auto;
     }
     // the borders properly
     > .btn-check:has(input:checked),
     > .btn-check:has(input:focus),
-    > .btn:hover,
-    > .btn:focus,
-    > .btn:active,
-    > .btn.active {
+    > [class*="btn-"]:hover,
+    > [class*="btn-"]:focus,
+    > [class*="btn-"]:active,
+    > [class*="btn-"].active {
       z-index: 1;
     }
   }
@@ -34,6 +33,7 @@
   .btn-toolbar {
     display: flex;
     flex-wrap: wrap;
+    gap: .5rem;
     justify-content: flex-start;
 
     .input-group {
     @include border-radius($btn-border-radius);
 
     // Prevent double borders when buttons are next to each other
-    > .btn:not(:first-child),
-    > .btn-check:not(:first-child),
+    > [class*="btn-"]:not(:first-child),
     > .btn-group:not(:first-child) {
       margin-inline-start: calc(-1 * #{$btn-border-width});
     }
 
     // Reset rounded corners
-    > .btn:not(:last-child):not(.dropdown-toggle),
-    > .btn-check:not(:last-child),
-    > .btn.dropdown-toggle-split:first-child,
-    > .btn-group:not(:last-child) > .btn {
+    > [class*="btn-"]:not(:last-child):not(.dropdown-toggle),
+    > .btn-group:not(:last-child) > [class*="btn-"] {
       @include border-end-radius(0);
     }
 
     // The left radius should be 0 if the button is not the first child
-    > .btn:not(:first-child),
-    > .btn-check:not(:first-child),
-    > .btn-group:not(:first-child) > .btn {
+    > [class*="btn-"]:not(:first-child),
+    > .btn-group:not(:first-child) > [class*="btn-"] {
       @include border-start-radius(0);
     }
   }
@@ -71,8 +67,8 @@
   //
   // Remix the default button sizing classes into new ones for easier manipulation.
 
-  .btn-group-sm > .btn { @extend .btn-sm; }
-  .btn-group-lg > .btn { @extend .btn-lg; }
+  // .btn-group-sm > [class*="btn-"] { @extend .btn-sm; }
+  // .btn-group-lg > [class*="btn-"] { @extend .btn-lg; }
 
 
   //
     align-items: flex-start;
     justify-content: center;
 
-    > .btn,
-    > .btn-check,
+    > [class*="btn-"],
     > .btn-group {
       width: 100%;
     }
 
-    > .btn:not(:first-child),
-    > .btn-check:not(:first-child),
+    > [class*="btn-"]:not(:first-child),
     > .btn-group:not(:first-child) {
       margin-top: calc(-1 * #{$btn-border-width});
     }
 
     // Reset rounded corners
-    > .btn:not(:last-child):not(.dropdown-toggle),
-    > .btn-check:not(:last-child),
-    > .btn-group:not(:last-child) > .btn {
+    > [class*="btn-"]:not(:last-child):not(.dropdown-toggle),
+    > .btn-group:not(:last-child) > [class*="btn-"] {
       @include border-bottom-radius(0);
     }
 
     // The top radius should be 0 if the button is not the first child
-    > .btn:not(:first-child),
-    > .btn-check:not(:first-child),
-    > .btn-group:not(:first-child) > .btn {
+    > [class*="btn-"]:not(:first-child),
+    > .btn-group:not(:first-child) > [class*="btn-"] {
       @include border-top-radius(0);
     }
   }
index 2515dda2b72a53b887388e8a287b71981a2ee52f..b60b7cf82606f722e83426c89043dea15a64a48a 100644 (file)
@@ -332,7 +332,8 @@ $btn-variant-selectors: () !default;
   // Generate button size classes from the $button-sizes map
   // Skip "md" as it's the default size for .btn
   @each $size, $properties in $button-sizes {
-    .btn-#{$size} {
+    .btn-#{$size},
+    .btn-group-#{$size} > [class*="btn-"] {
       --#{$prefix}btn-min-height: #{map.get($properties, "min-height")};
       --#{$prefix}btn-padding-y: #{map.get($properties, "padding-y")};
       --#{$prefix}btn-padding-x: #{map.get($properties, "padding-x")};
index 635b186b0922239220b5bce9a006b9b2fa835efa..5af58096764f22335be4a8fcf47d00ea088785bb 100644 (file)
@@ -6,12 +6,12 @@ toc: true
 
 ## Basic example
 
-Wrap a series of buttons with `.btn` in `.btn-group`.
+Wrap a series of buttons in `.btn-group`.
 
 <Example code={`<div class="btn-group" role="group" aria-label="Basic example">
-    <button type="button" class="btn btn-primary">Left</button>
-    <button type="button" class="btn btn-primary">Middle</button>
-    <button type="button" class="btn btn-primary">Right</button>
+    <button type="button" class="btn-solid theme-primary">Left</button>
+    <button type="button" class="btn-solid theme-primary">Middle</button>
+    <button type="button" class="btn-solid theme-primary">Right</button>
   </div>`} />
 
 <Callout>
@@ -21,30 +21,32 @@ Button groups require an appropriate `role` attribute and explicit label to ensu
 These classes can also be added to groups of links, as an alternative to the [`.nav` navigation components]([[docsref:/components/navs-tabs]]).
 
 <Example code={`<div class="btn-group">
-    <a href="#" class="btn btn-primary active" aria-current="page">Active link</a>
-    <a href="#" class="btn btn-primary">Link</a>
-    <a href="#" class="btn btn-primary">Link</a>
+    <a href="#" class="btn-solid theme-primary active" aria-current="page">Active link</a>
+    <a href="#" class="btn-solid theme-primary">Link</a>
+    <a href="#" class="btn-solid theme-primary">Link</a>
   </div>`} />
 
-## Mixed styles
+## Mixed variants
 
 <Example code={`<div class="btn-group" role="group" aria-label="Basic mixed styles example">
-    <button type="button" class="btn btn-danger">Left</button>
-    <button type="button" class="btn btn-warning">Middle</button>
-    <button type="button" class="btn btn-success">Right</button>
+    <button type="button" class="btn-solid theme-danger">Left</button>
+    <button type="button" class="btn-solid theme-warning">Middle</button>
+    <button type="button" class="btn-solid theme-success">Right</button>
   </div>`} />
 
-## Outlined styles
+## Outline buttons
 
 <Example code={`<div class="btn-group" role="group" aria-label="Basic outlined example">
-    <button type="button" class="btn btn-outline-primary">Left</button>
-    <button type="button" class="btn btn-outline-primary">Middle</button>
-    <button type="button" class="btn btn-outline-primary">Right</button>
+    <button type="button" class="btn-outline theme-primary">Left</button>
+    <button type="button" class="btn-outline theme-primary">Middle</button>
+    <button type="button" class="btn-outline theme-primary">Right</button>
   </div>`} />
 
-## Checkbox and radio button groups
+## Toggle buttons
 
-Combine button-like checkbox and radio toggle buttons into a seamless looking button group.
+### Checkbox
+
+Checkbox toggle buttons can be grouped together. Any or all of the buttons can be checked.
 
 <Example code={`<div class="btn-group" role="group" aria-label="Basic checkbox toggle button group">
     <label class="btn-check btn-outline theme-primary">
@@ -61,6 +63,10 @@ Combine button-like checkbox and radio toggle buttons into a seamless looking bu
     </label>
   </div>`} />
 
+### Radio
+
+By design, radio toggle button groups can only have one button checked at a time.
+
 <Example code={`<div class="btn-group" role="group" aria-label="Basic radio toggle button group">
     <label class="btn-check btn-outline theme-primary">
       <input type="radio" name="btnradio" autocomplete="off" checked>
@@ -81,30 +87,30 @@ Combine button-like checkbox and radio toggle buttons into a seamless looking bu
 Combine sets of button groups into button toolbars for more complex components. Use utility classes as needed to space out groups, buttons, and more.
 
 <Example code={`<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups">
-    <div class="btn-group me-2" role="group" aria-label="First group">
-      <button type="button" class="btn btn-primary">1</button>
-      <button type="button" class="btn btn-primary">2</button>
-      <button type="button" class="btn btn-primary">3</button>
-      <button type="button" class="btn btn-primary">4</button>
+    <div class="btn-group" role="group" aria-label="First group">
+      <button type="button" class="btn-solid theme-primary">1</button>
+      <button type="button" class="btn-solid theme-primary">2</button>
+      <button type="button" class="btn-solid theme-primary">3</button>
+      <button type="button" class="btn-solid theme-primary">4</button>
     </div>
-    <div class="btn-group me-2" role="group" aria-label="Second group">
-      <button type="button" class="btn btn-secondary">5</button>
-      <button type="button" class="btn btn-secondary">6</button>
-      <button type="button" class="btn btn-secondary">7</button>
+    <div class="btn-group" role="group" aria-label="Second group">
+      <button type="button" class="btn-solid theme-secondary">5</button>
+      <button type="button" class="btn-solid theme-secondary">6</button>
+      <button type="button" class="btn-solid theme-secondary">7</button>
     </div>
     <div class="btn-group" role="group" aria-label="Third group">
-      <button type="button" class="btn btn-info">8</button>
+      <button type="button" class="btn-solid theme-info">8</button>
     </div>
   </div>`} />
 
-Feel free to mix input groups with button groups in your toolbars. Similar to the example above, youll likely need some utilities though to space things properly.
+Feel free to mix input groups with button groups in your toolbars. Similar to the example above, you'll likely need some utilities though to space things properly.
 
-<Example code={`<div class="btn-toolbar mb-3" role="toolbar" aria-label="Toolbar with button groups">
-    <div class="btn-group me-2" role="group" aria-label="First group">
-      <button type="button" class="btn btn-outline-secondary">1</button>
-      <button type="button" class="btn btn-outline-secondary">2</button>
-      <button type="button" class="btn btn-outline-secondary">3</button>
-      <button type="button" class="btn btn-outline-secondary">4</button>
+<Example class="d-flex gap-3 flex-column" code={`<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups">
+    <div class="btn-group" role="group" aria-label="First group">
+      <button type="button" class="btn-outline theme-secondary">1</button>
+      <button type="button" class="btn-outline theme-secondary">2</button>
+      <button type="button" class="btn-outline theme-secondary">3</button>
+      <button type="button" class="btn-outline theme-secondary">4</button>
     </div>
     <div class="input-group">
       <div class="input-group-text" id="btnGroupAddon">@</div>
@@ -114,10 +120,10 @@ Feel free to mix input groups with button groups in your toolbars. Similar to th
 
   <div class="btn-toolbar justify-content-between" role="toolbar" aria-label="Toolbar with button groups">
     <div class="btn-group" role="group" aria-label="First group">
-      <button type="button" class="btn btn-outline-secondary">1</button>
-      <button type="button" class="btn btn-outline-secondary">2</button>
-      <button type="button" class="btn btn-outline-secondary">3</button>
-      <button type="button" class="btn btn-outline-secondary">4</button>
+      <button type="button" class="btn-outline theme-secondary">1</button>
+      <button type="button" class="btn-outline theme-secondary">2</button>
+      <button type="button" class="btn-outline theme-secondary">3</button>
+      <button type="button" class="btn-outline theme-secondary">4</button>
     </div>
     <div class="input-group">
       <div class="input-group-text" id="btnGroupAddon2">@</div>
@@ -129,22 +135,25 @@ Feel free to mix input groups with button groups in your toolbars. Similar to th
 
 Instead of applying button sizing classes to every button in a group, just add `.btn-group-*` to each `.btn-group`, including each one when nesting multiple groups.
 
-<Example code={`<div class="btn-group btn-group-lg" role="group" aria-label="Large button group">
-    <button type="button" class="btn btn-outline-primary">Left</button>
-    <button type="button" class="btn btn-outline-primary">Middle</button>
-    <button type="button" class="btn btn-outline-primary">Right</button>
+<Example class="d-flex gap-3 flex-column align-items-start" code={`<div class="btn-group btn-group-lg" role="group" aria-label="Large button group">
+    <button type="button" class="btn-outline theme-primary">Left</button>
+    <button type="button" class="btn-outline theme-primary">Middle</button>
+    <button type="button" class="btn-outline theme-primary">Right</button>
   </div>
-  <br>
   <div class="btn-group" role="group" aria-label="Default button group">
-    <button type="button" class="btn btn-outline-primary">Left</button>
-    <button type="button" class="btn btn-outline-primary">Middle</button>
-    <button type="button" class="btn btn-outline-primary">Right</button>
+    <button type="button" class="btn-outline theme-primary">Left</button>
+    <button type="button" class="btn-outline theme-primary">Middle</button>
+    <button type="button" class="btn-outline theme-primary">Right</button>
   </div>
-  <br>
   <div class="btn-group btn-group-sm" role="group" aria-label="Small button group">
-    <button type="button" class="btn btn-outline-primary">Left</button>
-    <button type="button" class="btn btn-outline-primary">Middle</button>
-    <button type="button" class="btn btn-outline-primary">Right</button>
+    <button type="button" class="btn-outline theme-primary">Left</button>
+    <button type="button" class="btn-outline theme-primary">Middle</button>
+    <button type="button" class="btn-outline theme-primary">Right</button>
+  </div>
+  <div class="btn-group btn-group-xs" role="group" aria-label="Extra small button group">
+    <button type="button" class="btn-outline theme-primary">Left</button>
+    <button type="button" class="btn-outline theme-primary">Middle</button>
+    <button type="button" class="btn-outline theme-primary">Right</button>
   </div>`} />
 
 ## Nesting
@@ -152,11 +161,11 @@ Instead of applying button sizing classes to every button in a group, just add `
 Place a `.btn-group` within another `.btn-group` when you want dropdown menus mixed with a series of buttons.
 
 <Example code={`<div class="btn-group" role="group" aria-label="Button group with nested dropdown">
-    <button type="button" class="btn btn-primary">1</button>
-    <button type="button" class="btn btn-primary">2</button>
+    <button type="button" class="btn-solid theme-primary">1</button>
+    <button type="button" class="btn-solid theme-primary">2</button>
 
     <div class="btn-group" role="group">
-      <button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
+      <button type="button" class="btn-solid theme-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
         Dropdown
       </button>
       <ul class="dropdown-menu">
@@ -171,15 +180,15 @@ Place a `.btn-group` within another `.btn-group` when you want dropdown menus mi
 Make a set of buttons appear vertically stacked rather than horizontally. **Split button dropdowns are not supported here.**
 
 <Example code={`<div class="btn-group-vertical" role="group" aria-label="Vertical button group">
-    <button type="button" class="btn btn-primary">Button</button>
-    <button type="button" class="btn btn-primary">Button</button>
-    <button type="button" class="btn btn-primary">Button</button>
-    <button type="button" class="btn btn-primary">Button</button>
+    <button type="button" class="btn-solid theme-primary">Button</button>
+    <button type="button" class="btn-solid theme-primary">Button</button>
+    <button type="button" class="btn-solid theme-primary">Button</button>
+    <button type="button" class="btn-solid theme-primary">Button</button>
   </div>`} />
 
 <Example code={`<div class="btn-group-vertical" role="group" aria-label="Vertical button group">
     <div class="btn-group" role="group">
-      <button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
+      <button type="button" class="btn-solid theme-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
         Dropdown
       </button>
       <ul class="dropdown-menu">
@@ -187,10 +196,10 @@ Make a set of buttons appear vertically stacked rather than horizontally. **Spli
         <li><a class="dropdown-item" href="#">Dropdown link</a></li>
       </ul>
     </div>
-    <button type="button" class="btn btn-primary">Button</button>
-    <button type="button" class="btn btn-primary">Button</button>
+    <button type="button" class="btn-solid theme-primary">Button</button>
+    <button type="button" class="btn-solid theme-primary">Button</button>
     <div class="btn-group dropstart" role="group">
-      <button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
+      <button type="button" class="btn-solid theme-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
         Dropdown
       </button>
       <ul class="dropdown-menu">
@@ -199,7 +208,7 @@ Make a set of buttons appear vertically stacked rather than horizontally. **Spli
       </ul>
     </div>
     <div class="btn-group dropend" role="group">
-      <button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
+      <button type="button" class="btn-solid theme-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
         Dropdown
       </button>
       <ul class="dropdown-menu">
@@ -208,7 +217,7 @@ Make a set of buttons appear vertically stacked rather than horizontally. **Spli
       </ul>
     </div>
     <div class="btn-group dropup" role="group">
-      <button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
+      <button type="button" class="btn-solid theme-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
         Dropdown
       </button>
       <ul class="dropdown-menu">
index 78102993ec714cd7eeed4c3db898f5e3be2278b7..d35e4e881921fd46b92938706dc9bb63d4f52b45 100644 (file)
       margin-inline-start: .5rem;
     }
 
-    // Buttons
-    > .btn-group {
-      margin: .25rem .125rem;
-    }
-    > .btn-toolbar + .btn-toolbar {
-      margin-top: .5rem;
-    }
-
     // List groups
     > .list-group {
       max-width: 400px;