[material-ui] Attach selector for default color scheme
There is an edge case bug from #42839. Found this when working on #42916 to showcase light and dark colors.
Root cause
If a colorSchemeSelector is set to class or data attribute, the selector is not generated for the default color scheme.
For example:
<CssVarsProvider theme={extendTheme({ colorSchemes: { light: true, dark: true }, colorSchemeSelector: 'class' }>
// generated CSS
:root {
…light color
}
.dark {
…dark color
}
This makes it impossible to force a specific part of the app to be light because the .dark will always win :root:
<div class="light"> // this will not work in dark mode
Changes
The fix is to generate a selector for a default color scheme too, so it becomes:
:root, .light {
…light color
}
.dark {
…dark color
}
- [x] I have followed (at least) the PR section of the contributing guide.
Netlify deploy preview
https://deploy-preview-43035--material-ui.netlify.app/
Bundle size report
Details of bundle changes (Toolpad) Details of bundle changes
Generated by :no_entry_sign: dangerJS against c9e96840d645c2cbc1ae28abc048627b4ac25391
Hey @siriwatknp!
This makes it impossible to force a specific part of the app to be
lightbecause the.darkwill always win:root:<div class="light"> // this will not work in dark mode
Is this something we want to support? What's the use case? As far as I understand, light and dark modes are not designed to be used at the same time.
Hey @siriwatknp!
This makes it impossible to force a specific part of the app to be
lightbecause the.darkwill always win:root:<div class="light"> // this will not work in dark modeIs this something we want to support? What's the use case? As far as I understand, light and dark modes are not designed to be used at the same time.
It's quite common in the design to force a section to use dark or light color scheme, one example is our homepage
I think not supporting this is considered a bug to me because the CSS variables are not applied as expected and there is no workaround to make it work since the styles are our responsibility.
It's quite common in the design to force a section to use dark or light color scheme
I think that's a different thing. One is the global light/dark mode, and the other is a highlight/contrast section. That the highlight section on our homepage coincides with the dark tokens on light mode is a coincidence. Semantically, they are different things. This is evident by the same section keeping its dark tokens on dark mode as well:
| light mode | dark mode |
|---|---|
Because they're different semantically, they should be implemented differently. The highlight section should not use the same infrastructure as the global color mode, even though they share token values. This makes it easier to maintain and modify in the future.
I think that's a different thing.
In our case, it's intentional. I believe that the designer want to leverage the dark palette tokens:
One is the global light/dark mode, and the other is a highlight/contrast section. That the highlight section on our homepage coincides with the dark tokens on light mode is a coincidence. Semantically, they are different things. This is evident by the same section keeping its dark tokens on dark mode as well:
I think that's a different topic and not my goal of fixing the issue. My point is the current behavior is a bug because the CSS variables is not applied based on the specified selector.
Before: https://codesandbox.io/s/new-violet-jmv323?file=/src/Demo.tsx After: https://codesandbox.io/p/sandbox/material-ui-cra-ts-forked-9cvf3l
| Before | After |
|---|---|
I stand by my point that scoping color schemes in the same app is not a good practice. I think we shouldn't teach our users to do this. For example, if they're trying to achieve a highlight section like the one on mui.com, it should be implemented as such:
Okay, I won't add this point to the docs as it depends on the preference of the user.