[PROTO]: handle data-bs-theme differently
:warning: DRAFT - PROTOTYPE
Description
This PR suggests to change the way we handle data-bs-theme by automatically setting color and background-color values with the following rule:
:root,
[data-bs-theme] {
color: var(--#{$prefix}body-color);
background-color: var(--#{$prefix}body-bg);
}
It allows users to set data-bs-theme on any element and have the correct colors applied to it. For example:
<div data-bs-theme="dark">
<h1>Title</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
Based on that statement, it would mean that we could maybe remove some color: var(--bs-{component}-color) and background-color: var(--bs-{component}-bg) rules from our components.
- [ ] Test this theory more in depth
In order to apply this rule within components, color-mode mixin is rewritten to either apply the @content to :root, [data-bs-theme="light"] or [data-bs-theme="{theme}"].
This PR also shows how to fix an issue in our components; for instance where a light accordion is declared within a dark div, its icons have not the right color because we only had the following rule:
@if $enable-dark-mode {
@include color-mode(dark) {
.accordion-button::after {
--#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon-dark)};
--#{$prefix}accordion-btn-active-icon: #{escape-svg($accordion-button-active-icon-dark)};
}
}
}
This issue can be seen in this CodePen
Because of the CSS cascade order, it seems not possible to specify the CSS var with a class because the priority between nested data themes can mess up everything. The idea is to declare those specific CSS variables at the root level:
@include color-mode(light, true) {
--#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon)};
--#{$prefix}accordion-btn-active-icon: #{escape-svg($accordion-button-active-icon)};
}
@if $enable-dark-mode {
@include color-mode(dark, true) {
--#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon-dark)};
--#{$prefix}accordion-btn-active-icon: #{escape-svg($accordion-button-active-icon-dark)};
}
}
This code could have been written in _root.scss since it's a global rule but if we do that for the accordions, when a custom CSS build will be made, the user will have extra useless CSS variables.
In order to check everything, I've create a temporary (or not?) example page: https://deploy-preview-39295--twbs-bootstrap.netlify.app/docs/5.3/examples/dark-mode/
Type of changes
- [x] Refactoring (non-breaking change)
Checklist
- [x] I have read the contributing guidelines
- [x] My code follows the code style of the project (using
npm run lint) - [x] My change introduces changes to the documentation
- (N/A) I have updated the documentation accordingly
- [x] I have added tests to cover my changes
- [x] All new and existing tests passed
Live previews
- https://deploy-preview-39295--twbs-bootstrap.netlify.app/docs/5.3/examples/
- https://deploy-preview-39295--twbs-bootstrap.netlify.app/docs/5.3/examples/dark-mode/
Related issues
-
Closes #39138
-
#39765 might be closed depending on the final content of this PR
-
Closes #39915 (might be closed depending on the final content of this PR and the associated explanation)
-
#40414 might be closed by this PR
-
[ ] TODO
Note to revisit #39977 after I merge it for v5.3.4.
Currently when building with $color-mode-type: media-query; the generated output is void of any [data-bs-theme= (as one would expect) ... except the first set of :root. This is because _root.scss has it hard-coded:
:root,
[data-bs-theme] {
//...
This injects the data tag, ignoring both $enable-dark-mode and $color-mode-type ... even though these are then later used in the dark selection.
May I suggest a localised mixin to remediate this? So the top of _root.scss will be:
@mixin root_root() {
@if not $enable-dark-mode or $color-mode-type == "media-query" {
:root {
@content;
}
} @else {
:root,
[data-bs-theme="light"] {
@content;
}
}
}
@include root_root() {
color-scheme: light;
// Note: Custom variable values only support SassScript inside `#{}`.
//...
Output stays the same for normal/default compile but makes for a cleaner CSS with $enable-dark-mode and $color-mode-type variations. (Obviously come up with a better name than root_root :grimacing: )
(Can also be done in #41232 ?)
[EDIT] Ummmm.. seems carousel, close and navbar also have hardcoded data-bs-theme :frowning: