no-color-scheme-on-docusaurus-html-root
Disallow color-scheme declarations on Docusaurus root selectors managed by the framework.
Targeted pattern scopeโ
This rule walks all color-scheme property declarations and reports any that appear inside a CSS rule whose selector (or comma-separated selector list) matches one of the Docusaurus-managed root selectors:
:roothtml[data-theme][data-theme="dark"]/[data-theme='dark'][data-theme="light"]/[data-theme='light']html[data-theme]html[data-theme="dark"]/html[data-theme='dark']html[data-theme="light"]/html[data-theme='light']
What this rule reportsโ
A color-scheme declaration inside a rule that targets any of the selectors listed above.
Why this rule existsโ
Docusaurus manages the page's color-scheme through its own theme-switching mechanism, which sets the color-scheme CSS property on the <html> element programmatically at runtime. Overriding this from custom CSS interferes with that mechanism in subtle ways:
color-scheme: darkset on:rootcan prevent Docusaurus's light-mode from fully applying system-widget light styles (for example scrollbars, form inputs, date pickers).- Overriding
color-schemeon[data-theme]may produce a momentary flash when the theme toggle fires, because the JS and CSS updates race. - The Docusaurus team may change how
color-schemeis managed between minor releases; a CSS override may silently stop working or start conflicting.
The correct approach is to let Docusaurus manage color-scheme entirely, and use [data-theme="dark"] / [data-theme="light"] selectors only for setting values of other custom properties.
โ Incorrectโ
/* Overrides the color-scheme Docusaurus manages */
:root {
color-scheme: dark light;
}
/* Fights the theme-toggle mechanism */
html[data-theme="dark"] {
color-scheme: dark;
}
/* Caught when part of a comma-separated selector list */
html, :root {
color-scheme: normal;
}
โ Correctโ
/* color-scheme on a custom component โ not a framework root selector */
.my-widget {
color-scheme: dark;
}
/* Theme tokens on data-theme โ fine as long as not color-scheme */
[data-theme="dark"] {
--ifm-color-primary: #66b2ff;
--ifm-navbar-background-color: #1a1b26;
}
/* color-scheme inside a media query on a non-root selector โ fine */
@media (prefers-color-scheme: dark) {
.custom-code-block {
color-scheme: dark;
}
}
Behavior and migration notesโ
- Selector matching is case-sensitive and exact after trimming and whitespace normalization.
- Multi-selector rules (comma-separated) are split and each part is checked individually.
- Nested
color-schemedeclarations inside nested rule blocks (for example inside@layer) still trigger when the resolved selector matches a managed root. - This rule is report-only; no autofix removes the declaration.
Additional examplesโ
โ Incorrect โ comma-separated list includes a managed rootโ
html, .wrapper {
color-scheme: dark;
}
Even though .wrapper is not managed by Docusaurus, the html part triggers the rule.
โ Correct โ scoped override for a specific sub-componentโ
.theme-code-block pre {
color-scheme: dark;
}
Stylelint config exampleโ
import { docusaurusPluginConfigs } from "stylelint-plugin-docusaurus";
export default {
plugins: ["stylelint-plugin-docusaurus"],
rules: {
"docusaurus/no-color-scheme-on-docusaurus-html-root": true
}
};
When not to use itโ
Disable this rule if your Docusaurus site uses a custom theme that intentionally overrides color-scheme on the root element and you have verified that this does not conflict with the framework's theme-switching mechanism.
Further readingโ
Rule catalog ID: R032