颜色模式
自 5.3.0 版起,Bootstrap 现在支持色彩模式或主题。探索我们的默认浅色模式和新的深色模式,或使用我们的样式作为模板创建您自己的模式。
深色模式
Bootstrap现在支持颜色模式,从深色模式开始! 使用v5.3.0,您可以实现自己的颜色模式切换器(请参阅下面Bootstrap文档中的示例),并根据需要应用不同的颜色模式。我们支持浅色模式(默认)和深色模式。通过 data-bs-theme
属性,可以在 <html>
元素或特定组件和元素上全局切换颜色模式。
另外,你也可以使用我们的颜色模式混合素切换到媒体查询实现–请参阅使用部分了解详情。不过需要注意的是,这样就无法按组件更换主题了,如下图所示。
示例
例如,要更改下拉菜单的颜色模式,可在父级 .dropdown
中添加 data-bs-theme=“light”
或 data-bs-theme=“dark”
。现在,无论全局颜色模式如何,这些下拉菜单都将以指定的主题值显示。
<div class="dropdown" data-bs-theme="light">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButtonLight" data-bs-toggle="dropdown" aria-expanded="false">
Default dropdown
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButtonLight">
<li><a class="dropdown-item active" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Separated link</a></li>
</ul>
</div>
<div class="dropdown" data-bs-theme="dark">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButtonDark" data-bs-toggle="dropdown" aria-expanded="false">
Dark dropdown
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButtonDark">
<li><a class="dropdown-item active" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Separated link</a></li>
</ul>
</div>
工作原理
-
如上所示,颜色模式样式由
data-bs-theme
属性控制。该属性可以应用于<html>
元素,也可以应用于任何其他元素或 Bootstrap 组件。如果应用于<html>
元素,它将应用于所有内容。如果应用于某个组件或元素,它将作用于该特定组件或元素。 -
对于您希望支持的每一种颜色模式,您都需要为共享的全局 CSS 变量添加新的重载。在我们的
_root.scss
样式表中,我们已经为深色模式添加了重载,而浅色模式则是默认值。在编写特定颜色模式样式时,请使用 mixin:// 在 _root.scss 中的颜色模式变量 @include color-mode(dark) { // CSS 变量... }
-
我们使用自定义的
_variables-dark.scss
为深色模式提供共享的全局 CSS 变量覆盖。你的自定义颜色模式并不需要这个文件,但我们的深色模式需要它,原因有二。首先,最好在一个地方重置全局颜色。其次,一些 Sass 变量必须被重写,以用于手风琴、表单组件等 CSS 中嵌入的背景图片。
用法
启用深色模式
通过在 <html>
元素中添加 data-bs-theme="dark"
属性,在整个项目中启用内置的深色模式。这将对所有组件和元素应用深色模式,但应用了特定 data-bs-theme
属性的组件和元素除外。以快速入门模板 为基础:
<!doctype html>
<html lang="en" data-bs-theme="dark">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap demo</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Y3IQOsa3niuvpqakr8NIT3EETRv0G6tFumi3detLTSYuXBc6XxbPEt9sOg6OcLgO" crossorigin="anonymous">
</head>
<body>
<h1>Hello, world!</h1>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-r5kRSTMtRNVfwqCvIzNkemSRRqsQB3BJN5m7GjomHUT+81f70U37lfRUk9tJSSQO" crossorigin="anonymous"></script>
</body>
</html>
Bootstrap 还没有内置颜色模式选择器,但您可以使用我们自己文档中的选择器。在 JavaScript 部分了解更多
使用 Sass 构建
我们的新深色模式选项可供所有 Bootstrap 用户使用,但它是通过数据属性而非媒体查询来控制的,不会自动切换项目的色彩模式。您可以通过 Sass 将$enable-dark-mode
更改为false
,从而完全禁用我们的深色模式。
我们使用自定义的 Sass mixin color-mode()
,帮助你控制色彩模式的应用方式。默认情况下,我们使用 data
属性方法,允许您创建更友好的用户体验,让您的访问者可以选择自动深色模式或控制他们的偏好(就像我们自己的文档一样)。这也是添加不同主题和更多自定义颜色模式(除明暗模式外)的一种简单、可扩展的方法。
如果你想使用媒体查询并只让颜色模式自动生效,可以通过 Sass 变量更改 mixin 的默认类型。请看下面的代码段及其编译后的 CSS 输出。
$color-mode-type: data;
@include color-mode(dark) {
.element {
color: var(--bs-primary-text-emphasis);
background-color: var(--bs-primary-bg-subtle);
}
}
输出:
[data-bs-theme=dark] .element {
color: var(--bs-primary-text-emphasis);
background-color: var(--bs-primary-bg-subtle);
}
设置 media-query
:
$color-mode-type: media-query;
@include color-mode(dark) {
.element {
color: var(--bs-primary-text-emphasis);
background-color: var(--bs-primary-bg-subtle);
}
}
输出:
@media (prefers-color-scheme: dark) {
.element {
color: var(--bs-primary-text-emphasis);
background-color: var(--bs-primary-bg-subtle);
}
}
自定义颜色模式
虽然颜色模式的主要用途是浅色和深色模式,但也可以自定义颜色模式。创建您自己的 data-bs-theme
选择器,用自定义值作为您的颜色模式名称,然后根据需要修改我们的 Sass 和 CSS 变量。我们选择创建一个单独的 _variables-dark.scss
样式表来存放 Bootstrap 的深色模式专用 Sass 变量,但这对你来说不是必需的。
例如,您可以使用选择器 data-bs-theme=“blue”
创建一个 “蓝色主题”。在你的自定义 Sass 或 CSS 文件中,添加新的选择器,并根据需要覆盖任何全局或组件 CSS 变量。如果使用 Sass,还可以在 CSS 变量覆盖中使用 Sass 的函数。
[data-bs-theme="blue"] {
--bs-body-color: var(--bs-white);
--bs-body-color-rgb: #{to-rgb($white)};
--bs-body-bg: var(--bs-blue);
--bs-body-bg-rgb: #{to-rgb($blue)};
--bs-tertiary-bg: #{$blue-600};
.dropdown-menu {
--bs-dropdown-bg: #{mix($blue-500, $blue-600)};
--bs-dropdown-link-active-bg: #{$blue-700};
}
.btn-secondary {
--bs-btn-bg: #{mix($gray-600, $blue-400, .5)};
--bs-btn-border-color: #{rgba($white, .25)};
--bs-btn-hover-bg: #{darken(mix($gray-600, $blue-400, .5), 5%)};
--bs-btn-hover-border-color: #{rgba($white, .25)};
--bs-btn-active-bg: #{darken(mix($gray-600, $blue-400, .5), 10%)};
--bs-btn-active-border-color: #{rgba($white, .5)};
--bs-btn-focus-border-color: #{rgba($white, .5)};
--bs-btn-focus-box-shadow: 0 0 0 .25rem rgba(255, 255, 255, .2);
}
}
Some paragraph text to show how the blue theme might look with written copy.
<div data-bs-theme="blue">
...
</div>
JavaScript
要允许访问者或用户切换颜色模式,您需要创建一个切换元素来控制根元素<html>
上的 data-bs-theme
属性。我们在文档中创建了一个切换器,它最初会遵从用户当前的系统颜色模式,但提供了一个覆盖该模式并选择特定颜色模式的选项。
下面是为其提供支持的 JavaScript。请随意查看我们自己的文档导航栏,看看它是如何使用我们自己组件的 HTML 和 CSS 实现的。建议将 JavaScript 放在页面顶部,以减少重新加载网站时可能出现的屏幕闪烁。请注意,如果您决定在颜色模式中使用媒体查询,则可能需要修改或删除 JavaScript(如果您喜欢隐式控制)。
/*!
* Color mode toggler for Bootstrap's docs (https://getbootstrap.com/)
* Copyright 2011-2024 The Bootstrap Authors
* Licensed under the Creative Commons Attribution 3.0 Unported License.
*/
(() => {
'use strict'
const getStoredTheme = () => localStorage.getItem('theme')
const setStoredTheme = theme => localStorage.setItem('theme', theme)
const getPreferredTheme = () => {
const storedTheme = getStoredTheme()
if (storedTheme) {
return storedTheme
}
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
}
const setTheme = theme => {
if (theme === 'auto') {
document.documentElement.setAttribute('data-bs-theme', (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'))
} else {
document.documentElement.setAttribute('data-bs-theme', theme)
}
}
setTheme(getPreferredTheme())
const showActiveTheme = (theme, focus = false) => {
const themeSwitcher = document.querySelector('#bd-theme')
if (!themeSwitcher) {
return
}
const themeSwitcherText = document.querySelector('#bd-theme-text')
const activeThemeIcon = document.querySelector('.theme-icon-active use')
const btnToActive = document.querySelector(`[data-bs-theme-value="${theme}"]`)
const svgOfActiveBtn = btnToActive.querySelector('svg use').getAttribute('href')
document.querySelectorAll('[data-bs-theme-value]').forEach(element => {
element.classList.remove('active')
element.setAttribute('aria-pressed', 'false')
})
btnToActive.classList.add('active')
btnToActive.setAttribute('aria-pressed', 'true')
activeThemeIcon.setAttribute('href', svgOfActiveBtn)
const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})`
themeSwitcher.setAttribute('aria-label', themeSwitcherLabel)
if (focus) {
themeSwitcher.focus()
}
}
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
const storedTheme = getStoredTheme()
if (storedTheme !== 'light' && storedTheme !== 'dark') {
setTheme(getPreferredTheme())
}
})
window.addEventListener('DOMContentLoaded', () => {
showActiveTheme(getPreferredTheme())
document.querySelectorAll('[data-bs-theme-value]')
.forEach(toggle => {
toggle.addEventListener('click', () => {
const theme = toggle.getAttribute('data-bs-theme-value')
setStoredTheme(theme)
setTheme(theme)
showActiveTheme(theme, true)
})
})
})
})()
添加主题颜色
在 $theme-colors
中添加新颜色对于我们的某些组件来说是不够的,例如 alerts 和 list groups。对于浅色主题,还必须在$theme-colors-text
、$theme-colors-bg-subtle
和$theme-colors-border-subtle
中定义新颜色;对于深色主题,还必须在$theme-colors-text-dark
、$theme-colors-bg-subtle-dark
和$theme-colors-border-subtle-dark
中定义新颜色。
这是一个手动过程,因为 Sass 无法根据现有变量或映射生成自己的 Sass 变量。在 Bootstrap 的未来版本中,我们将重新审视这一设置,以减少重复。
// 必要的
@import "functions";
@import "variables";
@import "variables-dark";
// 添加自定义颜色到变量 $theme-colors
$custom-colors: (
"custom-color": #712cf9
);
$theme-colors: map-merge($theme-colors, $custom-colors);
@import "maps";
@import "mixins";
@import "utilities";
// 添加一个自定义颜色到新的主题映射
// 浅色模式
$custom-colors-text: ("custom-color": #712cf9);
$custom-colors-bg-subtle: ("custom-color": #e1d2fe);
$custom-colors-border-subtle: ("custom-color": #bfa1fc);
$theme-colors-text: map-merge($theme-colors-text, $custom-colors-text);
$theme-colors-bg-subtle: map-merge($theme-colors-bg-subtle, $custom-colors-bg-subtle);
$theme-colors-border-subtle: map-merge($theme-colors-border-subtle, $custom-colors-border-subtle);
// 深色模式
$custom-colors-text-dark: ("custom-color": #e1d2f2);
$custom-colors-bg-subtle-dark: ("custom-color": #8951fa);
$custom-colors-border-subtle-dark: ("custom-color": #e1d2f2);
$theme-colors-text-dark: map-merge($theme-colors-text-dark, $custom-colors-text-dark);
$theme-colors-bg-subtle-dark: map-merge($theme-colors-bg-subtle-dark, $custom-colors-bg-subtle-dark);
$theme-colors-border-subtle-dark: map-merge($theme-colors-border-subtle-dark, $custom-colors-border-subtle-dark);
// 导入 Bootstrap 的其余部分
@import "root";
@import "reboot";
// etc
CSS
变量
数十个根级 CSS 变量被重复作为深色模式的覆盖变量。这些变量的作用域是颜色模式选择器,其默认值为 data-bs-theme
,但可以配置为使用 prefers-color-scheme
媒体查询。将这些变量作为生成新颜色模式的指南。
--#{$prefix}body-color: #{$body-color-dark};
--#{$prefix}body-color-rgb: #{to-rgb($body-color-dark)};
--#{$prefix}body-bg: #{$body-bg-dark};
--#{$prefix}body-bg-rgb: #{to-rgb($body-bg-dark)};
--#{$prefix}emphasis-color: #{$body-emphasis-color-dark};
--#{$prefix}emphasis-color-rgb: #{to-rgb($body-emphasis-color-dark)};
--#{$prefix}secondary-color: #{$body-secondary-color-dark};
--#{$prefix}secondary-color-rgb: #{to-rgb($body-secondary-color-dark)};
--#{$prefix}secondary-bg: #{$body-secondary-bg-dark};
--#{$prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg-dark)};
--#{$prefix}tertiary-color: #{$body-tertiary-color-dark};
--#{$prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color-dark)};
--#{$prefix}tertiary-bg: #{$body-tertiary-bg-dark};
--#{$prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg-dark)};
@each $color, $value in $theme-colors-text-dark {
--#{$prefix}#{$color}-text-emphasis: #{$value};
}
@each $color, $value in $theme-colors-bg-subtle-dark {
--#{$prefix}#{$color}-bg-subtle: #{$value};
}
@each $color, $value in $theme-colors-border-subtle-dark {
--#{$prefix}#{$color}-border-subtle: #{$value};
}
--#{$prefix}heading-color: #{$headings-color-dark};
--#{$prefix}link-color: #{$link-color-dark};
--#{$prefix}link-hover-color: #{$link-hover-color-dark};
--#{$prefix}link-color-rgb: #{to-rgb($link-color-dark)};
--#{$prefix}link-hover-color-rgb: #{to-rgb($link-hover-color-dark)};
--#{$prefix}code-color: #{$code-color-dark};
--#{$prefix}highlight-color: #{$mark-color-dark};
--#{$prefix}highlight-bg: #{$mark-bg-dark};
--#{$prefix}border-color: #{$border-color-dark};
--#{$prefix}border-color-translucent: #{$border-color-translucent-dark};
--#{$prefix}form-valid-color: #{$form-valid-color-dark};
--#{$prefix}form-valid-border-color: #{$form-valid-border-color-dark};
--#{$prefix}form-invalid-color: #{$form-invalid-color-dark};
--#{$prefix}form-invalid-border-color: #{$form-invalid-border-color-dark};
Sass 变量
深色模式的 CSS 变量部分由 _variables-dark.scss
中特定于深色模式的 Sass 变量生成。其中还包括一些自定义重载,用于更改整个组件中使用的嵌入式 SVG 的颜色。
$primary-text-emphasis-dark: tint-color($primary, 40%);
$secondary-text-emphasis-dark: tint-color($secondary, 40%);
$success-text-emphasis-dark: tint-color($success, 40%);
$info-text-emphasis-dark: tint-color($info, 40%);
$warning-text-emphasis-dark: tint-color($warning, 40%);
$danger-text-emphasis-dark: tint-color($danger, 40%);
$light-text-emphasis-dark: $gray-100;
$dark-text-emphasis-dark: $gray-300;
$primary-bg-subtle-dark: shade-color($primary, 80%);
$secondary-bg-subtle-dark: shade-color($secondary, 80%);
$success-bg-subtle-dark: shade-color($success, 80%);
$info-bg-subtle-dark: shade-color($info, 80%);
$warning-bg-subtle-dark: shade-color($warning, 80%);
$danger-bg-subtle-dark: shade-color($danger, 80%);
$light-bg-subtle-dark: $gray-800;
$dark-bg-subtle-dark: mix($gray-800, $black);
$primary-border-subtle-dark: shade-color($primary, 40%);
$secondary-border-subtle-dark: shade-color($secondary, 40%);
$success-border-subtle-dark: shade-color($success, 40%);
$info-border-subtle-dark: shade-color($info, 40%);
$warning-border-subtle-dark: shade-color($warning, 40%);
$danger-border-subtle-dark: shade-color($danger, 40%);
$light-border-subtle-dark: $gray-700;
$dark-border-subtle-dark: $gray-800;
$body-color-dark: $gray-300;
$body-bg-dark: $gray-900;
$body-secondary-color-dark: rgba($body-color-dark, .75);
$body-secondary-bg-dark: $gray-800;
$body-tertiary-color-dark: rgba($body-color-dark, .5);
$body-tertiary-bg-dark: mix($gray-800, $gray-900, 50%);
$body-emphasis-color-dark: $white;
$border-color-dark: $gray-700;
$border-color-translucent-dark: rgba($white, .15);
$headings-color-dark: inherit;
$link-color-dark: tint-color($primary, 40%);
$link-hover-color-dark: shift-color($link-color-dark, -$link-shade-percentage);
$code-color-dark: tint-color($code-color, 40%);
$mark-color-dark: $body-color-dark;
$mark-bg-dark: $yellow-800;
//
// Forms
//
$form-select-indicator-color-dark: $body-color-dark;
$form-select-indicator-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='#{$form-select-indicator-color-dark}' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/></svg>");
$form-switch-color-dark: rgba($white, .25);
$form-switch-bg-image-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-color-dark}'/></svg>");
$form-valid-color-dark: $green-300;
$form-valid-border-color-dark: $green-300;
$form-invalid-color-dark: $red-300;
$form-invalid-border-color-dark: $red-300;
//
// Accordion
//
$accordion-icon-color-dark: $primary-text-emphasis-dark;
$accordion-icon-active-color-dark: $primary-text-emphasis-dark;
$accordion-button-icon-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-color-dark}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/></svg>");
$accordion-button-active-icon-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-active-color-dark}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/></svg>");
Sass mixins
深色模式的样式,以及你创建的任何自定义颜色模式,都可以通过可定制的 color-mode()
mixin,适当地作用于 data-bs-theme
属性选择器或媒体查询。更多详情,请参阅Sass 使用部分。
@mixin color-mode($mode: light, $root: false) {
@if $color-mode-type == "media-query" {
@if $root == true {
@media (prefers-color-scheme: $mode) {
:root {
@content;
}
}
} @else {
@media (prefers-color-scheme: $mode) {
@content;
}
}
} @else {
[data-bs-theme="#{$mode}"] {
@content;
}
}
}