Skip to content

Commit 825d67d

Browse files
committed
Add dark mode support
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).
1 parent 9f7fb2a commit 825d67d

30 files changed

+561
-171
lines changed

scss/_dropdown.scss

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// stylelint-disable custom-property-empty-line-before
2+
13
// The dropdown wrapper (`<div>`)
24
.dropup,
35
.dropend,
@@ -20,7 +22,7 @@
2022
--#{$variable-prefix}dropdown-padding: #{$dropdown-padding-y $dropdown-padding-x};
2123
--#{$variable-prefix}dropdown-spacer: #{$dropdown-spacer};
2224
@include rfs($dropdown-font-size, --#{$variable-prefix}dropdown-font-size);
23-
--#{$variable-prefix}dropdown-color: #{$dropdown-color}; // stylelint-disable-line custom-property-empty-line-before
25+
--#{$variable-prefix}dropdown-color: #{$dropdown-color};
2426
--#{$variable-prefix}dropdown-bg: #{$dropdown-bg};
2527
--#{$variable-prefix}dropdown-border-color: #{$dropdown-border-color};
2628
--#{$variable-prefix}dropdown-border-radius: #{$dropdown-border-radius};
@@ -165,6 +167,7 @@
165167
white-space: nowrap; // prevent links from randomly breaking onto new lines
166168
background-color: transparent; // For `<button>`s
167169
border: 0; // For `<button>`s
170+
border-radius: var(--#{$variable-prefix}dropdown-item-border-radius, 0); // stylelint-disable-line property-disallowed-list
168171

169172
// Prevent dropdown overflow if there's no padding
170173
// See https://github.com/twbs/bootstrap/pull/27703

scss/_reboot.scss

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ hr {
8787
font-style: $headings-font-style;
8888
font-weight: $headings-font-weight;
8989
line-height: $headings-line-height;
90-
color: $headings-color;
90+
color: var(--#{$variable-prefix}heading-color);
9191
}
9292

9393
h1 {
@@ -243,11 +243,11 @@ sup { top: -.5em; }
243243
// Links
244244

245245
a {
246-
color: $link-color;
246+
color: var(--#{$variable-prefix}link-color);
247247
text-decoration: $link-decoration;
248248

249249
&:hover {
250-
color: $link-hover-color;
250+
color: var(--#{$variable-prefix}link-hover-color);
251251
text-decoration: $link-hover-decoration;
252252
}
253253
}
@@ -298,7 +298,7 @@ pre {
298298

299299
code {
300300
@include font-size($code-font-size);
301-
color: $code-color;
301+
color: var(--#{$variable-prefix}code-color);
302302
word-wrap: break-word;
303303

304304
// Streamline the style when inside anchors to avoid broken underline and more

scss/_root.scss

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
:root {
1+
// stylelint-disable custom-property-empty-line-before
2+
3+
:root,
4+
[data-theme="light"] {
25
// Note: Custom variable values only support SassScript inside `#{}`.
36

47
// Colors
@@ -35,7 +38,7 @@
3538
--#{$variable-prefix}gradient: #{$gradient};
3639

3740
// Root and body
38-
// stylelint-disable custom-property-empty-line-before
41+
3942
// scss-docs-start root-body-variables
4043
@if $font-size-root != null {
4144
--#{$variable-prefix}root-font-size: #{$font-size-root};
@@ -45,10 +48,75 @@
4548
--#{$variable-prefix}body-font-weight: #{$font-weight-base};
4649
--#{$variable-prefix}body-line-height: #{$line-height-base};
4750
--#{$variable-prefix}body-color: #{$body-color};
51+
// --#{$variable-prefix}body-accent-color: #{$body-accent-color};
52+
53+
// todo: replace body-accent-color with secondary-color
54+
--#{$variable-prefix}secondary-color: #{$body-secondary-color};
55+
--#{$variable-prefix}secondary-color-rgb: #{to-rgb($body-secondary-color)};
56+
--#{$variable-prefix}secondary-bg: #{$body-secondary-bg};
57+
--#{$variable-prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg)};
58+
59+
--#{$variable-prefix}tertiary-color: #{$body-tertiary-color};
60+
--#{$variable-prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color)};
61+
--#{$variable-prefix}tertiary-bg: #{$body-tertiary-bg};
62+
--#{$variable-prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg)};
63+
4864
@if $body-text-align != null {
4965
--#{$variable-prefix}body-text-align: #{$body-text-align};
5066
}
5167
--#{$variable-prefix}body-bg: #{$body-bg};
68+
--#{$variable-prefix}body-bg-rgb: #{to-rgb($body-bg)};
5269
// scss-docs-end root-body-variables
53-
// stylelint-enable custom-property-empty-line-before
70+
71+
--#{$variable-prefix}heading-color: #{$headings-color};
72+
--#{$variable-prefix}link-color: #{$link-color};
73+
--#{$variable-prefix}link-hover-color: #{$link-hover-color};
74+
75+
--#{$variable-prefix}code-color: #{$code-color};
76+
77+
--#{$variable-prefix}border-color: #{$border-color};
78+
--#{$variable-prefix}border-style: #{$border-style};
79+
--#{$variable-prefix}border-width: #{$border-width};
80+
81+
// TODO: move to form components? or make global?
82+
--#{$variable-prefix}form-control-bg: var(--#{$variable-prefix}body-bg);
83+
--#{$variable-prefix}form-control-disabled-bg: var(--#{$variable-prefix}secondary-bg);
84+
}
85+
86+
[data-theme="dark"] {
87+
--#{$variable-prefix}primary: #{$blue-300};
88+
--#{$variable-prefix}success: #{$green-300};
89+
--#{$variable-prefix}danger: #{$red-300};
90+
--#{$variable-prefix}warning: #{$yellow-300};
91+
--#{$variable-prefix}info: #{$cyan-300};
92+
93+
--#{$variable-prefix}primary-rgb: #{to-rgb($blue-300)};
94+
--#{$variable-prefix}success-rgb: #{to-rgb($green-300)};
95+
--#{$variable-prefix}danger-rgb: #{to-rgb($red-300)};
96+
--#{$variable-prefix}warning-rgb: #{to-rgb($yellow-300)};
97+
--#{$variable-prefix}info-rgb: #{to-rgb($cyan-300)};
98+
99+
--#{$variable-prefix}body-color: #{$body-color-dark};
100+
--#{$variable-prefix}body-color-rgb: #{to-rgb($body-color-dark)};
101+
--#{$variable-prefix}body-bg: #{$body-bg-dark};
102+
--#{$variable-prefix}body-bg-rgb: #{to-rgb($body-bg-dark)};
103+
104+
--#{$variable-prefix}secondary-color: #{$body-secondary-color-dark};
105+
// --#{$variable-prefix}secondary-color-rgb: #{to-rgb($body-secondary-color-dark)};
106+
--#{$variable-prefix}secondary-bg: #{$body-secondary-bg-dark};
107+
--#{$variable-prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg-dark)};
108+
109+
--#{$variable-prefix}tertiary-color: #{$body-tertiary-color-dark};
110+
// --#{$variable-prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color-dark)};
111+
--#{$variable-prefix}tertiary-bg: #{$body-tertiary-bg-dark};
112+
--#{$variable-prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg-dark)};
113+
114+
--#{$variable-prefix}heading-color: #{$headings-color-dark};
115+
116+
--#{$variable-prefix}link-color: #{$link-color-dark};
117+
--#{$variable-prefix}link-hover-color: #{$link-hover-color-dark};
118+
119+
--#{$variable-prefix}code-color: #{$code-color-dark};
120+
121+
--#{$variable-prefix}border-color: #{$border-color-dark};
54122
}

scss/_utilities.scss

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,37 +99,37 @@ $utilities: map-merge(
9999
"border": (
100100
property: border,
101101
values: (
102-
null: $border-width solid $border-color,
102+
null: var(--#{$variable-prefix}border-width) solid var(--#{$variable-prefix}border-color),
103103
0: 0,
104104
)
105105
),
106106
"border-top": (
107107
property: border-top,
108108
values: (
109-
null: $border-width solid $border-color,
109+
null: var(--#{$variable-prefix}border-width) solid var(--#{$variable-prefix}border-color),
110110
0: 0,
111111
)
112112
),
113113
"border-end": (
114114
property: border-right,
115115
class: border-end,
116116
values: (
117-
null: $border-width solid $border-color,
117+
null: var(--#{$variable-prefix}border-width) solid var(--#{$variable-prefix}border-color),
118118
0: 0,
119119
)
120120
),
121121
"border-bottom": (
122122
property: border-bottom,
123123
values: (
124-
null: $border-width solid $border-color,
124+
null: var(--#{$variable-prefix}border-width) solid var(--#{$variable-prefix}border-color),
125125
0: 0,
126126
)
127127
),
128128
"border-start": (
129129
property: border-left,
130130
class: border-start,
131131
values: (
132-
null: $border-width solid $border-color,
132+
null: var(--#{$variable-prefix}border-width) solid var(--#{$variable-prefix}border-color),
133133
0: 0,
134134
)
135135
),
@@ -523,6 +523,8 @@ $utilities: map-merge(
523523
"muted": $text-muted,
524524
"black-50": rgba($black, .5), // deprecated
525525
"white-50": rgba($white, .5), // deprecated
526+
"body-secondary": var(--#{$variable-prefix}secondary-color),
527+
"body-tertiary": var(--#{$variable-prefix}tertiary-color),
526528
"reset": inherit,
527529
)
528530
)
@@ -548,7 +550,9 @@ $utilities: map-merge(
548550
values: map-merge(
549551
$utilities-bg-colors,
550552
(
551-
"transparent": transparent
553+
"transparent": transparent,
554+
"body-secondary": rgba(var(--#{$variable-prefix}secondary-bg-rgb), var(--#{$variable-prefix}bg-opacity)),
555+
"body-tertiary": rgba(var(--#{$variable-prefix}tertiary-bg-rgb), var(--#{$variable-prefix}bg-opacity)),
552556
)
553557
)
554558
),

scss/_variables.scss

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,24 @@ $position-values: (
396396
//
397397
// Settings for the `<body>` element.
398398

399-
$body-bg: $white !default;
400-
$body-color: $gray-900 !default;
401399
$body-text-align: null !default;
400+
$body-color: $gray-900 !default;
401+
$body-bg: $white !default;
402+
403+
$body-color-dark: $gray-500 !default;
404+
$body-bg-dark: $gray-900 !default;
405+
406+
$body-secondary-color: rgba($body-color, .75) !default;
407+
$body-secondary-bg: $gray-200 !default;
408+
409+
$body-tertiary-color: rgba($body-color, .5) !default;
410+
$body-tertiary-bg: $gray-100 !default;
411+
412+
$body-secondary-color-dark: rgba($body-color-dark, .75) !default;
413+
$body-secondary-bg-dark: $gray-800 !default;
414+
415+
$body-tertiary-color-dark: rgba($body-color-dark, .5) !default;
416+
$body-tertiary-bg-dark: mix($gray-800, $gray-900, 50%) !default;
402417

403418
// Links
404419
//
@@ -413,6 +428,9 @@ $link-hover-decoration: null !default;
413428
$stretched-link-pseudo-element: after !default;
414429
$stretched-link-z-index: 1 !default;
415430

431+
$link-color-dark: $blue-300 !default;
432+
$link-hover-color-dark: $blue-200 !default;
433+
416434
// Paragraphs
417435
//
418436
// Style p element.
@@ -483,8 +501,9 @@ $border-widths: (
483501
4: 4px,
484502
5: 5px
485503
) !default;
486-
487-
$border-color: $gray-300 !default;
504+
$border-style: solid !default;
505+
$border-color: rgba($black, .15) !default;
506+
$border-color-dark: rgba($white, .15) !default;
488507
// scss-docs-end border-variables
489508

490509
// scss-docs-start border-radius-variables
@@ -588,6 +607,7 @@ $headings-font-style: null !default;
588607
$headings-font-weight: 500 !default;
589608
$headings-line-height: 1.2 !default;
590609
$headings-color: null !default;
610+
$headings-color-dark: #fff !default;
591611
// scss-docs-end headings-variables
592612

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

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

663-
$table-color: $body-color !default;
683+
$table-color: null !default;
664684
$table-bg: transparent !default;
665685
$table-accent-bg: transparent !default;
666686

@@ -820,12 +840,12 @@ $input-padding-y-lg: $input-btn-padding-y-lg !default;
820840
$input-padding-x-lg: $input-btn-padding-x-lg !default;
821841
$input-font-size-lg: $input-btn-font-size-lg !default;
822842

823-
$input-bg: $body-bg !default;
824-
$input-disabled-bg: $gray-200 !default;
843+
$input-bg: var(--#{$variable-prefix}form-control-bg) !default;
844+
$input-disabled-bg: var(--#{$variable-prefix}form-control-disabled-bg) !default;
825845
$input-disabled-border-color: null !default;
826846

827-
$input-color: $body-color !default;
828-
$input-border-color: $gray-400 !default;
847+
$input-color: var(--#{$variable-prefix}body-color) !default;
848+
$input-border-color: var(--#{$variable-prefix}border-color) !default; //$gray-400
829849
$input-border-width: $input-btn-border-width !default;
830850
$input-box-shadow: $box-shadow-inset !default;
831851

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

871891
$form-check-input-bg: $input-bg !default;
872-
$form-check-input-border: 1px solid rgba($black, .25) !default;
892+
$form-check-input-border: var(--#{$variable-prefix}border-width) solid var(--#{$variable-prefix}border-color) !default;
873893
$form-check-input-border-radius: .25em !default;
874894
$form-check-radio-border-radius: 50% !default;
875895
$form-check-input-focus-border: $input-focus-border-color !default;
@@ -1128,19 +1148,19 @@ $dropdown-padding-x: 0 !default;
11281148
$dropdown-padding-y: .5rem !default;
11291149
$dropdown-spacer: .125rem !default;
11301150
$dropdown-font-size: $font-size-base !default;
1131-
$dropdown-color: $body-color !default;
1132-
$dropdown-bg: $white !default;
1133-
$dropdown-border-color: rgba($black, .15) !default;
1151+
$dropdown-color: var(--#{$variable-prefix}body-color) !default;
1152+
$dropdown-bg: var(--#{$variable-prefix}body-bg) !default;
1153+
$dropdown-border-color: var(--#{$variable-prefix}border-color) !default;
11341154
$dropdown-border-radius: $border-radius !default;
11351155
$dropdown-border-width: $border-width !default;
11361156
$dropdown-inner-border-radius: subtract($dropdown-border-radius, $dropdown-border-width) !default;
11371157
$dropdown-divider-bg: $dropdown-border-color !default;
11381158
$dropdown-divider-margin-y: $spacer * .5 !default;
11391159
$dropdown-box-shadow: $box-shadow !default;
11401160

1141-
$dropdown-link-color: $gray-900 !default;
1142-
$dropdown-link-hover-color: shade-color($dropdown-link-color, 10%) !default;
1143-
$dropdown-link-hover-bg: $gray-200 !default;
1161+
$dropdown-link-color: var(--#{$variable-prefix}body-color) !default;
1162+
$dropdown-link-hover-color: $dropdown-link-color !default;
1163+
$dropdown-link-hover-bg: var(--#{$variable-prefix}tertiary-bg) !default;
11441164

11451165
$dropdown-link-active-color: $component-active-color !default;
11461166
$dropdown-link-active-bg: $component-active-bg !default;
@@ -1591,8 +1611,8 @@ $offcanvas-transition-duration: .3s !default;
15911611
$offcanvas-border-color: $modal-content-border-color !default;
15921612
$offcanvas-border-width: $modal-content-border-width !default;
15931613
$offcanvas-title-line-height: $modal-title-line-height !default;
1594-
$offcanvas-bg-color: $modal-content-bg !default;
1595-
$offcanvas-color: $modal-content-color !default;
1614+
$offcanvas-bg-color: var(--#{$variable-prefix}body-bg) !default;
1615+
$offcanvas-color: var(--#{$variable-prefix}body-color) !default;
15961616
$offcanvas-box-shadow: $modal-content-box-shadow-xs !default;
15971617
$offcanvas-backdrop-bg: $modal-backdrop-bg !default;
15981618
$offcanvas-backdrop-opacity: $modal-backdrop-opacity !default;
@@ -1602,6 +1622,7 @@ $offcanvas-backdrop-opacity: $modal-backdrop-opacity !default;
16021622

16031623
$code-font-size: $small-font-size !default;
16041624
$code-color: $pink !default;
1625+
$code-color-dark: $pink-300 !default;
16051626

16061627
$kbd-padding-y: .2rem !default;
16071628
$kbd-padding-x: .4rem !default;

0 commit comments

Comments
 (0)