]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Additional `.theme-*` utilities to replace color background helpers and more (#41978)
authorMark Otto <markd.otto@gmail.com>
Sat, 27 Dec 2025 20:59:42 +0000 (12:59 -0800)
committerMark Otto <markdotto@gmail.com>
Fri, 9 Jan 2026 04:14:09 +0000 (20:14 -0800)
* New .theme-* utilities for consuming the existing .theme styles, replace color-background helpers

* Update blue to be less indigo

* Rebuild metadata

* mdx lint

* Fix docs link while here

* Fix up some docs work while here

* links

32 files changed:
README.md
dist/css/bootstrap-utilities.metadata.json
scss/_colors.scss
scss/_progress.scss
scss/_utilities.scss
scss/helpers/_color-bg.scss [deleted file]
scss/helpers/index.scss
site/data/sidebar.yml
site/src/assets/examples/album-rtl/index.astro
site/src/assets/examples/album/index.astro
site/src/assets/examples/starter-template/index.astro
site/src/components/header/Navigation.astro
site/src/components/home/GetStarted.astro
site/src/content/docs/components/list-group.mdx
site/src/content/docs/components/progress.mdx
site/src/content/docs/customize/color-modes.mdx
site/src/content/docs/customize/overview.mdx
site/src/content/docs/getting-started/approach.mdx
site/src/content/docs/getting-started/install.mdx
site/src/content/docs/getting-started/introduction.mdx [deleted file]
site/src/content/docs/getting-started/rtl.mdx
site/src/content/docs/guides/npm.mdx
site/src/content/docs/guides/quickstart.mdx
site/src/content/docs/helpers/color-background.mdx [deleted file]
site/src/content/docs/utilities/background.mdx
site/src/content/docs/utilities/colors.mdx
site/src/content/docs/utilities/position.mdx
site/src/content/docs/utilities/theme.mdx [new file with mode: 0644]
site/src/pages/docs/[version]/index.astro
site/src/pages/docs/index.astro
site/src/scss/_callouts.scss
site/src/scss/_component-examples.scss

index 32e088f9e412a3ba1997ef0d4cc8708efa1bb2a4..15258e442cbed1a0e67f88f1b515242e551b68bb 100644 (file)
--- a/README.md
+++ b/README.md
@@ -52,7 +52,7 @@ Several quick start options are available:
 - Install with [Composer](https://getcomposer.org/): `composer require twbs/bootstrap:5.3.8`
 - Install with [NuGet](https://www.nuget.org/): CSS: `Install-Package bootstrap` Sass: `Install-Package bootstrap.sass`
 
-Read the [Getting started page](https://getbootstrap.com/docs/5.3/getting-started/introduction/) for information on the framework contents, templates, examples, and more.
+Read the [Getting started page](https://getbootstrap.com/docs/5.3/getting-started/) for information on the framework contents, templates, examples, and more.
 
 
 ## Status
index 095db4c99cd60b951bdfad4be73bb08409fa0b33..219b44a7c15d111cd8fed54a0984da8a02870c69 100644 (file)
@@ -19,7 +19,7 @@
     },
     "aspect-ratio": {
       "class": "ratio",
-      "property": "--bs-ratio",
+      "property": "--ratio",
       "classes": [
         "ratio-auto",
         "ratio-1x1",
     },
     "focus-ring": {
       "class": "focus-ring",
-      "property": "--bs-focus-ring-color",
+      "property": "--focus-ring-color",
       "classes": [
         "focus-ring-primary",
         "focus-ring-accent",
     },
     "grid-column-counts": {
       "class": "grid-cols",
-      "property": "--bs-columns",
+      "property": "--columns",
       "classes": [
         "grid-cols-3",
         "grid-cols-4",
         "fg-emphasis-secondary"
       ]
     },
+    "fg-contrast": {
+      "class": "fg-contrast",
+      "classes": [
+        "fg-contrast-primary",
+        "fg-contrast-accent",
+        "fg-contrast-success",
+        "fg-contrast-danger",
+        "fg-contrast-warning",
+        "fg-contrast-info",
+        "fg-contrast-inverse",
+        "fg-contrast-secondary"
+      ]
+    },
     "fg-opacity": {
       "class": "fg",
       "property": "color",
         "fg-100"
       ]
     },
-    "fg-contrast": {
-      "class": "fg-contrast",
-      "classes": [
-        "fg-contrast-primary",
-        "fg-contrast-accent",
-        "fg-contrast-success",
-        "fg-contrast-danger",
-        "fg-contrast-warning",
-        "fg-contrast-info",
-        "fg-contrast-inverse",
-        "fg-contrast-secondary"
-      ]
-    },
     "link-opacity": {
       "class": "link",
       "property": "color",
         "bg-100"
       ]
     },
+    "theme-contrast": {
+      "class": "theme-contrast",
+      "classes": [
+        "theme-contrast"
+      ]
+    },
+    "theme-subtle": {
+      "class": "theme-subtle",
+      "classes": [
+        "theme-subtle"
+      ]
+    },
+    "theme-muted": {
+      "class": "theme-muted",
+      "classes": [
+        "theme-muted"
+      ]
+    },
+    "theme-border": {
+      "class": "theme-border",
+      "property": "border",
+      "classes": [
+        "theme-border"
+      ]
+    },
     "gradient": {
       "class": "bg",
       "property": "background-image",
index 8e08a9f016e53bed37c42a11faba3474607ce79f..af7f03ce415126b37b63d03086808b21bbec911b 100644 (file)
@@ -3,7 +3,7 @@
 // stylelint-disable hue-degree-notation, @stylistic/number-leading-zero
 
 // Easily convert colors to oklch() with https://oklch.com/
-$new-blue: oklch(60% 0.24 258) !default;
+$new-blue: oklch(60% 0.24 240) !default;
 $new-indigo: oklch(56% 0.26 288) !default;
 $new-violet: oklch(56% 0.24 300) !default;
 $new-purple: oklch(56% 0.24 320) !default;
index 3edbd911c8a8df5a6a387839bfb6a74b176472f2..20fe987ae2f25843c2cdd3fb67cc3d9af4819994 100644 (file)
@@ -57,10 +57,10 @@ $progress-bar-transition:           width .6s ease !default;
     flex-direction: column;
     justify-content: center;
     overflow: hidden;
-    color: var(--progress-bar-color);
+    color: var(--theme-contrast, var(--progress-bar-color));
     text-align: center;
     white-space: nowrap;
-    background-color: var(--progress-bar-bg);
+    background-color: var(--theme-bg, var(--progress-bar-bg));
     @include transition(var(--progress-bar-transition));
   }
 
index a7f1919c91ebfaa2bbc7861bc2d3325bc66c66f7..a1c1aad7852c52a147577849ad0b801162715d99 100644 (file)
@@ -735,11 +735,6 @@ $utilities: map.merge(
       class: fg-emphasis,
       values: theme-color-values("text-emphasis"),
     ),
-    "fg-opacity": (
-      class: fg,
-      property: color,
-      values: theme-opacity-values(--fg)
-    ),
     "fg-contrast": (
       property: (
         "--fg": null,
@@ -748,6 +743,11 @@ $utilities: map.merge(
       class: fg-contrast,
       values: theme-color-values("contrast"),
     ),
+    "fg-opacity": (
+      class: fg,
+      property: color,
+      values: theme-opacity-values(--fg)
+    ),
     // scss-docs-end utils-color
     // scss-docs-start utils-links
     "link-opacity": (
@@ -824,6 +824,38 @@ $utilities: map.merge(
       values: theme-opacity-values(--bg)
     ),
     // scss-docs-end utils-bg-color
+    // scss-docs-start utils-theme
+    // Theme style utilities - pair with .theme-{color} to apply coordinated bg + text colors
+    "theme-contrast": (
+      property: (
+        "background-color": var(--theme-bg),
+        "color": var(--theme-contrast)
+      ),
+      class: theme-contrast,
+      values: (null: null)
+    ),
+    "theme-subtle": (
+      property: (
+        "background-color": var(--theme-bg-subtle),
+        "color": var(--theme-text)
+      ),
+      class: theme-subtle,
+      values: (null: null)
+    ),
+    "theme-muted": (
+      property: (
+        "background-color": var(--theme-bg-muted),
+        "color": var(--theme-text-emphasis)
+      ),
+      class: theme-muted,
+      values: (null: null)
+    ),
+    "theme-border": (
+      property: border,
+      class: theme-border,
+      values: (null: var(--border-width) solid var(--theme-border))
+    ),
+    // scss-docs-end utils-theme
     "gradient": (
       property: background-image,
       class: bg,
diff --git a/scss/helpers/_color-bg.scss b/scss/helpers/_color-bg.scss
deleted file mode 100644 (file)
index 410e258..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-@use "../config" as *;
-@use "../variables" as *;
-@use "../colors" as *;
-@use "../theme" as *;
-
-@layer helpers {
-  // All-caps `RGBA()` function used because of this Sass bug: https://github.com/sass/node-sass/issues/2251
-  @each $color, $value in $new-theme-colors {
-    .text-bg-#{$color} {
-      color: var(--#{$color}-text);
-      --bg: var(--#{$color}-bg-subtle);
-      // color: color-contrast($value);
-      // background-color: RGBA(var(--#{$color}-rgb), var(--bg-opacity, 1));
-    }
-  }
-}
index 450afce02a2588e391106f217ac00ba8dc142604..90e88eaa73976f385e694c6d62e6e2e72bf737f6 100644 (file)
@@ -1,4 +1,3 @@
-@forward "color-bg";
 @forward "focus-ring";
 @forward "icon-link";
 @forward "position";
index b22b80f6a1bc4c84b1f6e5343d1c01c48d8975ae..ec230f92e0de6263e1d9cebc959ec00b01650b42 100644 (file)
   icon: magic
   icon_color: orange
   pages:
-    - title: Color & background
     - title: Focus ring
     - title: Icon link
     - title: Position
       pages:
         - title: Colors
         - title: Background
+        - title: Theme
     - group: Layout
       pages:
         - title: Aspect ratio
index d02e9f4044b59ec0c5a47e3d996305fb223a29dd..a5e224a00b80318281c57d2cb0b6f75ac8d1cf59 100644 (file)
@@ -206,6 +206,6 @@ export const direction = 'rtl'
       <a href="#">عد إلى الأعلى</a>
     </p>
     <p class="mb-1">مثال الألبوم هو © Bootstrap ، ولكن يرجى تنزيله وتخصيصه لنفسك!</p>
-    <p class="mb-0">جديد على Bootstrap؟ <a href="/"> تفضل بزيارة الصفحة الرئيسية </a> أو اقرأ <a href={getVersionedDocsPath('/getting-started/introduction')}> دليل البدء </a>.</p>
+    <p class="mb-0">جديد على Bootstrap؟ <a href="/"> تفضل بزيارة الصفحة الرئيسية </a> أو اقرأ <a href={getVersionedDocsPath('/getting-started')}> دليل البدء </a>.</p>
   </div>
 </footer>
index 9b5279302a8e0bc09b8ac84f3e14fc0804f72ded..204062c52a9723d1f243e7c2566fe83fc764c1d1 100644 (file)
@@ -205,6 +205,6 @@ import Placeholder from "@shortcodes/Placeholder.astro"
       <a href="#">Back to top</a>
     </p>
     <p class="mb-1">Album example is &copy; Bootstrap, but please download and customize it for yourself!</p>
-    <p class="mb-0">New to Bootstrap? <a href="/">Visit the homepage</a> or read our <a href={getVersionedDocsPath('/getting-started/introduction')}>getting started guide</a>.</p>
+    <p class="mb-0">New to Bootstrap? <a href="/">Visit the homepage</a> or read our <a href={getVersionedDocsPath('/getting-started/')}>getting started guide</a>.</p>
   </div>
 </footer>
index 8b2ef1045f636740667a9214787a9bb56f5b925e..7241922e70e393e8bdd280e36500a934bc7485b1 100644 (file)
@@ -69,9 +69,9 @@ export const title = 'Starter Template'
         <p>Read more detailed instructions and documentation on using or contributing to Bootstrap.</p>
         <ul class="list-unstyled ps-0">
           <li>
-            <a class="icon-link mb-1" href={getVersionedDocsPath('/getting-started/introduction')}>
+            <a class="icon-link mb-1" href={getVersionedDocsPath('/guides/quickstart')}>
               <svg class="bi" width="16" height="16" aria-hidden="true"><use href="#arrow-right-circle"/></svg>
-              Bootstrap quick start guide
+              Bootstrap quickstart guide
             </a>
           </li>
           <li>
index cec0a744e6456deb1ad5d1107cf5c68b14ab05af..b7dda6307034b5dada59d3f875ddcb62687f32b9 100644 (file)
@@ -80,7 +80,7 @@ const { addedIn, layout, title } = Astro.props
       <div class="offcanvas-body p-4 pt-0 p-lg-0">
         <hr class="d-lg-none text-white-50" />
         <ul class="navbar-nav flex-row flex-wrap bd-navbar-nav">
-          <LinkItem active={layout === 'docs'} href={getVersionedDocsPath('getting-started/introduction/')} track>
+          <LinkItem active={layout === 'docs'} href={getVersionedDocsPath('getting-started/install/')} track>
             Docs
           </LinkItem>
           <LinkItem active={title === 'Examples'} href={getVersionedDocsPath('examples/')} track>Examples</LinkItem>
index 00eb1d0779f1009b776d3370bda1a914e4fe1746..9e9354ac18909d61e2a05b8f28873eda93011fd1 100644 (file)
@@ -43,12 +43,9 @@ import Code from '@shortcodes/Code.astro'
     <p class="pe-lg-5">
       When you only need to include Bootstrap’s compiled CSS or JS, you can use <a
         href="https://www.jsdelivr.com/package/npm/bootstrap">jsDelivr</a
-      >. See it in action with our simple <a href={getVersionedDocsPath('getting-started/introduction/#quick-start')}
+      >. See it in action with our simple <a href={getVersionedDocsPath('guides/quickstart/')}
         >quick start</a
-      >, or <a href={getVersionedDocsPath('examples')}>browse the examples</a> to jumpstart your next project. You can also
-      choose to include Popper and our JS <a href={getVersionedDocsPath('getting-started/introduction/#separate')}
-        >separately</a
-      >.
+      >, or <a href={getVersionedDocsPath('examples')}>browse the examples</a> to jumpstart your next project.
     </p>
     <Code
       code={`<link href="${getConfig().cdn.css}" rel="stylesheet" integrity="${
index 3b08bd0b21cb1cdd1ea8b8a6a1c2c6c286a373eb..cfdf9fd97b73a459b385114e39571ea8e1d33d47 100644 (file)
@@ -92,21 +92,21 @@ These work great with custom content as well.
         <div class="fw-bold">Subheading</div>
         Content for list item
       </div>
-      <span class="badge text-bg-primary rounded-pill">14</span>
+      <span class="badge theme-primary">14</span>
     </li>
     <li class="list-group-item d-flex justify-content-between align-items-start">
       <div class="ms-2 me-auto">
         <div class="fw-bold">Subheading</div>
         Content for list item
       </div>
-      <span class="badge text-bg-primary rounded-pill">14</span>
+      <span class="badge theme-primary">14</span>
     </li>
     <li class="list-group-item d-flex justify-content-between align-items-start">
       <div class="ms-2 me-auto">
         <div class="fw-bold">Subheading</div>
         Content for list item
       </div>
-      <span class="badge text-bg-primary rounded-pill">14</span>
+      <span class="badge theme-primary">14</span>
     </li>
   </ol>`} />
 
@@ -155,15 +155,15 @@ Add badges to any list group item to show unread counts, activity, and more with
 <Example code={`<ul class="list-group">
     <li class="list-group-item d-flex justify-content-between align-items-center">
       A list item
-      <span class="badge text-bg-primary rounded-pill">14</span>
+      <span class="badge theme-primary">14</span>
     </li>
     <li class="list-group-item d-flex justify-content-between align-items-center">
       A second list item
-      <span class="badge text-bg-primary rounded-pill">2</span>
+      <span class="badge theme-primary">2</span>
     </li>
     <li class="list-group-item d-flex justify-content-between align-items-center">
       A third list item
-      <span class="badge text-bg-primary rounded-pill">1</span>
+      <span class="badge theme-primary">1</span>
     </li>
   </ul>`} />
 
index 264c06b602df63dd19cb3dca60bec179e3b193d2..5f52ede00a70374a77b4d1999de5f2083937bab3 100644 (file)
@@ -90,19 +90,19 @@ Use background utility classes to change the appearance of individual progress b
 
 <Details name="warning-color-assistive-technologies" />
 
-If you’re adding labels to progress bars with a custom background color, make sure to also set an appropriate [text color]([[docsref:/utilities/colors#colors]]), so the labels remain readable and have sufficient contrast. We recommend using the [color and background]([[docsref:/helpers/color-background]]) helper classes.
+If you’re adding labels to progress bars with a custom background color, make sure to also set an appropriate [text color]([[docsref:/utilities/colors#colors]]), so the labels remain readable and have sufficient contrast. We recommend using the [theme contrast]([[docsref:/utilities/theme#contrast]]) helper classes.
 
 <Example code={`<div class="progress" role="progressbar" aria-label="Success example" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100">
-    <div class="progress-bar text-bg-success" style="width: 25%">25%</div>
+    <div class="progress-bar theme-success" style="width: 25%">25%</div>
   </div>
   <div class="progress" role="progressbar" aria-label="Info example" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100">
-    <div class="progress-bar text-bg-info" style="width: 50%">50%</div>
+    <div class="progress-bar theme-info" style="width: 50%">50%</div>
   </div>
   <div class="progress" role="progressbar" aria-label="Warning example" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100">
-    <div class="progress-bar text-bg-warning" style="width: 75%">75%</div>
+    <div class="progress-bar theme-warning" style="width: 75%">75%</div>
   </div>
   <div class="progress" role="progressbar" aria-label="Danger example" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100">
-    <div class="progress-bar text-bg-danger" style="width: 100%">100%</div>
+    <div class="progress-bar theme-danger" style="width: 100%">100%</div>
   </div>`} />
 
 ## Multiple bars
index 74cb60f353c65d464b38c8a3332c21218e03c610..77b4a60d0afabdaefd0534e993e0d8e9b2ed17e2 100644 (file)
@@ -67,7 +67,7 @@ For example, to change the color mode of a dropdown menu, add `data-bs-theme="li
 
 ### Enable dark mode
 
-Enable the built in dark color mode across your entire project by adding the `data-bs-theme="dark"` attribute to the `<html>` element. This will apply the dark color mode to all components and elements, other than those with a specific `data-bs-theme` attribute applied. Building on the [quick start template]([[docsref:/getting-started/introduction#quick-start]]):
+Enable the built in dark color mode across your entire project by adding the `data-bs-theme="dark"` attribute to the `<html>` element. This will apply the dark color mode to all components and elements, other than those with a specific `data-bs-theme` attribute applied. Building on the [quick start template]([[docsref:/guides/quickstart/]]):
 
 ```html
 <!doctype html>
index cf4289dbe21328b738de99481bb0a0b68cb5ffb2..b6566e8132065d575a72856c6a55b835ed045ee4 100644 (file)
@@ -33,7 +33,7 @@ Our two preferred methods are:
 
 While we cannot go into details here on how to use every package manager, we can give some guidance on [using Bootstrap with your own Sass compiler]([[docsref:/customize/sass]]).
 
-For those who want to use the distribution files, review the [getting started page]([[docsref:/getting-started/introduction]]) for how to include those files and an example HTML page. From there, consult the docs for the layout, components, and behaviors you’d like to use.
+For those who want to use the distribution files, review the [getting started page]([[docsref:/guides/quickstart]]) for how to include those files and an example HTML page. From there, consult the docs for the layout, components, and behaviors you’d like to use.
 
 As you familiarize yourself with Bootstrap, continue exploring this section for more details on how to utilize our global options, making use of and changing our color system, how we build our components, how to use our growing list of CSS custom properties, and how to optimize your code when building with Bootstrap.
 
index 9ceea05f348a04561e4e6d8242f05ef27f56adbf..9215bc635d4e1f9b45cfa8086cbfae7106d41f87 100644 (file)
@@ -41,7 +41,7 @@ Bootstrap is developed *mobile first*, a strategy in which we optimize code for
 <meta name="viewport" content="width=device-width, initial-scale=1">
 ```
 
-You can see an example of this in action in [the quick start]([[docsref:/getting-started/introduction#quick-start]]).
+You can see an example of this in action in [the quick start]([[docsref:/guides/quickstart/]]).
 
 ### Box-sizing
 
index ace55374eef3c49b572c815041fa3a3514f8f150..9d326a768c436d86963435073f30357a2959be50 100644 (file)
@@ -2,6 +2,10 @@
 title: Install Bootstrap
 description: Add Bootstrap to your project with CDN, package manager, or source files.
 toc: true
+aliases:
+ - "/docs/[[config:docs_version]]/getting-started/"
+ - "/docs/getting-started/"
+ - "/getting-started/"
 ---
 
 ## Install
diff --git a/site/src/content/docs/getting-started/introduction.mdx b/site/src/content/docs/getting-started/introduction.mdx
deleted file mode 100644 (file)
index 99a6798..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: Basics of Bootstrap
-description: Bootstrap is a powerful, feature-packed frontend toolkit. Build anything—from prototype to production—in minutes.
-aliases:
- - "/docs/[[config:docs_version]]/getting-started/"
- - "/docs/getting-started/"
- - "/getting-started/"
-toc: true
----
index 4714fe4ec7b79c6675f444db3e47db7cd0f2c5d6..7822a6be42ba429af91dc3d82c030a8900128f65 100644 (file)
@@ -5,7 +5,7 @@ toc: true
 ---
 
 <Callout type="info">
-  **ProTip:** Get familiar with Bootstrap first with our [getting started guide]([[docsref:/getting-started/introduction]]) before working with RTL.
+  **ProTip:** Get familiar with Bootstrap first with our [getting started guide]([[docsref:/getting-started/]]) before working with RTL.
 </Callout>
 
 ## How it works
index 9639e9ed2dbb32046ed8e6ae16ed01743fddd077..4fe2a720d2d8e3874f962e9dc8bbe59df5c1af03 100644 (file)
@@ -5,7 +5,7 @@ toc: true
 thumbnail: guides/bootstrap-npm@2x.png
 ---
 
-<img class="d-block mx-auto mb-4 img-fluid rounded-3" srcset="/docs/[[config:docs_version]]/assets/img/guides/bootstrap-npm.png, /docs/[[config:docs_version]]/assets/img/guides/bootstrap-npm@2x.png 2x" src="/docs/[[config:docs_version]]/assets/img/guides/bootstrap-npm.png" width="1000" height="500" alt=""/>
+<img class="d-block mx-auto img-fluid rounded-3" srcset="/docs/[[config:docs_version]]/assets/img/guides/bootstrap-npm.png, /docs/[[config:docs_version]]/assets/img/guides/bootstrap-npm@2x.png 2x" src="/docs/[[config:docs_version]]/assets/img/guides/bootstrap-npm.png" width="1000" height="500" alt=""/>
 
 <Callout>
 **Want to skip to the end?** Download the source code and working demo for this guide from the [twbs/examples repository](https://github.com/twbs/examples/tree/sass-js/). You can also [open the example in StackBlitz](https://stackblitz.com/github/twbs/examples/tree/main/sass-js?file=index.html).
index f9e86ba7effb4729adbf9fe9b8ce2f016b4a57d5..f029999dbfb6617302b426a979077236fd05e6fd 100644 (file)
@@ -9,8 +9,6 @@ Get started using Bootstrap in seconds by including our production-ready CSS and
 **Got the gist already?** See the end result in this [Bootstrap CodePen demo](https://codepen.io/team/bootstrap/pen/qBamdLj).
 </Callout>
 
-<br/>
-
 1. **Create a new `index.html` file in your project root.** Include the `<meta name="viewport">` tag as well for [proper responsive behavior](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/meta/name/viewport) in mobile devices.
 
    ```html
diff --git a/site/src/content/docs/helpers/color-background.mdx b/site/src/content/docs/helpers/color-background.mdx
deleted file mode 100644 (file)
index fa62d3f..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: Color and background
-description: Set a background color with contrasting foreground color.
-toc: true
----
-
-import { getData } from '@libs/data'
-
-## Overview
-
-Color and background helpers combine the power of our [`.text-*` utilities]([[docsref:/utilities/colors]]) and [`.bg-*` utilities]([[docsref:/utilities/background]]) in one class. Using our Sass `color-contrast()` function, we automatically determine a contrasting `color` for a particular `background-color`.
-
-<Callout type="warning">
-**Heads up!** There’s currently no support for a CSS-native `color-contrast` function, so we use our own via Sass. This means that customizing our theme colors via CSS variables may cause color contrast issues with these utilities.
-</Callout>
-
-<Example code={getData('theme-colors').map((themeColor) => `<div class="text-bg-${themeColor.name} p-3">${themeColor.title} with contrasting color</div>`)} />
-
-<Details name="warning-color-assistive-technologies" />
-
-## With components
-
-Use them in place of combined `.text-*` and `.bg-*` classes, like on [badges]([[docsref:/components/badge#background-colors]]):
-
-<Example code={`<span class="badge text-bg-primary">Primary</span>
-<span class="badge text-bg-info">Info</span>`} />
-
-Or on [cards]([[docsref:/components/card#background-and-color]]):
-
-<Example code={`<div class="card text-bg-primary mb-3" style="max-width: 18rem;">
-    <div class="card-header">Header</div>
-    <div class="card-body">
-      <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card’s content.</p>
-    </div>
-  </div>
-  <div class="card text-bg-info mb-3" style="max-width: 18rem;">
-    <div class="card-header">Header</div>
-    <div class="card-body">
-      <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card’s content.</p>
-    </div>
-  </div>`} />
index 556a38b8d3dad0b1ba384fa5c1e95af303e42155..1da4f866628c0ae4a831d86fbd05d964d0cb005c 100644 (file)
@@ -50,12 +50,10 @@ By adding a `.bg-gradient` class, a linear gradient is added as background image
 
 Do you need a gradient in your custom CSS? Just add `background-image: var(--bs-gradient);`.
 
-{getData('theme-colors').map((themeColor) => {
-  return (
-    <div class={`p-3 mb-2 bg-${themeColor.name} bg-gradient text-white`}>.bg-{themeColor.name}.bg-gradient</div>
-  )
-})}
-<div class="p-3 mb-2 bg-black bg-gradient text-white">.bg-black.bg-gradient</div>
+<Example class="d-flex flex-column gap-2" code={[
+  ...getData('theme-colors').map((themeColor) => `<div class="p-3 bg-${themeColor.name} bg-gradient fg-contrast-${themeColor.name}">.bg-${themeColor.name}.bg-gradient</div>`),
+  `<div class="p-3 bg-black bg-gradient fg-contrast">.bg-black.bg-gradient</div>`
+]} />
 
 ## Opacity
 
index 9a50bbab57579c6c3682729939cf090072027afb..b2165d1968538f3d36628b0d43f8b5c3f8f4181b 100644 (file)
@@ -59,6 +59,38 @@ Change the opacity of a text color by using any of the `.fg-<percentage>` utilit
 <div class="fg-primary fg-20">This is 20% opacity primary text</div>
 <div class="fg-primary fg-10">This is 10% opacity primary text</div>`} />
 
+## Contrast colors
+
+Change the contrast color of a text or link with `.fg-contrast-{color}`. This will set the `--bs-fg` variable to the theme’s `contrast` key color.
+```css
+.fg-contrast-primary {
+  --bs-fg: var(--bs-white);
+  color: var(--bs-fg);
+}
+```
+
+<Example class="d-flex flex-column gap-2" code={`<p class="bg-primary fg-contrast-primary">.fg-contrast-primary</p>
+<p class="bg-accent fg-contrast-accent">.fg-contrast-accent</p>
+<p class="bg-success fg-contrast-success">.fg-contrast-success</p>
+<p class="bg-danger fg-contrast-danger">.fg-contrast-danger</p>
+<p class="bg-warning fg-contrast-warning">.fg-contrast-warning</p>
+<p class="bg-info fg-contrast-info">.fg-contrast-info</p>
+<p class="bg-inverse fg-contrast-inverse">.fg-contrast-inverse</p>
+<p class="bg-secondary fg-contrast-secondary">.fg-contrast-secondary</p>`} />
+
+These even mix with the opacity utilities.
+
+<Example class="d-flex flex-column gap-2" code={`<p class="bg-primary fg-contrast-primary fg-100">.fg-contrast-primary fg-100</p>
+<p class="bg-primary fg-contrast-primary fg-90">.fg-contrast-primary fg-90</p>
+<p class="bg-primary fg-contrast-primary fg-80">.fg-contrast-primary fg-80</p>
+<p class="bg-primary fg-contrast-primary fg-70">.fg-contrast-primary fg-70</p>
+<p class="bg-primary fg-contrast-primary fg-60">.fg-contrast-primary fg-60</p>
+<p class="bg-primary fg-contrast-primary fg-50">.fg-contrast-primary fg-50</p>
+<p class="bg-primary fg-contrast-primary fg-40">.fg-contrast-primary fg-40</p>
+<p class="bg-primary fg-contrast-primary fg-30">.fg-contrast-primary fg-30</p>
+<p class="bg-primary fg-contrast-primary fg-20">.fg-contrast-primary fg-20</p>
+<p class="bg-primary fg-contrast-primary fg-10">.fg-contrast-primary fg-10</p>`} />
+
 ## Reset color
 
 Reset a text or link's color with `.text-reset`, so that it inherits the color from its parent.
index 7426030253386665b733f94fb3430d4b9229dbc3..1b6f9044917284af9291b91b5edb0d15eedbd7ec 100644 (file)
@@ -88,15 +88,15 @@ By adding `.translate-middle-x` or `.translate-middle-y` classes, elements can b
 Here are some real life examples of these classes:
 
 <Example class="bd-example-position-examples d-flex justify-content-around align-items-center" code={`<button type="button" class="btn btn-primary position-relative">
-    Mails <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill text-bg-secondary">+99 <span class="visually-hidden">unread messages</span></span>
+    Mails <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill theme-secondary theme-contrast">+99 <span class="visually-hidden">unread messages</span></span>
   </button>
 
-  <div class="position-relative py-2 px-4 text-bg-secondary border border-secondary rounded-pill">
-    Marker <svg width="1em" height="1em" viewBox="0 0 16 16" class="position-absolute top-100 start-50 translate-middle mt-1" fill="var(--bs-secondary)" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M7.247 11.14L2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z"/></svg>
+  <div class="position-relative py-2 px-4 theme-secondary theme-contrast border border-secondary rounded-pill">
+    Marker <svg width="1em" height="1em" viewBox="0 0 16 16" class="position-absolute top-100 start-50 translate-middle mt-1" fill="var(--bs-theme-bg)" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M7.247 11.14L2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z"/></svg>
   </div>
 
   <button type="button" class="btn btn-primary position-relative">
-    Alerts <span class="position-absolute top-0 start-100 translate-middle badge border border-light rounded-circle bg-danger p-2"><span class="visually-hidden">unread messages</span></span>
+    Alerts <span class="position-absolute top-0 start-100 translate-middle w-1 h-1 border border-bg rounded-circle bg-danger p-2"><span class="visually-hidden">unread messages</span></span>
   </button>`} />
 
 You can use these classes with existing components to create new ones. Remember that you can extend its functionality by adding entries to the `$position-values` variable.
@@ -105,9 +105,9 @@ You can use these classes with existing components to create new ones. Remember
     <div class="progress" role="progressbar" aria-label="Progress" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100" style="height: 1px;">
       <div class="progress-bar" style="width: 50%"></div>
     </div>
-    <button type="button" class="position-absolute top-0 start-0 translate-middle btn btn-sm btn-primary rounded-pill" style="width: 2rem; height:2rem;">1</button>
-    <button type="button" class="position-absolute top-0 start-50 translate-middle btn btn-sm btn-primary rounded-pill" style="width: 2rem; height:2rem;">2</button>
-    <button type="button" class="position-absolute top-0 start-100 translate-middle btn btn-sm btn-secondary rounded-pill" style="width: 2rem; height:2rem;">3</button>
+    <button type="button" class="position-absolute top-0 start-0 translate-middle btn-solid btn-sm theme-primary rounded-pill" style="width: 2rem; height:2rem;">1</button>
+    <button type="button" class="position-absolute top-0 start-50 translate-middle btn-solid btn-sm theme-primary rounded-pill" style="width: 2rem; height:2rem;">2</button>
+    <button type="button" class="position-absolute top-0 start-100 translate-middle btn-solid btn-sm theme-secondary rounded-pill" style="width: 2rem; height:2rem;">3</button>
   </div>`} />
 
 ## CSS
diff --git a/site/src/content/docs/utilities/theme.mdx b/site/src/content/docs/utilities/theme.mdx
new file mode 100644 (file)
index 0000000..59c42b3
--- /dev/null
@@ -0,0 +1,108 @@
+---
+title: Theme
+description: Combine one of three theme utilities with our theme color classes to set `color` and `background-color` pairings on any element, just like component variants.
+toc: true
+utility:
+  - theme-contrast
+  - theme-subtle
+  - theme-muted
+  - theme-border
+---
+
+import { getData } from '@libs/data'
+
+## Overview
+
+Take any of our theme color classes and add `.theme-contrast`, `.theme-subtle`, or `.theme-muted` to set a predefined `color and `background-color` pairing. Then optionally add `.theme-border` to set a predefined border color. For more information on how theme colors work, see the [Theme documentation]([[docsref:/customize/theme]]) in our Customize section.
+
+### Contrast
+
+Contrast pairs the `bg` theme token with the `contrast` text color for maximum readability. This is ideal for high-emphasis elements with solid backgrounds.
+
+<Example class="d-grid gap-2" code={getData('theme-colors').map((themeColor) => `<div class="p-2 theme-${themeColor.name} theme-contrast">.theme-${themeColor.name} .theme-contrast</div>`)} />
+
+### Subtle
+
+Subtle pairs the `bg-subtle` theme token with the `text` text color for a lower-contrast, more subtle appearance. This combination will automatically adjust to the current color mode.
+
+<Example class="d-grid gap-2" code={getData('theme-colors').map((themeColor) => `<div class="p-2 theme-${themeColor.name} theme-subtle">.theme-${themeColor.name} .theme-subtle</div>`)} />
+
+And with borders:
+
+<Example class="d-grid gap-2" code={getData('theme-colors').map((themeColor) => `<div class="p-2 theme-${themeColor.name} theme-subtle theme-border">.theme-${themeColor.name} .theme-subtle</div>`)} />
+
+### Muted
+
+Muted pairs the `bg-muted` theme token with the `text-emphasis` text color for a lower-contrast, more muted appearance. Like subtle, this combination will automatically adjust to the current color mode.
+
+<Example class="d-grid gap-2" code={getData('theme-colors').map((themeColor) => `<div class="p-2 theme-${themeColor.name} theme-muted">.theme-${themeColor.name} .theme-muted</div>`)} />
+
+And with borders:
+
+<Example class="d-grid gap-2" code={getData('theme-colors').map((themeColor) => `<div class="p-2 theme-${themeColor.name} theme-muted theme-border">.theme-${themeColor.name} .theme-muted</div>`)} />
+
+## Comparison
+
+Here's a side-by-side comparison of all three styles for each theme color:
+
+<Example code={getData('theme-colors').map((themeColor) => `<div class="d-flex gap-2 mb-2">
+    <div class="theme-${themeColor.name} theme-contrast p-3 flex-fill text-center rounded">${themeColor.title} contrast</div>
+    <div class="theme-${themeColor.name} theme-subtle p-3 flex-fill text-center rounded">${themeColor.title} subtle</div>
+    <div class="theme-${themeColor.name} theme-muted p-3 flex-fill text-center rounded">${themeColor.title} muted</div>
+  </div>`)} />
+
+## With components
+
+Theme utilities work great with components that support theming. Apply the theme color to a container and use theme style classes on individual elements.
+
+<Example code={`<div class="theme-primary">
+    <div class="d-flex gap-2 mb-3">
+      <span class="badge theme-contrast">Contrast badge</span>
+      <span class="badge theme-subtle">Subtle badge</span>
+      <span class="badge theme-muted">Muted badge</span>
+    </div>
+  </div>
+  <div class="theme-danger">
+    <div class="d-flex gap-2 mb-3">
+      <span class="badge theme-contrast">Contrast badge</span>
+      <span class="badge theme-subtle">Subtle badge</span>
+      <span class="badge theme-muted">Muted badge</span>
+    </div>
+  </div>`} />
+
+You can also mix theme colors within the same container by applying different `.theme-{color}` classes to child elements:
+
+<Example code={`<div class="d-flex gap-2">
+    <div class="theme-success theme-contrast p-3 rounded">Success</div>
+    <div class="theme-warning theme-contrast p-3 rounded">Warning</div>
+    <div class="theme-danger theme-contrast p-3 rounded">Danger</div>
+  </div>`} />
+
+## CSS
+
+### Generated CSS
+
+The theme style classes generate the following CSS:
+
+```css
+.theme-contrast {
+  background-color: var(--theme-bg);
+  color: var(--theme-contrast);
+}
+
+.theme-subtle {
+  background-color: var(--theme-bg-subtle);
+  color: var(--theme-text);
+}
+
+.theme-muted {
+  background-color: var(--theme-bg-muted);
+  color: var(--theme-text-emphasis);
+}
+```
+
+### Sass utilities API
+
+Theme utilities are declared in our utilities API in `scss/_utilities.scss`. [Learn how to use the utilities API.]([[docsref:/utilities/api#using-the-api]])
+
+<ScssDocs name="utils-theme" file="scss/_utilities.scss" />
index 461760fb2006b3db405c6ee2a05f2b786b16a03b..30b057a7b62ff310c05b6df0ea73095e157a1965 100644 (file)
@@ -12,4 +12,4 @@ export function getStaticPaths() {
 }
 ---
 
-<RedirectLayout path={getVersionedDocsPath('/getting-started/introduction/')} />
+<RedirectLayout path={getVersionedDocsPath('/getting-started/install/')} />
index e1796424dc5fa4e44ba23419545f55133464b227..3a924b6da56ca33ad72e55b36e0e1c7361045b6b 100644 (file)
@@ -3,4 +3,4 @@ import RedirectLayout from '@layouts/RedirectLayout.astro'
 import { getVersionedDocsPath } from '@libs/path'
 ---
 
-<RedirectLayout path={getVersionedDocsPath('/getting-started/introduction/')} />
+<RedirectLayout path={getVersionedDocsPath('/getting-started/install/')} />
index b2da95f3882b8c4d8175c14e201b8853966ad22c..63cdcea182bf46343928c27cad52c7b931ea9922 100644 (file)
@@ -14,8 +14,6 @@
     --code-color: var(--bd-callout-code-color);
 
     padding: 1.25rem;
-    margin-top: 1.25rem;
-    margin-bottom: 1.25rem;
     font-size: .875rem;
     line-height: 1.5;
     // color: var(--bd-callout-color, inherit);
index f5ba91d5febbcc1a70fd48aa52619664873c15c8..36931f00b23804e453a07ebb2514a15401da7c96 100644 (file)
     }
   }
 
+  li > .bd-code-snippet {
+    margin-block: 1.25rem;
+  }
+  li:last-child > .bd-code-snippet:last-child {
+    margin-bottom: 0;
+  }
+
   .highlight-toolbar {
     padding-block: .375rem;
     padding-inline-start: var(--bd-example-padding);
 
     .position-relative {
       height: 200px;
-      background-color: var(--bs-tertiary-bg);
+      background-color: var(--bs-bg-2);
     }
 
     .position-absolute {
       width: 2rem;
       height: 2rem;
-      background-color: var(--bs-body-color);
+      background-color: var(--bs-fg-2);
       @include border-radius();
     }
   }