From ad836ffabc53bcf3968ac0c5e029309d7f0d6035 Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Mon, 13 Oct 2025 21:39:18 -0700 Subject: [PATCH] v6: Drop component variants for global `.theme-*` classes (#41789) * New theme classes, revamped buttons * bundle, lint, more cleanup * update checks and radios * Improve table theme variant usage * remove table-border-factor --- .bundlewatch.config.json | 14 +- scss/_accordion.scss | 4 +- scss/_alert.scss | 21 +- scss/_badge.scss | 14 +- scss/_card.scss | 4 +- scss/_colors.scss | 24 +- scss/_dropdown.scss | 6 +- scss/_list-group.scss | 45 +--- scss/_nav.scss | 2 +- scss/_pagination.scss | 2 +- scss/_popover.scss | 4 +- scss/_root.scss | 40 +-- scss/_theme.scss | 96 +++++--- scss/_tooltip.scss | 4 +- scss/_utilities.scss | 7 - scss/_variables.scss | 38 +-- scss/buttons/_button-variables.scss | 2 +- scss/buttons/_button.scss | 228 ++++++++++-------- scss/content/_images.scss | 2 +- scss/content/_reboot.scss | 4 +- scss/content/_tables.scss | 86 ++----- scss/forms/_check.scss | 8 +- scss/forms/_form-variables.scss | 12 +- scss/forms/_radio.scss | 10 +- site/data/theme-colors.yml | 1 + site/src/components/shortcodes/Swatch.astro | 117 ++++++++- site/src/content/docs/components/alerts.mdx | 4 +- site/src/content/docs/components/badge.mdx | 21 +- site/src/content/docs/components/buttons.mdx | 22 +- .../content/docs/components/list-group.mdx | 10 +- site/src/content/docs/content/tables.mdx | 16 +- .../src/content/docs/customize/components.mdx | 12 +- site/src/content/docs/customize/theme.mdx | 219 +++++++++++------ site/src/content/docs/forms/checkbox.mdx | 4 +- site/src/content/docs/forms/radio.mdx | 4 +- site/src/layouts/DocsLayout.astro | 44 ++-- site/src/scss/_component-examples.scss | 9 +- site/src/scss/_masthead.scss | 4 +- site/src/scss/_toc.scss | 6 +- 39 files changed, 653 insertions(+), 517 deletions(-) diff --git a/.bundlewatch.config.json b/.bundlewatch.config.json index 359e9ed23e..b9aa1a9d85 100644 --- a/.bundlewatch.config.json +++ b/.bundlewatch.config.json @@ -2,15 +2,15 @@ "files": [ { "path": "./dist/css/bootstrap-grid.css", - "maxSize": "9.00 kB" + "maxSize": "9.5 kB" }, { "path": "./dist/css/bootstrap-grid.min.css", - "maxSize": "8.25 kB" + "maxSize": "8.5 kB" }, { "path": "./dist/css/bootstrap-reboot.css", - "maxSize": "5.0 kB" + "maxSize": "5.25 kB" }, { "path": "./dist/css/bootstrap-reboot.min.css", @@ -18,19 +18,19 @@ }, { "path": "./dist/css/bootstrap-utilities.css", - "maxSize": "13.5 kB" + "maxSize": "14.0 kB" }, { "path": "./dist/css/bootstrap-utilities.min.css", - "maxSize": "12.0 kB" + "maxSize": "12.25 kB" }, { "path": "./dist/css/bootstrap.css", - "maxSize": "36.5 kB" + "maxSize": "37.5 kB" }, { "path": "./dist/css/bootstrap.min.css", - "maxSize": "33.0 kB" + "maxSize": "33.75 kB" }, { "path": "./dist/js/bootstrap.bundle.js", diff --git a/scss/_accordion.scss b/scss/_accordion.scss index 4f3dc7b8f0..46c43f66f8 100644 --- a/scss/_accordion.scss +++ b/scss/_accordion.scss @@ -10,8 +10,8 @@ // scss-docs-start accordion-variables $accordion-padding-y: 1rem !default; $accordion-padding-x: 1.25rem !default; -$accordion-color: var(--#{$prefix}body-color) !default; -$accordion-bg: var(--#{$prefix}body-bg) !default; +$accordion-color: var(--#{$prefix}color-body) !default; +$accordion-bg: var(--#{$prefix}bg-body) !default; $accordion-border-width: var(--#{$prefix}border-width) !default; $accordion-border-color: var(--#{$prefix}border-color) !default; $accordion-border-radius: var(--#{$prefix}border-radius-lg) !default; diff --git a/scss/_alert.scss b/scss/_alert.scss index a4b88a1a46..58c381abdd 100644 --- a/scss/_alert.scss +++ b/scss/_alert.scss @@ -17,20 +17,20 @@ $alert-dismissible-padding-r: $alert-padding-x * 3 !default; // 3x covers widt @layer components { .alert { // scss-docs-start alert-css-vars - --#{$prefix}alert-bg: transparent; + --#{$prefix}alert-bg: var(--#{$prefix}theme-bg-subtle, transparent); --#{$prefix}alert-padding-x: #{$alert-padding-x}; --#{$prefix}alert-padding-y: #{$alert-padding-y}; --#{$prefix}alert-margin-bottom: #{$alert-margin-bottom}; - --#{$prefix}alert-color: inherit; + --#{$prefix}alert-color: var(--#{$prefix}theme-text, inherit); --#{$prefix}alert-border-color: transparent; - --#{$prefix}alert-border: #{$alert-border-width} solid var(--#{$prefix}alert-border-color); + --#{$prefix}alert-border: #{$alert-border-width} solid var(--#{$prefix}theme-border, var(--#{$prefix}alert-border-color)); --#{$prefix}alert-border-radius: #{$alert-border-radius}; --#{$prefix}alert-link-color: inherit; // scss-docs-end alert-css-vars position: relative; padding: var(--#{$prefix}alert-padding-y) var(--#{$prefix}alert-padding-x); - margin-bottom: var(--#{$prefix}alert-margin-bottom); + // margin-bottom: var(--#{$prefix}alert-margin-bottom); color: var(--#{$prefix}alert-color); background-color: var(--#{$prefix}alert-bg); border: var(--#{$prefix}alert-border); @@ -66,17 +66,4 @@ $alert-dismissible-padding-r: $alert-padding-x * 3 !default; // 3x covers widt padding: $alert-padding-y * 1.25 $alert-padding-x; } } - - - // scss-docs-start alert-modifiers - // Generate contextual modifier classes for colorizing the alert - @each $state in map.keys($new-theme-colors) { - .alert-#{$state} { - --#{$prefix}alert-color: var(--#{$prefix}#{$state}-text); - --#{$prefix}alert-bg: var(--#{$prefix}#{$state}-bg-subtle); - --#{$prefix}alert-border-color: var(--#{$prefix}#{$state}-border-subtle); - --#{$prefix}alert-link-color: var(--#{$prefix}#{$state}-text-emphasis); - } - } - // scss-docs-end alert-modifiers } diff --git a/scss/_badge.scss b/scss/_badge.scss index 0e575012e7..1fd147979c 100644 --- a/scss/_badge.scss +++ b/scss/_badge.scss @@ -1,6 +1,7 @@ @use "config" as *; @use "colors" as *; @use "variables" as *; +@use "theme" as *; @use "mixins/border-radius" as *; @use "mixins/gradients" as *; @use "vendor/rfs" as *; @@ -8,9 +9,9 @@ // scss-docs-start badge-variables $badge-font-size: .75em !default; $badge-font-weight: $font-weight-bold !default; -$badge-color: $white !default; +$badge-color: inherit !default; $badge-padding-y: .35em !default; -$badge-padding-x: .65em !default; +$badge-padding-x: .5em !default; $badge-border-radius: var(--#{$prefix}border-radius) !default; // scss-docs-end badge-variables @@ -21,7 +22,8 @@ $badge-border-radius: var(--#{$prefix}border-radius) !default; --#{$prefix}badge-padding-y: #{$badge-padding-y}; @include rfs($badge-font-size, --#{$prefix}badge-font-size); --#{$prefix}badge-font-weight: #{$badge-font-weight}; - --#{$prefix}badge-color: #{$badge-color}; + --#{$prefix}badge-color: var(--#{$prefix}theme-contrast, #{$badge-color}); + --#{$prefix}badge-bg: var(--#{$prefix}theme-bg, var(--#{$prefix}bg-2)); --#{$prefix}badge-border-radius: #{$badge-border-radius}; // scss-docs-end badge-css-vars @@ -34,6 +36,7 @@ $badge-border-radius: var(--#{$prefix}border-radius) !default; text-align: center; white-space: nowrap; vertical-align: baseline; + background-color: var(--#{$prefix}badge-bg); @include border-radius(var(--#{$prefix}badge-border-radius)); @include gradient-bg(); @@ -48,4 +51,9 @@ $badge-border-radius: var(--#{$prefix}border-radius) !default; position: relative; top: -1px; } + + .badge-subtle { + --#{$prefix}badge-color: var(--#{$prefix}theme-text); + --#{$prefix}badge-bg: var(--#{$prefix}theme-bg-subtle); + } } diff --git a/scss/_card.scss b/scss/_card.scss index 8221a3b4cc..b02dc65e05 100644 --- a/scss/_card.scss +++ b/scss/_card.scss @@ -21,7 +21,7 @@ $card-cap-bg: rgba(var(--#{$prefix}body-color-rgb), .03) ! $card-cap-color: null !default; $card-height: null !default; $card-color: null !default; -$card-bg: var(--#{$prefix}body-bg) !default; +$card-bg: var(--#{$prefix}bg-body) !default; $card-img-overlay-padding: $spacer !default; $card-group-margin: $grid-gutter-width * .5 !default; // scss-docs-end card-variables @@ -55,7 +55,7 @@ $card-group-margin: $grid-gutter-width * .5 !default; flex-direction: column; min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106 height: var(--#{$prefix}card-height); - color: var(--#{$prefix}body-color); + color: var(--#{$prefix}color-body); word-wrap: break-word; background-color: var(--#{$prefix}card-bg); background-clip: border-box; diff --git a/scss/_colors.scss b/scss/_colors.scss index 2030a71946..d260291de9 100644 --- a/scss/_colors.scss +++ b/scss/_colors.scss @@ -41,19 +41,19 @@ $hues: ( :root { @each $color, $hue in $hues { - --#{$prefix}#{$color}-025: color-mix(in srgb, #fff 94%, #{$hue}); - --#{$prefix}#{$color}-050: color-mix(in srgb, #fff 90%, #{$hue}); - --#{$prefix}#{$color}-100: color-mix(in srgb, #fff 80%, #{$hue}); - --#{$prefix}#{$color}-200: color-mix(in srgb, #fff 60%, #{$hue}); - --#{$prefix}#{$color}-300: color-mix(in srgb, #fff 40%, #{$hue}); - --#{$prefix}#{$color}-400: color-mix(in srgb, #fff 20%, #{$hue}); + --#{$prefix}#{$color}-025: color-mix(in oklch, #fff 94%, #{$hue}); + --#{$prefix}#{$color}-050: color-mix(in oklch, #fff 90%, #{$hue}); + --#{$prefix}#{$color}-100: color-mix(in oklch, #fff 80%, #{$hue}); + --#{$prefix}#{$color}-200: color-mix(in oklch, #fff 60%, #{$hue}); + --#{$prefix}#{$color}-300: color-mix(in oklch, #fff 40%, #{$hue}); + --#{$prefix}#{$color}-400: color-mix(in oklch, #fff 20%, #{$hue}); --#{$prefix}#{$color}-500: #{$hue}; - --#{$prefix}#{$color}-600: color-mix(in srgb, #000 16%, #{$hue}); - --#{$prefix}#{$color}-700: color-mix(in srgb, #000 32%, #{$hue}); - --#{$prefix}#{$color}-800: color-mix(in srgb, #000 48%, #{$hue}); - --#{$prefix}#{$color}-900: color-mix(in srgb, #000 64%, #{$hue}); - --#{$prefix}#{$color}-950: color-mix(in srgb, #000 76%, #{$hue}); - --#{$prefix}#{$color}-975: color-mix(in srgb, #000 88%, #{$hue}); + --#{$prefix}#{$color}-600: color-mix(in oklch, #000 16%, #{$hue}); + --#{$prefix}#{$color}-700: color-mix(in oklch, #000 32%, #{$hue}); + --#{$prefix}#{$color}-800: color-mix(in oklch, #000 48%, #{$hue}); + --#{$prefix}#{$color}-900: color-mix(in oklch, #000 64%, #{$hue}); + --#{$prefix}#{$color}-950: color-mix(in oklch, #000 76%, #{$hue}); + --#{$prefix}#{$color}-975: color-mix(in oklch, #000 88%, #{$hue}); } } diff --git a/scss/_dropdown.scss b/scss/_dropdown.scss index 1f212b2bcf..9859f9ce25 100644 --- a/scss/_dropdown.scss +++ b/scss/_dropdown.scss @@ -16,8 +16,8 @@ $dropdown-padding-x: 0 !default; $dropdown-padding-y: .5rem !default; $dropdown-spacer: .125rem !default; $dropdown-font-size: $font-size-base !default; -$dropdown-color: var(--#{$prefix}body-color) !default; -$dropdown-bg: var(--#{$prefix}body-bg) !default; +$dropdown-color: var(--#{$prefix}color-body) !default; +$dropdown-bg: var(--#{$prefix}bg-body) !default; $dropdown-border-color: var(--#{$prefix}border-color-translucent) !default; $dropdown-border-radius: var(--#{$prefix}border-radius) !default; $dropdown-border-width: var(--#{$prefix}border-width) !default; @@ -26,7 +26,7 @@ $dropdown-divider-bg: $dropdown-border-color !default; $dropdown-divider-margin-y: $spacer * .5 !default; $dropdown-box-shadow: var(--#{$prefix}box-shadow) !default; -$dropdown-link-color: var(--#{$prefix}body-color) !default; +$dropdown-link-color: var(--#{$prefix}color-body) !default; $dropdown-link-hover-color: $dropdown-link-color !default; $dropdown-link-hover-bg: var(--#{$prefix}tertiary-bg) !default; diff --git a/scss/_list-group.scss b/scss/_list-group.scss index f414157a23..c5c1985ad0 100644 --- a/scss/_list-group.scss +++ b/scss/_list-group.scss @@ -8,8 +8,8 @@ @use "layout/breakpoints" as *; // scss-docs-start list-group-variables -$list-group-color: var(--#{$prefix}body-color) !default; -$list-group-bg: var(--#{$prefix}body-bg) !default; +$list-group-color: var(--#{$prefix}color-body) !default; +$list-group-bg: var(--#{$prefix}bg-body) !default; $list-group-border-color: var(--#{$prefix}border-color) !default; $list-group-border-width: var(--#{$prefix}border-width) !default; $list-group-border-radius: var(--#{$prefix}border-radius) !default; @@ -28,7 +28,7 @@ $list-group-disabled-bg: $list-group-bg !default; $list-group-action-color: var(--#{$prefix}secondary-color) !default; $list-group-action-hover-color: var(--#{$prefix}emphasis-color) !default; -$list-group-action-active-color: var(--#{$prefix}body-color) !default; +$list-group-action-active-color: var(--#{$prefix}color-body) !default; $list-group-action-active-bg: var(--#{$prefix}secondary-bg) !default; // scss-docs-end list-group-variables @@ -82,10 +82,10 @@ $list-group-action-active-bg: var(--#{$prefix}secondary-bg) !default; position: relative; display: block; padding: var(--#{$prefix}list-group-item-padding-y) var(--#{$prefix}list-group-item-padding-x); - color: var(--#{$prefix}list-group-color); + color: var(--#{$prefix}theme-text, var(--#{$prefix}list-group-color)); text-decoration: if($link-decoration == none, null, none); - background-color: var(--#{$prefix}list-group-bg); - border: var(--#{$prefix}list-group-border-width) solid var(--#{$prefix}list-group-border-color); + background-color: var(--#{$prefix}theme-bg-subtle, var(--#{$prefix}list-group-bg)); + border: var(--#{$prefix}list-group-border-width) solid var(--#{$prefix}theme-border, var(--#{$prefix}list-group-border-color)); &:first-child { @include border-top-radius(inherit); @@ -128,7 +128,7 @@ $list-group-action-active-bg: var(--#{$prefix}secondary-bg) !default; .list-group-item-action { width: 100%; // For ``} /> Note that depending on how they are used, badges may be confusing for users of screen readers and similar assistive technologies. While the styling of badges provides a visual cue as to their purpose, these users will simply be presented with the content of the badge. Depending on the specific situation, these badges may seem like random additional words or numbers at the end of a sentence, link, or button. @@ -37,7 +37,7 @@ Use utilities to modify a `.badge` and position it in the corner of a link or bu Inbox - + 99+ unread messages @@ -56,7 +56,8 @@ You can also replace the `.badge` class with a few more utilities without a coun Set a `background-color` with contrasting foreground `color` with [our `.text-bg-{color}` helpers]([[docsref:helpers/color-background]]). Previously it was required to manually pair your choice of [`.text-{color}`]([[docsref:/utilities/colors]]) and [`.bg-{color}`]([[docsref:/utilities/background]]) utilities for styling, which you still may use if you prefer. - `${themeColor.title}`)} /> + `${themeColor.title}`)} /> + `${themeColor.title}`)} /> @@ -64,7 +65,7 @@ Set a `background-color` with contrasting foreground `color` with [our `.text-bg Use the `.rounded-pill` utility class to make badges more rounded with a larger `border-radius`. - `${themeColor.title}`)} /> + `${themeColor.title}`)} /> ## CSS diff --git a/site/src/content/docs/components/buttons.mdx b/site/src/content/docs/components/buttons.mdx index e6bbd3b5ba..8c89aa72b8 100644 --- a/site/src/content/docs/components/buttons.mdx +++ b/site/src/content/docs/components/buttons.mdx @@ -22,7 +22,11 @@ When using `.btn` without a modifier, be sure to add some explicit `:focus-visib Bootstrap includes several button variants, each serving its own semantic purpose, with a few extras thrown in for more control. - ``), ` + ` + + + +`), ` `]} /> @@ -276,15 +280,23 @@ Here’s an example of building a custom `.btn-*` modifier class as we do for th ### Sass variables - + + +### Sass map + +Button variants—including all their states—are defined in the `$button-variants` Sass map. This map identifies which theme color tokens to use for each variant's state. + +For example, a solid button uses the same `bg` token for its background and border colors because we want it to have a seamless look. + + ### Sass mixins There are three mixins for buttons: button and button outline variant mixins (both based on `$theme-colors`), plus a button size mixin. -{/* + - +{/* */} @@ -292,4 +304,4 @@ There are three mixins for buttons: button and button outline variant mixins (bo Button variants (for regular and outline buttons) use their respective mixins with our `$theme-colors` map to generate the modifier classes in `scss/_buttons.scss`. - +{/* */} diff --git a/site/src/content/docs/components/list-group.mdx b/site/src/content/docs/components/list-group.mdx index ef98dd5e25..fe45e14a72 100644 --- a/site/src/content/docs/components/list-group.mdx +++ b/site/src/content/docs/components/list-group.mdx @@ -130,7 +130,7 @@ Use contextual classes to style list items with a stateful background and color. `
  • A simple default list group item
  • `, - ...getData('theme-colors').map((themeColor) => `
  • A simple ${themeColor.name} list group item
  • `), + ...getData('theme-colors').map((themeColor) => `
  • A simple ${themeColor.name} list group item
  • `), `
` ]} /> @@ -142,7 +142,7 @@ Contextual classes also work with `.list-group-item-action` for `` and ` A simple default list group item `, - ...getData('theme-colors').map((themeColor) => ` A simple ${themeColor.name} list group item`), + ...getData('theme-colors').map((themeColor) => ` A simple ${themeColor.name} list group item`), `` ]} /> @@ -261,12 +261,6 @@ You can use `.stretched-link` on `