Skip to content

Commit

Permalink
Add dark mode support
Browse files Browse the repository at this point in the history
Heavily WIP still, but this begins the process of implementing dark mode for our docs and across the project itself.

- Color modes are toggled in the docs navbar with a custom toggler, which stores the select color mode in local storage.
- Color modes can also be set via data attribute thanks to `data-theme` (with light or dark options available currently).
- Docs are heavily WIP for demonstrating the dark mode.
- In order to best implement color modes, I've spiked out a number of new Sass and CSS variables (e.g., `--bs-secondary-bg` and `--bs-tertiary-bg`). In addition, I've added new global CSS variables like `--bs-border-color` and more. So, in addition to general color modes and theming support, we get greater real-time customization, too.

Todos and open questions:

- [ ] Do we refer to these as themes or color modes?
- [ ] Do we provide a color mode toggler JS plugin?
- [ ] Update all components to better utilize global CSS variables so they can be more easily themed (e.g., see `$dropdown-*` Sass variable changes in the diff).
  • Loading branch information
mdo committed Feb 24, 2022
1 parent e4fd8c0 commit 2ce19a3
Show file tree
Hide file tree
Showing 30 changed files with 561 additions and 171 deletions.
5 changes: 4 additions & 1 deletion scss/_dropdown.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// stylelint-disable custom-property-empty-line-before

// The dropdown wrapper (`<div>`)
.dropup,
.dropend,
Expand All @@ -20,7 +22,7 @@
--#{$variable-prefix}dropdown-padding: #{$dropdown-padding-y $dropdown-padding-x};
--#{$variable-prefix}dropdown-spacer: #{$dropdown-spacer};
@include rfs($dropdown-font-size, --#{$variable-prefix}dropdown-font-size);
--#{$variable-prefix}dropdown-color: #{$dropdown-color}; // stylelint-disable-line custom-property-empty-line-before
--#{$variable-prefix}dropdown-color: #{$dropdown-color};
--#{$variable-prefix}dropdown-bg: #{$dropdown-bg};
--#{$variable-prefix}dropdown-border-color: #{$dropdown-border-color};
--#{$variable-prefix}dropdown-border-radius: #{$dropdown-border-radius};
Expand Down Expand Up @@ -165,6 +167,7 @@
white-space: nowrap; // prevent links from randomly breaking onto new lines
background-color: transparent; // For `<button>`s
border: 0; // For `<button>`s
border-radius: var(--#{$variable-prefix}dropdown-item-border-radius, 0); // stylelint-disable-line property-disallowed-list

// Prevent dropdown overflow if there's no padding
// See https://github.com/twbs/bootstrap/pull/27703
Expand Down
8 changes: 4 additions & 4 deletions scss/_reboot.scss
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ hr {
font-style: $headings-font-style;
font-weight: $headings-font-weight;
line-height: $headings-line-height;
color: $headings-color;
color: var(--#{$variable-prefix}heading-color);
}

h1 {
Expand Down Expand Up @@ -243,11 +243,11 @@ sup { top: -.5em; }
// Links

a {
color: $link-color;
color: var(--#{$variable-prefix}link-color);
text-decoration: $link-decoration;

&:hover {
color: $link-hover-color;
color: var(--#{$variable-prefix}link-hover-color);
text-decoration: $link-hover-decoration;
}
}
Expand Down Expand Up @@ -298,7 +298,7 @@ pre {

code {
@include font-size($code-font-size);
color: $code-color;
color: var(--#{$variable-prefix}code-color);
word-wrap: break-word;

// Streamline the style when inside anchors to avoid broken underline and more
Expand Down
74 changes: 71 additions & 3 deletions scss/_root.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
:root {
// stylelint-disable custom-property-empty-line-before

:root,
[data-theme="light"] {
// Note: Custom variable values only support SassScript inside `#{}`.

// Colors
Expand Down Expand Up @@ -35,7 +38,7 @@
--#{$variable-prefix}gradient: #{$gradient};

// Root and body
// stylelint-disable custom-property-empty-line-before

// scss-docs-start root-body-variables
@if $font-size-root != null {
--#{$variable-prefix}root-font-size: #{$font-size-root};
Expand All @@ -45,10 +48,75 @@
--#{$variable-prefix}body-font-weight: #{$font-weight-base};
--#{$variable-prefix}body-line-height: #{$line-height-base};
--#{$variable-prefix}body-color: #{$body-color};
// --#{$variable-prefix}body-accent-color: #{$body-accent-color};

// todo: replace body-accent-color with secondary-color
--#{$variable-prefix}secondary-color: #{$body-secondary-color};
--#{$variable-prefix}secondary-color-rgb: #{to-rgb($body-secondary-color)};
--#{$variable-prefix}secondary-bg: #{$body-secondary-bg};
--#{$variable-prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg)};

--#{$variable-prefix}tertiary-color: #{$body-tertiary-color};
--#{$variable-prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color)};
--#{$variable-prefix}tertiary-bg: #{$body-tertiary-bg};
--#{$variable-prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg)};

@if $body-text-align != null {
--#{$variable-prefix}body-text-align: #{$body-text-align};
}
--#{$variable-prefix}body-bg: #{$body-bg};
--#{$variable-prefix}body-bg-rgb: #{to-rgb($body-bg)};
// scss-docs-end root-body-variables
// stylelint-enable custom-property-empty-line-before

--#{$variable-prefix}heading-color: #{$headings-color};
--#{$variable-prefix}link-color: #{$link-color};
--#{$variable-prefix}link-hover-color: #{$link-hover-color};

--#{$variable-prefix}code-color: #{$code-color};

--#{$variable-prefix}border-color: #{$border-color};
--#{$variable-prefix}border-style: #{$border-style};
--#{$variable-prefix}border-width: #{$border-width};

// TODO: move to form components? or make global?
--#{$variable-prefix}form-control-bg: var(--#{$variable-prefix}body-bg);
--#{$variable-prefix}form-control-disabled-bg: var(--#{$variable-prefix}secondary-bg);
}

[data-theme="dark"] {
--#{$variable-prefix}primary: #{$blue-300};
--#{$variable-prefix}success: #{$green-300};
--#{$variable-prefix}danger: #{$red-300};
--#{$variable-prefix}warning: #{$yellow-300};
--#{$variable-prefix}info: #{$cyan-300};

--#{$variable-prefix}primary-rgb: #{to-rgb($blue-300)};
--#{$variable-prefix}success-rgb: #{to-rgb($green-300)};
--#{$variable-prefix}danger-rgb: #{to-rgb($red-300)};
--#{$variable-prefix}warning-rgb: #{to-rgb($yellow-300)};
--#{$variable-prefix}info-rgb: #{to-rgb($cyan-300)};

--#{$variable-prefix}body-color: #{$body-color-dark};
--#{$variable-prefix}body-color-rgb: #{to-rgb($body-color-dark)};
--#{$variable-prefix}body-bg: #{$body-bg-dark};
--#{$variable-prefix}body-bg-rgb: #{to-rgb($body-bg-dark)};

--#{$variable-prefix}secondary-color: #{$body-secondary-color-dark};
// --#{$variable-prefix}secondary-color-rgb: #{to-rgb($body-secondary-color-dark)};
--#{$variable-prefix}secondary-bg: #{$body-secondary-bg-dark};
--#{$variable-prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg-dark)};

--#{$variable-prefix}tertiary-color: #{$body-tertiary-color-dark};
// --#{$variable-prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color-dark)};
--#{$variable-prefix}tertiary-bg: #{$body-tertiary-bg-dark};
--#{$variable-prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg-dark)};

--#{$variable-prefix}heading-color: #{$headings-color-dark};

--#{$variable-prefix}link-color: #{$link-color-dark};
--#{$variable-prefix}link-hover-color: #{$link-hover-color-dark};

--#{$variable-prefix}code-color: #{$code-color-dark};

--#{$variable-prefix}border-color: #{$border-color-dark};
}
16 changes: 10 additions & 6 deletions scss/_utilities.scss
Original file line number Diff line number Diff line change
Expand Up @@ -99,37 +99,37 @@ $utilities: map-merge(
"border": (
property: border,
values: (
null: $border-width solid $border-color,
null: var(--#{$variable-prefix}border-width) solid var(--#{$variable-prefix}border-color),
0: 0,
)
),
"border-top": (
property: border-top,
values: (
null: $border-width solid $border-color,
null: var(--#{$variable-prefix}border-width) solid var(--#{$variable-prefix}border-color),
0: 0,
)
),
"border-end": (
property: border-right,
class: border-end,
values: (
null: $border-width solid $border-color,
null: var(--#{$variable-prefix}border-width) solid var(--#{$variable-prefix}border-color),
0: 0,
)
),
"border-bottom": (
property: border-bottom,
values: (
null: $border-width solid $border-color,
null: var(--#{$variable-prefix}border-width) solid var(--#{$variable-prefix}border-color),
0: 0,
)
),
"border-start": (
property: border-left,
class: border-start,
values: (
null: $border-width solid $border-color,
null: var(--#{$variable-prefix}border-width) solid var(--#{$variable-prefix}border-color),
0: 0,
)
),
Expand Down Expand Up @@ -523,6 +523,8 @@ $utilities: map-merge(
"muted": $text-muted,
"black-50": rgba($black, .5), // deprecated
"white-50": rgba($white, .5), // deprecated
"body-secondary": var(--#{$variable-prefix}secondary-color),
"body-tertiary": var(--#{$variable-prefix}tertiary-color),
"reset": inherit,
)
)
Expand All @@ -548,7 +550,9 @@ $utilities: map-merge(
values: map-merge(
$utilities-bg-colors,
(
"transparent": transparent
"transparent": transparent,
"body-secondary": rgba(var(--#{$variable-prefix}secondary-bg-rgb), var(--#{$variable-prefix}bg-opacity)),
"body-tertiary": rgba(var(--#{$variable-prefix}tertiary-bg-rgb), var(--#{$variable-prefix}bg-opacity)),
)
)
),
Expand Down
57 changes: 39 additions & 18 deletions scss/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -396,9 +396,24 @@ $position-values: (
//
// Settings for the `<body>` element.

$body-bg: $white !default;
$body-color: $gray-900 !default;
$body-text-align: null !default;
$body-color: $gray-900 !default;
$body-bg: $white !default;

$body-color-dark: $gray-500 !default;
$body-bg-dark: $gray-900 !default;

$body-secondary-color: rgba($body-color, .75) !default;
$body-secondary-bg: $gray-200 !default;

$body-tertiary-color: rgba($body-color, .5) !default;
$body-tertiary-bg: $gray-100 !default;

$body-secondary-color-dark: rgba($body-color-dark, .75) !default;
$body-secondary-bg-dark: $gray-800 !default;

$body-tertiary-color-dark: rgba($body-color-dark, .5) !default;
$body-tertiary-bg-dark: mix($gray-800, $gray-900, 50%) !default;

// Links
//
Expand All @@ -413,6 +428,9 @@ $link-hover-decoration: null !default;
$stretched-link-pseudo-element: after !default;
$stretched-link-z-index: 1 !default;

$link-color-dark: $blue-300 !default;
$link-hover-color-dark: $blue-200 !default;

// Paragraphs
//
// Style p element.
Expand Down Expand Up @@ -483,8 +501,9 @@ $border-widths: (
4: 4px,
5: 5px
) !default;

$border-color: $gray-300 !default;
$border-style: solid !default;
$border-color: rgba($black, .15) !default;
$border-color-dark: rgba($white, .15) !default;
// scss-docs-end border-variables

// scss-docs-start border-radius-variables
Expand Down Expand Up @@ -588,6 +607,7 @@ $headings-font-style: null !default;
$headings-font-weight: 500 !default;
$headings-line-height: 1.2 !default;
$headings-color: null !default;
$headings-color-dark: #fff !default;
// scss-docs-end headings-variables

// scss-docs-start display-headings
Expand Down Expand Up @@ -660,7 +680,7 @@ $table-cell-padding-x-sm: .25rem !default;

$table-cell-vertical-align: top !default;

$table-color: $body-color !default;
$table-color: null !default;
$table-bg: transparent !default;
$table-accent-bg: transparent !default;

Expand Down Expand Up @@ -820,12 +840,12 @@ $input-padding-y-lg: $input-btn-padding-y-lg !default;
$input-padding-x-lg: $input-btn-padding-x-lg !default;
$input-font-size-lg: $input-btn-font-size-lg !default;

$input-bg: $body-bg !default;
$input-disabled-bg: $gray-200 !default;
$input-bg: var(--#{$variable-prefix}form-control-bg) !default;
$input-disabled-bg: var(--#{$variable-prefix}form-control-disabled-bg) !default;
$input-disabled-border-color: null !default;

$input-color: $body-color !default;
$input-border-color: $gray-400 !default;
$input-color: var(--#{$variable-prefix}body-color) !default;
$input-border-color: var(--#{$variable-prefix}border-color) !default; //$gray-400
$input-border-width: $input-btn-border-width !default;
$input-box-shadow: $box-shadow-inset !default;

Expand Down Expand Up @@ -869,7 +889,7 @@ $form-check-transition: null !default;
$form-check-input-active-filter: brightness(90%) !default;

$form-check-input-bg: $input-bg !default;
$form-check-input-border: 1px solid rgba($black, .25) !default;
$form-check-input-border: var(--#{$variable-prefix}border-width) solid var(--#{$variable-prefix}border-color) !default;
$form-check-input-border-radius: .25em !default;
$form-check-radio-border-radius: 50% !default;
$form-check-input-focus-border: $input-focus-border-color !default;
Expand Down Expand Up @@ -1128,19 +1148,19 @@ $dropdown-padding-x: 0 !default;
$dropdown-padding-y: .5rem !default;
$dropdown-spacer: .125rem !default;
$dropdown-font-size: $font-size-base !default;
$dropdown-color: $body-color !default;
$dropdown-bg: $white !default;
$dropdown-border-color: rgba($black, .15) !default;
$dropdown-color: var(--#{$variable-prefix}body-color) !default;
$dropdown-bg: var(--#{$variable-prefix}body-bg) !default;
$dropdown-border-color: var(--#{$variable-prefix}border-color) !default;
$dropdown-border-radius: $border-radius !default;
$dropdown-border-width: $border-width !default;
$dropdown-inner-border-radius: subtract($dropdown-border-radius, $dropdown-border-width) !default;
$dropdown-divider-bg: $dropdown-border-color !default;
$dropdown-divider-margin-y: $spacer * .5 !default;
$dropdown-box-shadow: $box-shadow !default;

$dropdown-link-color: $gray-900 !default;
$dropdown-link-hover-color: shade-color($dropdown-link-color, 10%) !default;
$dropdown-link-hover-bg: $gray-200 !default;
$dropdown-link-color: var(--#{$variable-prefix}body-color) !default;
$dropdown-link-hover-color: $dropdown-link-color !default;
$dropdown-link-hover-bg: var(--#{$variable-prefix}tertiary-bg) !default;

$dropdown-link-active-color: $component-active-color !default;
$dropdown-link-active-bg: $component-active-bg !default;
Expand Down Expand Up @@ -1591,8 +1611,8 @@ $offcanvas-transition-duration: .3s !default;
$offcanvas-border-color: $modal-content-border-color !default;
$offcanvas-border-width: $modal-content-border-width !default;
$offcanvas-title-line-height: $modal-title-line-height !default;
$offcanvas-bg-color: $modal-content-bg !default;
$offcanvas-color: $modal-content-color !default;
$offcanvas-bg-color: var(--#{$variable-prefix}body-bg) !default;
$offcanvas-color: var(--#{$variable-prefix}body-color) !default;
$offcanvas-box-shadow: $modal-content-box-shadow-xs !default;
$offcanvas-backdrop-bg: $modal-backdrop-bg !default;
$offcanvas-backdrop-opacity: $modal-backdrop-opacity !default;
Expand All @@ -1602,6 +1622,7 @@ $offcanvas-backdrop-opacity: $modal-backdrop-opacity !default;

$code-font-size: $small-font-size !default;
$code-color: $pink !default;
$code-color-dark: $pink-300 !default;

$kbd-padding-y: .2rem !default;
$kbd-padding-x: .4rem !default;
Expand Down
Loading

0 comments on commit 2ce19a3

Please sign in to comment.