Color modes
Bootstrap 5 Color modes
MDB now supports color modes, or themes, as of v7.0.0. Explore our default light color mode and the new dark mode, or create your own using our styles as your template.
Dark mode
MDB now supports color modes, starting with dark mode! With v7.0.0 you can implement
your own color mode toggler (see below for an example) and apply the different color modes
as you see fit. We support a light mode (default) and now dark mode. Color modes can be toggled globally on the
<html>
element, or on specific components and elements, thanks to the
data-mdb-theme
attribute.
Alternatively, you can also switch to a media query implementation thanks to our color mode mixin—see the usage section for details. Heads up though—this eliminates your ability to change themes on a per-component basis as shown below.
Enable color mode for a specific component
You can also change the mode to dark only for the specific component. For example, to change the color mode of a
card, add data-mdb-theme="light"
or
data-mdb-theme="dark"
to the div with .card
class. Now, no matter the global color mode,
these cards will display with the specified theme value.
Card title
Some quick example text to build on the card title and make up the bulk of the card's content.
Card title
Some quick example text to build on the card title and make up the bulk of the card's content.
<div class="row gx-lg-5">
<div class="col-lg-6 mb-5 mb-lg-0">
<div class="card" data-mdb-theme="light">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<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>
<button type="button" class="btn btn-primary" data-mdb-ripple-init>Button</button>
</div>
</div>
</div>
<div class="col-lg-6 mb-5 mb-lg-0">
<div class="card" data-mdb-theme="dark">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<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>
<button type="button" class="btn btn-primary" data-mdb-ripple-init>Button</button>
</div>
</div>
</div>
</div>
How it works
-
As shown above, color mode styles are controlled by the
data-mdb-theme
attribute. This attribute can be applied to the<html>
element, or to any other element or MDB component. If applied to the<html>
element, it will apply to everything. If applied to a component or element, it will be scoped to that specific component or element. -
For each color mode you wish to support, you’ll need to add new overrides for the shared global CSS variables. We do this already in our
_root.scss
stylesheet for dark mode, with light mode being the default values. In writing color mode specific styles, use the mixin:// Color mode variables in _root.scss @include color-mode(dark) { // CSS variable overrides here... }
-
We use a custom
_variables-dark.scss
to power those shared global CSS variable overrides for dark mode. This file isn’t required for your own custom color modes, but it’s required for our dark mode for two reasons. First, it’s better to have a single place to reset global colors. Second, some Sass variables had to be overridden for background images embedded in our CSS for accordions, form components, and more.
Usage
Enable dark mode
Enable the built in dark color mode across your entire project by adding the data-mdb-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-mdb-theme
attribute applied.
<!doctype html>
<html lang="en" data-mdb-theme="dark">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MDBootstrap demo</title>
<!-- Font Awesome -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet" />
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
rel="stylesheet" />
<!-- MDB -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/7.0.0/mdb.min.css" rel="stylesheet" />
</head>
<body>
<h1>Hello, world!</h1>
<!-- MDB -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/7.0.0/mdb.min.js">
</script>
</body>
</html>
Building with Sass
Our new dark mode option is available to use for all users of MDBootstrap, but it’s controlled via data
attributes instead of media queries and does not automatically toggle your project’s color mode. You can disable
our dark mode entirely via Sass by changing $enable-dark-mode
to false
.
We use a custom Sass mixin, color-mode()
, to help you control how color modes are
applied. By default, we use a data
attribute approach, allowing you to create more user-friendly
experiences where your visitors can choose to have an automatic dark mode or control their preference (like in
our own docs here). This is also an easy and scalable way to add different themes and more custom color modes
beyond light and dark.
In case you want to use media queries and only make color modes automatic, you can change the mixin’s default type via Sass variable. Consider the following snippet and its compiled CSS output.
$color-mode-type: data;
@include color-mode(dark) {
.element {
color: var(--mdb-primary-text-emphasis);
background-color: var(--mdb-primary-bg-subtle);
}
}
Outputs to:
[data-mdb-theme=dark] .element {
color: var(--mdb-primary-text-emphasis);
background-color: var(--mdb-primary-bg-subtle);
}
And when setting to media-query
:
$color-mode-type: media-query;
@include color-mode(dark) {
.element {
color: var(--mdb-primary-text-emphasis);
background-color: var(--mdb-primary-bg-subtle);
}
}
Outputs to:
@media (prefers-color-scheme: dark) {
.element {
color: var(--mdb-primary-text-emphasis);
background-color: var(--mdb-primary-bg-subtle);
}
}
Custom color modes
While the primary use case for color modes is light and dark mode, custom color modes are also possible. Create
your own data-mdb-theme
selector with a custom value as the name of your color mode, then modify our
Sass and CSS variables as needed. We opted to create a separate _variables-dark.scss
stylesheet to
house Bootstrap’s dark mode specific Sass variables, but that’s not required for you.
For example, you can create a “blue theme” with the selector data-mdb-theme="blue"
. In your custom
Sass or CSS file, add the new selector and override any global or component CSS variables as needed. If you’re
using Sass, you can also use Sass’s functions within your CSS variable overrides.
[data-mdb-theme="blue"] {
--mdb-body-color: var(--mdb-white);
--mdb-body-color-rgb: #{to-rgb($white)};
--mdb-body-bg: var(--mdb-blue);
--mdb-body-bg-rgb: #{to-rgb($blue)};
--mdb-tertiary-bg: #{$blue-600};
.dropdown-menu {
--mdb-dropdown-bg: #{mix($blue-500, $blue-600)};
--mdb-dropdown-link-active-bg: #{$blue-700};
}
.btn-outline-secondary {
--mdb-btn-bg: #{mix($gray-600, $blue-400, .5)};
--mdb-btn-color: var(--mdb-white);
--mdb-btn-border-color: var(--mdb-white);
--mdb-btn-hover-bg: #{darken(mix($gray-600, $blue-400, .5), 5%)};
--mdb-btn-hover-border-color: #{rgba($white, .25)};
--mdb-btn-active-bg: #{darken(mix($gray-600, $blue-400, .5), 10%)};
--mdb-btn-active-border-color: #{rgba($white, .5)};
--mdb-btn-focus-border-color: #{rgba($white, .5)};
--mdb-btn-focus-box-shadow: 0 0 0 .25rem rgba(255, 255, 255, .2);
--mdb-btn-hover-color: var(--mdb-white);
--mdb-btn-outline-focus-border-color: #{rgba($white, .5)};
--mdb-btn-active-color: #{rgba($white, .5)};
}
}
Some paragraph text to show how the blue theme might look with written copy.
<div data-mdb-theme="blue">
...
</div>
JavaScript
To allow visitors or users to toggle color modes, you’ll need to create a toggle element to control the
data-mdb-theme
attribute on the root element, <html>
. We’ve built a toggler in our
documentation that initially defers to a user’s current system color mode, but provides an option to override that
and pick a specific color mode.
Here’s a simplified version of code we used in own documentation navbar. You can see how it’s implemented using HTML and CSS from our own components. It is suggested to include the JavaScript at the top of your page to reduce potential screen flickering during reloading of your site.
<li class="nav-item align-items-center d-flex" >
<i class="fas fa-sun"></i>
<!-- Default switch -->
<div class="ms-2 form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="themingSwitcher" />
</div>
<i class="fas fa-moon"></i>
</li>
Place the code from the snippet below in JS file that you will link on every page at the end of a
<body>
tag. This code will check your system default settings and set theme based on that.
const themeStitcher = document.getElementById("themingSwitcher");
const isSystemThemeSetToDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
// set toggler position based on system theme
if (isSystemThemeSetToDark) {
themeStitcher.checked = true;
}
// add listener to theme toggler
themeStitcher.addEventListener("change", (e) => {
toggleTheme(e.target.checked);
});
const toggleTheme = (isChecked) => {
const theme = isChecked ? "dark" : "light";
document.documentElement.dataset.mdbTheme = theme;
}
// add listener to toggle theme with Shift + D
document.addEventListener("keydown", (e) => {
if (e.shiftKey && e.key === "D") {
themeStitcher.checked = !themeStitcher.checked;
toggleTheme(themeStitcher.checked);
}
});
The last part is added in the head of an head
of a <html>
page. It prevents
flickering of the colors by setting the saved theme before the whole page is loaded.
<script>
const isSystemThemeSetToDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
if (isSystemThemeSetToDark) {
document.documentElement.dataset.mdbTheme = "dark";
};
</script>
Adding theme colors
Adding a new color in $theme-colors
is not enough for some of our components like alerts and list groups.
New colors must also be defined in $theme-colors-text
, $theme-colors-bg-subtle
, and
$theme-colors-border-subtle
for light theme; but also in $theme-colors-text-dark
,
$theme-colors-bg-subtle-dark
, and $theme-colors-border-subtle-dark
for dark theme.
This is a manual process because Sass cannot generate its own Sass variables from an existing variable or map. In future versions, we’ll revisit this setup to reduce the duplication.
// Required
@import "functions";
@import "variables";
@import "variables-dark";
// Add a custom color to $theme-colors
$custom-colors: (
"custom-color": #712cf9
);
$theme-colors: map-merge($theme-colors, $custom-colors);
@import "maps";
@import "mixins";
@import "utilities";
// Add a custom color to new theme maps
// Light mode
$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);
// Dark mode
$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);
// Remainder of MDB imports
@import "root";
@import "reboot";
// etc
Color modes - API
CSS variables
Dozens of root level CSS variables are repeated as overrides for dark mode. These are scoped to the color mode
selector, which defaults to data-mdb-theme
but can be configured to
use a prefers-color-scheme
media query. Use these variables as a guideline for generating your own
new color modes.
--#{$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}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};
--#{$prefix}surface-color: #{$surface-color-dark};
--#{$prefix}surface-color-rgb: #{to-rgb($surface-color-dark)};
--#{$prefix}surface-bg: #{$surface-bg-dark};
--#{$prefix}surface-inverted-color: #{$surface-inverted-color-dark};
--#{$prefix}surface-inverted-color-rgb: #{to-rgb($surface-inverted-color-dark)};
--#{$prefix}surface-inverted-bg: #{$surface-inverted-bg-dark};
--#{$prefix}divider-color: #{$divider-color-dark};
--#{$prefix}highlight-bg-color: #{$highlight-bg-color-dark};
--#{$prefix}scrollbar-rail-bg: #{$scrollbar-rail-bg-dark};
--#{$prefix}scrollbar-thumb-bg: #{$scrollbar-thumb-bg-dark};
--#{$prefix}picker-header-bg: #{$picker-header-bg-dark};
--#{$prefix}timepicker-clock-face-bg: #{$timepicker-clock-face-bg-dark};
--#{$prefix}sidenav-backdrop-opacity: #{$sidenav-backdrop-opacity-dark};
--#{$prefix}form-control-border-color: #{$form-control-border-color-dark};
--#{$prefix}form-control-label-color: #{$form-control-label-color-dark};
--#{$prefix}form-control-disabled-bg: #{$form-control-disabled-bg-dark};
--#{$prefix}box-shadow-color: #{$box-shadow-color-dark};
--#{$prefix}box-shadow-color-rgb: #{to-rgb($box-shadow-color-dark)};
--#{$prefix}stepper-mobile-bg: #{$stepper-mobile-bg-dark};
SCSS variables
$primary-text-emphasis-dark: tint-color($primary, 20%) !default;
$secondary-text-emphasis-dark: tint-color($secondary, 60%) !default;
$success-text-emphasis-dark: tint-color($success, 40%) !default;
$info-text-emphasis-dark: tint-color($info, 30%) !default;
$warning-text-emphasis-dark: tint-color($warning, 40%) !default;
$danger-text-emphasis-dark: tint-color($danger, 20%) !default;
$light-text-emphasis-dark: $gray-100 !default;
$dark-text-emphasis-dark: $gray-200 !default;
$primary-bg-subtle-dark: shade-color($primary, 80%) !default;
$secondary-bg-subtle-dark: shade-color($secondary, 80%) !default;
$success-bg-subtle-dark: shade-color($success, 80%) !default;
$info-bg-subtle-dark: shade-color($info, 80%) !default;
$warning-bg-subtle-dark: shade-color($warning, 80%) !default;
$danger-bg-subtle-dark: shade-color($danger, 80%) !default;
$light-bg-subtle-dark: $gray-800 !default;
$dark-bg-subtle-dark: $gray-900 !default;
$primary-border-subtle-dark: shade-color($primary, 40%) !default;
$secondary-border-subtle-dark: shade-color($secondary, 40%) !default;
$success-border-subtle-dark: shade-color($success, 40%) !default;
$info-border-subtle-dark: shade-color($info, 40%) !default;
$warning-border-subtle-dark: shade-color($warning, 40%) !default;
$danger-border-subtle-dark: shade-color($danger, 40%) !default;
$light-border-subtle-dark: $gray-700 !default;
$dark-border-subtle-dark: $gray-800 !default;
$body-color-dark: $white !default;
$body-bg-dark: #303030 !default;
$body-secondary-bg-dark: $gray-200 !default;
$border-color-dark: rgba(255, 255, 255, 0.12) !default;
$border-color-translucent-dark: rgba($white, 0.15) !default;
$surface-color-dark: $white !default;
$surface-bg-dark: #424242 !default;
$surface-inverted-color-dark: $white !default;
$surface-inverted-bg-dark: #757575 !default;
$divider-color-dark: rgba(255, 255, 255, 0.12) !default;
$highlight-bg-color-dark: rgba(255, 255, 255, 0.3) !default;
$scrollbar-rail-bg-dark: $gray-500 !default;
$scrollbar-thumb-bg-dark: $gray-200 !default;
$picker-header-bg-dark: #323232 !default;
$timepicker-clock-face-bg-dark: $gray-700 !default;
$sidenav-backdrop-opacity-dark: 0.5 !default;
$form-control-border-color-dark: rgba(255, 255, 255, 0.7) !default;
$form-control-label-color-dark: $gray-400 !default;
$form-control-disabled-bg-dark: $gray-700 !default;
$box-shadow-color-dark: $black !default;
$stepper-mobile-bg-dark: $gray-800 !default;
// Accordion
$accordion-icon-color-dark: $surface-color-dark !default;
$accordion-icon-active-color-dark: $primary !default;
Sass mixins
Styles for dark mode, and any custom color modes you create, can be scoped appropriately to the
data-mdb-theme
attribute selector or media query with the customizable color-mode()
mixin. See the Sass usage section in the Overview tab for more details.
@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-mdb-theme='#{$mode}'] {
@content;
}
}
}