'
- ].join('')
-
- const btnGroupEl = fixtureEl.querySelector('.btn-group')
- const btnDanger = fixtureEl.querySelector('.btn-danger')
- const input = fixtureEl.querySelector('input')
-
- const button = new Button(btnGroupEl)
-
- button.toggle()
-
- expect(btnDanger.hasAttribute('disabled')).toEqual(true)
- expect(input.checked).toEqual(false)
- })
})
describe('dispose', () => {
diff --git a/scss/_button-group.scss b/scss/_button-group.scss
index e3d2e4cc4c..a2cf7cf274 100644
--- a/scss/_button-group.scss
+++ b/scss/_button-group.scss
@@ -10,15 +10,17 @@
> .btn {
position: relative;
flex: 1 1 auto;
+ }
- // Bring the hover, focused, and "active" buttons to the front to overlay
- // the borders properly
- &:hover,
- &:focus,
- &:active,
- &.active {
- z-index: 1;
- }
+ // Bring the hover, focused, and "active" buttons to the front to overlay
+ // the borders properly
+ > .btn-toggle:checked + .btn,
+ > .btn-toggle:focus + .btn,
+ > .btn:hover,
+ > .btn:focus,
+ > .btn:active,
+ > .btn.active {
+ z-index: 1;
}
}
@@ -46,7 +48,11 @@
@include border-right-radius(0);
}
- > .btn:not(:first-child),
+ // - Target second buttons which are not part of toggle buttons
+ // - Target third or more child
+ // - Target buttons in a button group
+ > :not(.btn-toggle) + .btn,
+ > .btn:nth-child(n + 3),
> .btn-group:not(:first-child) > .btn {
@include border-left-radius(0);
}
@@ -132,28 +138,3 @@
@include border-top-radius(0);
}
}
-
-
-// Checkbox and radio options
-//
-// In order to support the browser's form validation feedback, powered by the
-// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
-// `display: none;` or `visibility: hidden;` as that also hides the popover.
-// Simply visually hiding the inputs via `opacity` would leave them clickable in
-// certain cases which is prevented by using `clip` and `pointer-events`.
-// This way, we ensure a DOM element is visible to position the popover from.
-//
-// See https://github.com/twbs/bootstrap/pull/12794 and
-// https://github.com/twbs/bootstrap/pull/14559 for more information.
-
-.btn-group-toggle {
- > .btn,
- > .btn-group > .btn {
- input[type="radio"],
- input[type="checkbox"] {
- position: absolute;
- clip: rect(0, 0, 0, 0);
- pointer-events: none;
- }
- }
-}
diff --git a/scss/_buttons.scss b/scss/_buttons.scss
index 47f7fec141..67c70de3b1 100644
--- a/scss/_buttons.scss
+++ b/scss/_buttons.scss
@@ -24,12 +24,14 @@
text-decoration: if($link-hover-decoration == underline, none, null);
}
- &:focus,
- &.focus {
+ .btn-toggle:focus + &,
+ &:focus {
outline: 0;
box-shadow: $btn-focus-box-shadow;
}
+ .btn-toggle:checked + &,
+ .btn-toggle:active + &,
&:active,
&.active {
@include box-shadow($btn-active-box-shadow);
@@ -81,8 +83,7 @@
text-decoration: $link-hover-decoration;
}
- &:focus,
- &.focus {
+ &:focus {
text-decoration: $link-hover-decoration;
}
diff --git a/scss/forms/_form-check.scss b/scss/forms/_form-check.scss
index e7afd9b259..fef7be6fe0 100644
--- a/scss/forms/_form-check.scss
+++ b/scss/forms/_form-check.scss
@@ -134,3 +134,9 @@
display: inline-block;
margin-right: $form-check-inline-margin-right;
}
+
+.btn-toggle {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none;
+}
diff --git a/scss/mixins/_buttons.scss b/scss/mixins/_buttons.scss
index 4bb9feb8ae..e8655105d5 100644
--- a/scss/mixins/_buttons.scss
+++ b/scss/mixins/_buttons.scss
@@ -25,8 +25,8 @@
border-color: $hover-border;
}
- &:focus,
- &.focus {
+ .btn-toggle:focus + &,
+ &:focus {
color: $hover-color;
@include gradient-bg($hover-background);
border-color: $hover-border;
@@ -38,6 +38,8 @@
}
}
+ .btn-toggle:checked + &,
+ .btn-toggle:active + &,
&:active,
&.active,
.show > &.dropdown-toggle {
@@ -83,11 +85,13 @@
border-color: $active-border;
}
- &:focus,
- &.focus {
+ .btn-toggle:focus + &,
+ &:focus {
box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);
}
+ .btn-toggle:checked + &,
+ .btn-toggle:active + &,
&:active,
&.active,
&.dropdown-toggle.show {
diff --git a/site/content/docs/5.0/components/button-group.md b/site/content/docs/5.0/components/button-group.md
index 236cd146c9..15fef0e088 100644
--- a/site/content/docs/5.0/components/button-group.md
+++ b/site/content/docs/5.0/components/button-group.md
@@ -1,14 +1,14 @@
---
layout: docs
title: Button group
-description: Group a series of buttons together on a single line with the button group, and super-power them with JavaScript.
+description: Group a series of buttons together on a single line with the button group.
group: components
toc: true
---
## Basic example
-Wrap a series of buttons with `.btn` in `.btn-group`. Add on optional JavaScript radio and checkbox style behavior with [our buttons plugin]({{< docsref "/components/buttons#button-plugin" >}}).
+Wrap a series of buttons with `.btn` in `.btn-group`.
{{< example >}}
@@ -26,6 +26,26 @@ In order for assistive technologies (such as screen readers) to convey that a se
In addition, groups and toolbars should be given an explicit label, as most assistive technologies will otherwise not announce them, despite the presence of the correct role attribute. In the examples provided here, we use `aria-label`, but alternatives such as `aria-labelledby` can also be used.
{{< /callout >}}
+These classes can also be added to links. Use the `.active` class to highlight a link.
+
+{{< example >}}
+
+{{< /example >}}
+
## Button toolbar
Combine sets of button groups into button toolbars for more complex components. Use utility classes as needed to space out groups, buttons, and more.
diff --git a/site/content/docs/5.0/components/buttons.md b/site/content/docs/5.0/components/buttons.md
index b64dfdbec9..cc0887487e 100644
--- a/site/content/docs/5.0/components/buttons.md
+++ b/site/content/docs/5.0/components/buttons.md
@@ -75,15 +75,6 @@ Create block level buttons—those that span the full width of a parent—by add
{{< /example >}}
-## Active state
-
-Buttons will appear pressed (with a darker background, darker border, and inset shadow) when active. **There's no need to add a class to `
{{< /example >}}
+
+## Toggle buttons
+
+### Checkbox toggle buttons
+
+Bootstrap's `.btn` styles can be applied to `