Color modes

CoreUI now supports color modes, or themes, as of v5.0.0. Explore our default light color mode and the new dark mode, or create your own using our styles as your template.

Try it yourself! Download the source code and working demo for using CoreUI for Bootstrap with Stylelint, and the color modes from the twbs/examples repository. You can also open the example in StackBlitz.

Dark mode

CoreUI for Bootstrap now supports color modes, starting with dark mode! With v5.0.0 you can implement your own color mode toggler (see below for an example from CoreUI for Bootstrap’s docs) 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-coreui-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.

Example

For example, to change the color mode of a dropdown menu, add data-coreui-theme="light" or data-coreui-theme="dark" to the parent .dropdown. Now, no matter the global color mode, these dropdowns will display with the specified theme value.

html
<div class="dropdown" data-coreui-theme="light">
  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButtonLight" data-coreui-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-coreui-theme="dark">
  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButtonDark" data-coreui-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>

How it works

  • As shown above, color mode styles are controlled by the data-coreui-theme attribute. This attribute can be applied to the <html> element, or to any other element or CoreUI for Bootstrap 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-coreui-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-coreui-theme attribute applied. Building on the quick start template:

<!doctype html>
<html lang="en" data-coreui-theme="dark">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>CoreUI for Bootstrap demo</title>
    <link href="https://cdn.jsdelivr.net/npm/@coreui/[email protected]/dist/css/coreui.min.css" rel="stylesheet" integrity="sha384-kzZuZpWDubFVbc6rjWJo7yIstiGYZINkrUlJRa8qd1UcEy+7PRI/fUd1kAAACFAB" crossorigin="anonymous">
  </head>
  <body>
    <h1>Hello, world!</h1>
    <script src="https://cdn.jsdelivr.net/npm/@coreui/[email protected]/dist/js/coreui.bundle.min.js" integrity="sha384-5NxMv75IP7CLKF29WBrmqLX5uQcA+32rVe4dAPsc2GY/4nT8JWZwDmWzJ+GnvRS+" crossorigin="anonymous"></script>
  </body>
</html>

CoreUI for Bootstrap does not yet ship with a built-in color mode picker, but you can use the one from our own documentation if you like. Learn more in the JavaScript section.

Building with Sass

Our new dark mode option is available to use for all users of CoreUI for Bootstrap, 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(--cui-primary-text-emphasis);
    background-color: var(--cui-primary-bg-subtle);
  }
}

Outputs to:

[data-coreui-theme=dark] .element {
  color: var(--cui-primary-text-emphasis);
  background-color: var(--cui-primary-bg-subtle);
}

And when setting to media-query:

$color-mode-type: media-query;

@include color-mode(dark) {
  .element {
    color: var(--cui-primary-text-emphasis);
    background-color: var(--cui-primary-bg-subtle);
  }
}

Outputs to:

@media (prefers-color-scheme: dark) {
  .element {
    color: var(--cui-primary-text-emphasis);
    background-color: var(--cui-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-coreui-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 CoreUI for 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-coreui-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-coreui-theme="blue"] {
  --cui-body-color: var(--cui-white);
  --cui-body-color-rgb: #{to-rgb($white)};
  --cui-body-bg: var(--cui-blue);
  --cui-body-bg-rgb: #{to-rgb($blue)};
  --cui-tertiary-bg: #{$blue-600};

  .dropdown-menu {
    --cui-dropdown-bg: #{mix($blue-500, $blue-600)};
    --cui-dropdown-link-active-bg: #{$blue-700};
  }

  .btn-secondary {
    --cui-btn-bg: #{mix($gray-600, $blue-400, .5)};
    --cui-btn-border-color: #{rgba($white, .25)};
    --cui-btn-hover-bg: #{darken(mix($gray-600, $blue-400, .5), 5%)};
    --cui-btn-hover-border-color: #{rgba($white, .25)};
    --cui-btn-active-bg: #{darken(mix($gray-600, $blue-400, .5), 10%)};
    --cui-btn-active-border-color: #{rgba($white, .5)};
    --cui-btn-focus-border-color: #{rgba($white, .5)};
    --cui-btn-focus-box-shadow: 0 0 0 .25rem rgba(255, 255, 255, .2);
  }
}
Example blue theme

Some paragraph text to show how the blue theme might look with written copy.


<div data-coreui-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-coreui-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 look at the JavaScript that powers it. Feel free to inspect our own documentation navbar to 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. Note that if you decide to use media queries for your color modes, your JavaScript may need to be modified or removed if you prefer an implicit control.

/*!
 * Color mode toggler for CoreUI's docs (https://coreui.io/)
 * Copyright (c) 2023 creativeLabs Łukasz Holeczek
 * Licensed under the Creative Commons Attribution 3.0 Unported License.
 */

(() => {
  'use strict'

  const THEME = 'coreui-docs-theme'

  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' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
      document.documentElement.setAttribute('data-coreui-theme', 'dark')
    } else {
      document.documentElement.setAttribute('data-coreui-theme', theme)
    }
  }

  setTheme(getPreferredTheme())

  const showActiveTheme = theme => {
    const activeThemeIcon = document.querySelector('.theme-icon-active')
    const btnToActive = document.querySelector(`[data-coreui-theme-value="${theme}"]`)
    const svgOfActiveBtn = btnToActive.querySelector('svg.theme-icon')

    document.querySelectorAll('[data-coreui-theme-value]').forEach(element => {
      element.classList.remove('active')
    })

    btnToActive.classList.add('active')
    activeThemeIcon.innerHTML = svgOfActiveBtn.innerHTML
  }

  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-coreui-theme-value]')
      .forEach(toggle => {
        toggle.addEventListener('click', () => {
          const theme = toggle.getAttribute('data-coreui-theme-value')
          setStoredTheme(theme)
          setTheme(theme)
          showActiveTheme(theme)
        })
      })
  })
})()

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 of Bootstrap, 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 Bootstrap imports
@import "root";
@import "reboot";
// etc

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-coreui-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)};

--#{$prefix}high-emphasis: #{$body-color-dark};
--#{$prefix}medium-emphasis: #{$body-secondary-color-dark};
--#{$prefix}disabled: #{$body-tertiary-color-dark};

--#{$prefix}elevation-base-color: 0, 0, 0;

@each $color, $value in $theme-colors-dark {
  --#{$prefix}#{$color}: #{$value};
}

@each $color, $value in $grays-dark {
  --#{$prefix}gray-#{$color}: #{$value};
}

@each $color, $value in $theme-colors-rgb-dark {
  --#{$prefix}#{$color}-rgb: #{$value};
}

@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};
}

@each $color, $value in $theme-gradients-dark {
  --#{$prefix}#{$color}-start: #{map-get($value, "start")};
  --#{$prefix}#{$color}-stop: #{map-get($value, "stop")};
}

--#{$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};

Sass variables

CSS variables for our dark color mode are partially generated from dark mode specific Sass variables in _variables-dark.scss. This also includes some custom overrides for changing the colors of embedded SVGs used throughout our components.

// scss-docs-start gray-color-dark-variables
$gray-100-dark: #f3f4f7;
$gray-200-dark: #e7eaee;
$gray-300-dark: #dbdfe6;
$gray-400-dark: #cfd4de;
$gray-500-dark: #aab3c5;
$gray-600-dark: #6d7d9c;
$gray-700-dark: #4a566d;
$gray-800-dark: #323a49;
$gray-900-dark: #212631;
// scss-docs-end gray-color-dark-variables

// fusv-disable
// scss-docs-start gray-colors-dark-map
$grays-dark: (
  "100": $gray-100-dark,
  "200": $gray-200-dark,
  "300": $gray-300-dark,
  "400": $gray-400-dark,
  "500": $gray-500-dark,
  "600": $gray-600-dark,
  "700": $gray-700-dark,
  "800": $gray-800-dark,
  "900": $gray-900-dark
);
// scss-docs-end gray-colors-dark-map
// fusv-enable

// scss-docs-start theme-color-dark-variables
$primary-dark:       tint-color(desaturate($primary, 20%), 20%);
$secondary-dark:     desaturate($secondary, 10%);
$success-dark:       desaturate($success, 10%);
$info-dark:          desaturate($info, 10%);
$warning-dark:       desaturate($warning, 10%);
$danger-dark:        desaturate($danger, 10%);
$light-dark:         desaturate($light, 10%);
$dark-dark:          desaturate($dark, 10%);
// scss-docs-end theme-color-dark-variables

// scss-docs-start theme-colors-dark-map
$theme-colors-dark: (
  "primary":    $primary-dark,
  "secondary":  $secondary-dark,
  "success":    $success-dark,
  "info":       $info-dark,
  "warning":    $warning-dark,
  "danger":     $danger-dark,
  "light":      $light-dark,
  "dark":       $dark-dark
);
// scss-docs-end theme-colors-dark-map

// scss-docs-start theme-text-dark-variables
$primary-text-emphasis-dark:        $primary-text-emphasis;
$secondary-text-emphasis-dark:      $secondary-text-emphasis;
$success-text-emphasis-dark:        $success-text-emphasis;
$info-text-emphasis-dark:           $info-text-emphasis;
$warning-text-emphasis-dark:        $warning-text-emphasis;
$danger-text-emphasis-dark:         $danger-text-emphasis;
$light-text-emphasis-dark:          $gray-100-dark;
$dark-text-emphasis-dark:           $gray-300-dark;
// scss-docs-end theme-text-dark-variables

// scss-docs-start theme-bg-subtle-dark-variables
$primary-bg-subtle-dark:            $primary-bg-subtle;
$secondary-bg-subtle-dark:          $secondary-bg-subtle;
$success-bg-subtle-dark:            $success-bg-subtle;
$info-bg-subtle-dark:               $info-bg-subtle;
$warning-bg-subtle-dark:            $warning-bg-subtle;
$danger-bg-subtle-dark:             $danger-bg-subtle;
$light-bg-subtle-dark:              $gray-800-dark;
$dark-bg-subtle-dark:               mix($gray-800-dark, $black);
// scss-docs-end theme-bg-subtle-dark-variables

// scss-docs-start theme-border-subtle-dark-variables
$primary-border-subtle-dark:        $primary-border-subtle;
$secondary-border-subtle-dark:      $secondary-border-subtle;
$success-border-subtle-dark:        $success-border-subtle;
$info-border-subtle-dark:           $info-border-subtle;
$warning-border-subtle-dark:        $warning-border-subtle;
$danger-border-subtle-dark:         $danger-border-subtle;
$light-border-subtle-dark:          $gray-700-dark;
$dark-border-subtle-dark:           $gray-800-dark;
// scss-docs-end theme-border-subtle-dark-variables

// Gradients

// scss-docs-start theme-gradients-dark-variables
$primary-gradient-dark: (
  "start":  desaturate(#321fdb, 20%),
  "stop":   desaturate(#1f1498, 20%)
);

$secondary-gradient-dark: (
  "start":  desaturate(#c8d2dc, 20%),
  "stop":   desaturate($white, 20%)
);

$light-gradient-dark: (
  "start":  desaturate(#e3e8ed, 20%),
  "stop":   desaturate($white, 20%)
);

$dark-gradient-dark: (
  "start":  desaturate(#3c4b64, 20%),
  "stop":   desaturate(#212333, 20%)
);

$danger-gradient-dark: (
  "start":  desaturate(#e55353, 20%),
  "stop":   desaturate(#d93737, 20%)
);

$warning-gradient-dark: (
  "start":  desaturate(#f9b115, 20%),
  "stop":   desaturate(#f6960b, 20%)
);

$success-gradient-dark: (
  "start":  desaturate(#2eb85c, 20%),
  "stop":   desaturate(#1b9e3e, 20%)
);

$info-gradient-dark: (
  "start":  desaturate(#39f, 20%),
  "stop":   desaturate(#2982cc, 20%)
);

$theme-gradients-dark: (
  "primary":    $primary-gradient-dark,
  "secondary":  $secondary-gradient-dark,
  "success":    $success-gradient-dark,
  "info":       $info-gradient-dark,
  "warning":    $warning-gradient-dark,
  "danger":     $danger-gradient-dark,
  "light":      $light-gradient-dark,
  "dark":       $dark-gradient-dark
);
// scss-docs-end theme-gradients-dark-variables

$body-color-dark:                   $gray-500-dark;
$body-bg-dark:                      $gray-900-dark;
$body-secondary-color-dark:         rgba($body-color-dark, .75);
$body-secondary-bg-dark:            $gray-800-dark;
$body-tertiary-color-dark:          rgba($body-color-dark, .5);
$body-tertiary-bg-dark:             mix($gray-800-dark, #181924, 50%);
$body-emphasis-color-dark:          $white;
$border-color-dark:                 $gray-700-dark;
$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%);


//
// 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>");

// scss-docs-start form-validation-colors-dark
$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;
// scss-docs-end form-validation-colors-dark


//
// Accordion
//

$accordion-icon-color-dark:         $body-color-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-.708z'/></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-.708z'/></svg>");


//
// Buttons
//

$button-variants-dark: (
  "primary":    btn-color-map($primary-dark, $primary-dark),
  "secondary":  btn-color-map($secondary-dark, $secondary-dark),
  "success":    btn-color-map($success-dark, $success-dark),
  "danger":     btn-color-map($danger-dark, $danger-dark),
  "warning":    btn-color-map($warning-dark, $warning-dark),
  "info":       btn-color-map($info-dark, $info-dark)
);

$button-outline-ghost-variants-dark: (
  "primary":    btn-outline-color-map($primary-dark),
  "secondary":  btn-outline-color-map($secondary-dark),
  "success":    btn-outline-color-map($success-dark),
  "danger":     btn-outline-color-map($danger-dark),
  "warning":    btn-outline-color-map($warning-dark),
  "info":       btn-outline-color-map($info-dark)
);

//
// Calendar
//

$calendar-nav-icon-double-next-color-dark:        $body-tertiary-color-dark;
$calendar-nav-icon-double-next-dark:              url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$calendar-nav-icon-double-next-color-dark}' points='95.314 447.313 72.686 424.687 245.373 252 72.686 79.313 95.314 56.687 290.627 252 95.314 447.313'></polygon><polygon fill='#{$calendar-nav-icon-double-next-color-dark}' points='255.314 447.313 232.686 424.687 405.373 252 232.686 79.313 255.314 56.687 450.627 252 255.314 447.313'></polygon></svg>");
$calendar-nav-icon-double-next-hover-color-dark:  $body-color-dark;
$calendar-nav-icon-double-next-hover-dark:        url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$calendar-nav-icon-double-next-hover-color-dark}' points='95.314 447.313 72.686 424.687 245.373 252 72.686 79.313 95.314 56.687 290.627 252 95.314 447.313'></polygon><polygon fill='#{$calendar-nav-icon-double-next-hover-color-dark}' points='255.314 447.313 232.686 424.687 405.373 252 232.686 79.313 255.314 56.687 450.627 252 255.314 447.313'></polygon></svg>");

$calendar-nav-icon-double-prev-color-dark:        $body-tertiary-color-dark;
$calendar-nav-icon-double-prev-dark:              url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$calendar-nav-icon-double-prev-color-dark}' points='416.686 447.313 221.373 252 416.686 56.687 439.314 79.313 266.627 252 439.314 424.687 416.686 447.313'></polygon><polygon fill='#{$calendar-nav-icon-double-prev-color-dark}' points='256.686 447.313 61.373 252 256.686 56.687 279.314 79.313 106.627 252 279.314 424.687 256.686 447.313'></polygon></svg>");
$calendar-nav-icon-double-prev-hover-color-dark:  $body-color-dark;
$calendar-nav-icon-double-prev-hover-dark:        url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$calendar-nav-icon-double-prev-hover-color-dark}' points='416.686 447.313 221.373 252 416.686 56.687 439.314 79.313 266.627 252 439.314 424.687 416.686 447.313'></polygon><polygon fill='#{$calendar-nav-icon-double-prev-hover-color-dark}' points='256.686 447.313 61.373 252 256.686 56.687 279.314 79.313 106.627 252 279.314 424.687 256.686 447.313'></polygon></svg>");

$calendar-nav-icon-next-color-dark:               $body-tertiary-color-dark;
$calendar-nav-icon-next-dark:                     url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$calendar-nav-icon-next-color-dark}' points='179.313 451.313 156.687 428.687 329.372 256 156.687 83.313 179.313 60.687 374.627 256 179.313 451.313'></polygon></svg>");
$calendar-nav-icon-next-hover-color-dark:         $body-color-dark;
$calendar-nav-icon-next-hover-dark:               url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$calendar-nav-icon-next-hover-color-dark}' points='179.313 451.313 156.687 428.687 329.372 256 156.687 83.313 179.313 60.687 374.627 256 179.313 451.313'></polygon></svg>");

$calendar-nav-icon-prev-color-dark:               $body-tertiary-color-dark;
$calendar-nav-icon-prev-dark:                     url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$calendar-nav-icon-prev-color-dark}' points='324.687 451.313 129.373 256 324.687 60.687 347.313 83.313 174.628 256 347.313 428.687 324.687 451.313'></polygon></svg>");
$calendar-nav-icon-prev-hover-color-dark:         $body-color-dark;
$calendar-nav-icon-prev-hover-dark:               url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$calendar-nav-icon-prev-hover-color-dark}' points='324.687 451.313 129.373 256 324.687 60.687 347.313 83.313 174.628 256 347.313 428.687 324.687 451.313'></polygon></svg>");

//
// Date Picker
//

$date-picker-cleaner-icon-color-dark:        $body-tertiary-color-dark;
$date-picker-cleaner-icon-dark:              url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$date-picker-cleaner-icon-color-dark}' points='306.912 214.461 256 265.373 205.088 214.461 182.461 237.088 233.373 288 182.461 338.912 205.088 361.539 256 310.627 306.912 361.539 329.539 338.912 278.627 288 329.539 237.088 306.912 214.461'></polygon><path fill='#{$date-picker-cleaner-icon-color-dark}' d='M472,96H384V40H352V96H160V40H128V96H40a24.028,24.028,0,0,0-24,24V456a24.028,24.028,0,0,0,24,24H472a24.028,24.028,0,0,0,24-24V120A24.028,24.028,0,0,0,472,96Zm-8,352H48V128h80v40h32V128H352v40h32V128h80Z'></path></svg>");
$date-picker-cleaner-icon-hover-color-dark:  $body-color-dark;
$date-picker-cleaner-icon-hover-dark:        url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$date-picker-cleaner-icon-hover-color-dark}' points='306.912 214.461 256 265.373 205.088 214.461 182.461 237.088 233.373 288 182.461 338.912 205.088 361.539 256 310.627 306.912 361.539 329.539 338.912 278.627 288 329.539 237.088 306.912 214.461'></polygon><path fill='#{$date-picker-cleaner-icon-hover-color-dark}' d='M472,96H384V40H352V96H160V40H128V96H40a24.028,24.028,0,0,0-24,24V456a24.028,24.028,0,0,0,24,24H472a24.028,24.028,0,0,0,24-24V120A24.028,24.028,0,0,0,472,96Zm-8,352H48V128h80v40h32V128H352v40h32V128h80Z'></path></svg>");

$date-picker-indicator-icon-color-dark:      $body-tertiary-color-dark;
$date-picker-indicator-icon-dark:            url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><path fill='#{$date-picker-indicator-icon-color-dark}' d='M472,96H384V40H352V96H160V40H128V96H40a24.028,24.028,0,0,0-24,24V456a24.028,24.028,0,0,0,24,24H472a24.028,24.028,0,0,0,24-24V120A24.028,24.028,0,0,0,472,96Zm-8,352H48V128h80v40h32V128H352v40h32V128h80Z'></path><rect width='32' height='32' x='112' y='224' fill='#{$date-picker-indicator-icon-color-dark}'></rect><rect width='32' height='32' x='200' y='224' fill='#{$date-picker-indicator-icon-color-dark}'></rect><rect width='32' height='32' x='280' y='224' fill='#{$date-picker-indicator-icon-color-dark}'></rect><rect width='32' height='32' x='368' y='224' fill='#{$date-picker-indicator-icon-color-dark}'></rect><rect width='32' height='32' x='112' y='296' fill='#{$date-picker-indicator-icon-color-dark}'></rect><rect width='32' height='32' x='200' y='296' fill='#{$date-picker-indicator-icon-color-dark}'></rect><rect width='32' height='32' x='280' y='296' fill='#{$date-picker-indicator-icon-color-dark}'></rect><rect width='32' height='32' x='368' y='296' fill='#{$date-picker-indicator-icon-color-dark}'></rect><rect width='32' height='32' x='112' y='368' fill='#{$date-picker-indicator-icon-color-dark}'></rect><rect width='32' height='32' x='200' y='368' fill='#{$date-picker-indicator-icon-color-dark}'></rect><rect width='32' height='32' x='280' y='368' fill='#{$date-picker-indicator-icon-color-dark}'></rect><rect width='32' height='32' x='368' y='368' fill='#{$date-picker-indicator-icon-color-dark}'></rect></svg>");
$date-picker-indicator-invalid-icon-dark:    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><path fill='#{$form-invalid-color}' d='M472,96H384V40H352V96H160V40H128V96H40a24.028,24.028,0,0,0-24,24V456a24.028,24.028,0,0,0,24,24H472a24.028,24.028,0,0,0,24-24V120A24.028,24.028,0,0,0,472,96Zm-8,352H48V128h80v40h32V128H352v40h32V128h80Z'></path><rect width='32' height='32' x='112' y='224' fill='#{$form-invalid-color}'></rect><rect width='32' height='32' x='200' y='224' fill='#{$form-invalid-color}'></rect><rect width='32' height='32' x='280' y='224' fill='#{$form-invalid-color}'></rect><rect width='32' height='32' x='368' y='224' fill='#{$form-invalid-color}'></rect><rect width='32' height='32' x='112' y='296' fill='#{$form-invalid-color}'></rect><rect width='32' height='32' x='200' y='296' fill='#{$form-invalid-color}'></rect><rect width='32' height='32' x='280' y='296' fill='#{$form-invalid-color}'></rect><rect width='32' height='32' x='368' y='296' fill='#{$form-invalid-color}'></rect><rect width='32' height='32' x='112' y='368' fill='#{$form-invalid-color}'></rect><rect width='32' height='32' x='200' y='368' fill='#{$form-invalid-color}'></rect><rect width='32' height='32' x='280' y='368' fill='#{$form-invalid-color}'></rect><rect width='32' height='32' x='368' y='368' fill='#{$form-invalid-color}'></rect></svg>");
$date-picker-indicator-valid-icon-dark:      url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><path fill='#{$form-valid-color}' d='M472,96H384V40H352V96H160V40H128V96H40a24.028,24.028,0,0,0-24,24V456a24.028,24.028,0,0,0,24,24H472a24.028,24.028,0,0,0,24-24V120A24.028,24.028,0,0,0,472,96Zm-8,352H48V128h80v40h32V128H352v40h32V128h80Z'></path><rect width='32' height='32' x='112' y='224' fill='#{$form-valid-color}'></rect><rect width='32' height='32' x='200' y='224' fill='#{$form-valid-color}'></rect><rect width='32' height='32' x='280' y='224' fill='#{$form-valid-color}'></rect><rect width='32' height='32' x='368' y='224' fill='#{$form-valid-color}'></rect><rect width='32' height='32' x='112' y='296' fill='#{$form-valid-color}'></rect><rect width='32' height='32' x='200' y='296' fill='#{$form-valid-color}'></rect><rect width='32' height='32' x='280' y='296' fill='#{$form-valid-color}'></rect><rect width='32' height='32' x='368' y='296' fill='#{$form-valid-color}'></rect><rect width='32' height='32' x='112' y='368' fill='#{$form-valid-color}'></rect><rect width='32' height='32' x='200' y='368' fill='#{$form-valid-color}'></rect><rect width='32' height='32' x='280' y='368' fill='#{$form-valid-color}'></rect><rect width='32' height='32' x='368' y='368' fill='#{$form-valid-color}'></rect></svg>");

$date-picker-separator-icon-color-dark:      $body-tertiary-color-dark;
$date-picker-separator-icon-dark:            url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$date-picker-separator-icon-color-dark}' points='359.873 121.377 337.246 144.004 433.243 240.001 16 240.001 16 240.002 16 272.001 16 272.002 433.24 272.002 337.246 367.996 359.873 390.623 494.498 256 359.873 121.377'></polygon></svg>");
$date-picker-separator-icon-rtl-dark:        url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$date-picker-separator-icon-color-dark}' points='497.333 239.999 80.092 239.999 176.087 144.004 153.46 121.377 18.837 256 153.46 390.623 176.087 367.996 80.09 271.999 497.333 271.999 497.333 239.999'></polygon></svg>");

//
// Multi Select
//

$form-multi-select-tag-delete-color-dark:          $body-tertiary-color-dark;
$form-multi-select-tag-delete-bg-dark:             url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$form-multi-select-tag-delete-color-dark}'><path d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/></svg>");
$form-multi-select-tag-delete-hover-color-dark:    $body-color-dark;
$form-multi-select-tag-delete-hover-bg-dark:       url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$form-multi-select-tag-delete-hover-color-dark}'><path d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/></svg>");
$form-multi-select-tag-delete-focus-color-dark:    $body-color-dark;
$form-multi-select-tag-delete-focus-bg-dark:       url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$form-multi-select-tag-delete-focus-color-dark}'><path d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/></svg>");

$form-multi-select-cleaner-color-dark:             $body-tertiary-color-dark;
$form-multi-select-cleaner-bg-dark:                url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$form-multi-select-cleaner-color-dark}'><path d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/></svg>");
$form-multi-select-cleaner-hover-color-dark:       $body-color-dark;
$form-multi-select-cleaner-hover-bg-dark:          url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$form-multi-select-cleaner-hover-color-dark}'><path d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/></svg>");
$form-multi-select-cleaner-focus-color-dark:       $body-color-dark;
$form-multi-select-cleaner-focus-bg-dark:          url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$form-multi-select-cleaner-focus-color-dark}'><path d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/></svg>");

$form-multi-select-indicator-color-dark:           $body-tertiary-color-dark;
$form-multi-select-indicator-bg-dark:              url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' fill='#{$form-multi-select-indicator-color-dark}'><path d='M256.045 416.136.717 160.807l29.579-29.579 225.749 225.748 225.749-225.748 29.579 29.579-255.328 255.329z'/></svg>");
$form-multi-select-indicator-hover-color-dark:     $body-color-dark;
$form-multi-select-indicator-hover-bg-dark:        url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' fill='#{$form-multi-select-indicator-hover-color-dark}'><path d='M256.045 416.136.717 160.807l29.579-29.579 225.749 225.748 225.749-225.748 29.579 29.579-255.328 255.329z'/></svg>");
$form-multi-select-indicator-focus-color-dark:     $body-color-dark;
$form-multi-select-indicator-focus-bg-dark:        url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' fill='#{$form-multi-select-indicator-focus-color-dark}'><path d='M256.045 416.136.717 160.807l29.579-29.579 225.749 225.748 225.749-225.748 29.579 29.579-255.328 255.329z'/></svg>");

//
// Time Picker
//

$time-picker-cleaner-icon-color-dark:        $body-tertiary-color-dark;
$time-picker-cleaner-icon-dark:              url("data:image/svg+ xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$time-picker-cleaner-icon-color-dark}' points='348.071 141.302 260.308 229.065 172.545 141.302 149.917 163.929 237.681 251.692 149.917 339.456 172.545 362.083 260.308 274.32 348.071 362.083 370.699 339.456 282.935 251.692 370.699 163.929 348.071 141.302'></polygon><path fill='#{$time-picker-cleaner-icon-color-dark}' d='M425.706,86.294A240,240,0,0,0,86.294,425.706,240,240,0,0,0,425.706,86.294ZM256,464C141.309,464,48,370.691,48,256S141.309,48,256,48s208,93.309,208,208S370.691,464,256,464Z'></path></svg>");
$time-picker-cleaner-icon-hover-color-dark:  $body-color-dark;
$time-picker-cleaner-icon-hover-dark:        url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$time-picker-cleaner-icon-hover-color-dark}  ts='348.071 141.302 260.308 229.065 172.545 141.302 149.917 163.929 237.681 251.692 149.917 339.456 172.545 362.083 260.308 274.32 348.071 362.083 370.699 339.456 282.935 251.692 370.699 163.929 348.071 141.302'></polygon><path fill='#{$time-picker-cleaner-icon-hover-color-dark}  425.706,86.294A240,240,0,0,0,86.294,425.706,240,240,0,0,0,425.706,86.294ZM256,464C141.309,464,48,370.691,48,256S141.309,48,256,48s208,93.309,208,208S370.691,464,256,464Z'></path></svg>");

$time-picker-indicator-icon-color-dark:      $body-tertiary-color-dark;
$time-picker-indicator-icon-dark:            url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$time-picker-indicator-icon-color-dark}' points='271.514 95.5 239.514 95.5 239.514 273.611 355.127 328.559 368.864 299.657 271.514 253.389 271.514 95.5'></polygon><path fill='#{$time-picker-indicator-icon-color-dark}' d='M256,16C123.452,16,16,123.452,16,256S123.452,496,256,496,496,388.548,496,256,388.548,16,256,16Zm0,448C141.125,464,48,370.875,48,256S141.125,48,256,48s208,93.125,208,208S370.875,464,256,464Z'></path></svg>");
$time-picker-indicator-invalid-icon-dark:    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$form-invalid-color-dark}' points='271.514 95.5 239.514 95.5 239.514 273.611 355.127 328.559 368.864 299.657 271.514 253.389 271.514 95.5'></polygon><path fill='#{$form-invalid-color-dark}' d='M256,16C123.452,16,16,123.452,16,256S123.452,496,256,496,496,388.548,496,256,388.548,16,256,16Zm0,448C141.125,464,48,370.875,48,256S141.125,48,256,48s208,93.125,208,208S370.875,464,256,464Z'></path></svg>");
$time-picker-indicator-valid-icon-dark:      url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' role='img'><polygon fill='#{$form-valid-color-dark}' points='271.514 95.5 239.514 95.5 239.514 273.611 355.127 328.559 368.864 299.657 271.514 253.389 271.514 95.5'></polygon><path fill='#{$form-valid-color-dark}' d='M256,16C123.452,16,16,123.452,16,256S123.452,496,256,496,496,388.548,496,256,388.548,16,256,16Zm0,448C141.125,464,48,370.875,48,256S141.125,48,256,48s208,93.125,208,208S370.875,464,256,464Z'></path></svg>");

//
// Sidebar
//

$sidebar-bg-dark:            $body-bg-dark;
$sidebar-border-width-dark:  var(--#{$prefix}border-width);
$sidebar-border-color-dark:  var(--#{$prefix}border-color);

Sass mixins

Styles for dark mode, and any custom color modes you create, can be scoped appropriately to the data-coreui-theme attribute selector or media query with the customizable color-mode() mixin. See the Sass usage section 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 {
    .#{$mode}-theme, // TODO: remove in v5
    [data-coreui-theme="#{$mode}"] {
      @content;
    }
  }
}