Skip to content

[system][material-ui] Scope the CSS theme variables of nested and sibling ThemeProviders - #49581

Draft
aarongarciah wants to merge 9 commits into
mui:masterfrom
aarongarciah:css-vars-scoped-theme-providers
Draft

aarongarciah wants to merge 9 commits into
mui:masterfrom
aarongarciah:css-vars-scoped-theme-providers

Conversation

@aarongarciah

@aarongarciah aarongarciah commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

Before: with CSS theme variables, every ThemeProvider writes to :root, so nested themes are ignored and sibling providers overwrite each other.

After: a nested provider whose variables differ writes only the changed ones on a display: contents wrapper (.mui-theme-<hash>). A sibling provider opts in with scoped, and unscoped siblings get a dev warning. Modal and Popper apply the scope to portaled content, and useThemeScope() does it for other portals.

Needed before #49291.

Known cost: the wrapper breaks direct-child selectors, including Stack's sibling margins.

claude and others added 3 commits October 26, 2026 12:20
…ling ThemeProviders

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HG4YYGmgsLG7riohZnG1WZ
…bles

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HG4YYGmgsLG7riohZnG1WZ
@aarongarciah aarongarciah added customization: theme Higher level theming customizability. v10.x labels Oct 26, 2026
@code-infra-dashboard

code-infra-dashboard Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Deploy preview

Bundle size

Bundle Parsed size Gzip size
@mui/material 🔺+3.26KB(+0.60%) 🔺+1.18KB(+0.76%)
@mui/lab 0B(0.00%) 0B(0.00%)
@mui/private-theming 0B(0.00%) 0B(0.00%)
@mui/system 🔺+3.07KB(+4.42%) 🔺+1.13KB(+4.57%)
@mui/utils 0B(0.00%) 0B(0.00%)

Details of bundle changes

Performance

No regressions in 32 benchmarks · ran 4m 33s · details


Check out the code infra dashboard for more information about this PR.

aarongarciah and others added 6 commits October 26, 2026 14:56
…ded type

- Fix the intro of "Nested and multiple theme providers": sibling providers also write to `:root`, only nested or `scoped` ones are scoped.
- Mention the dev warning for sibling providers, and that a `scoped` name suffixes both storage keys.
- Note in the theming guide that only nested themes whose variables differ are wrapped.
- Remove the internal `generateCssVarsByColorScheme` type from `CssVarsTheme`; it's only read through untyped code.
- Sort the `scoped` propType alphabetically.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Keep `generateStyleSheets` and the color scheme selector effect as they are on master. `generateCssVarsByColorScheme` and `getColorSchemeRule` are now only used for scoping.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Every nested provider generated and diffed the CSS variables of both themes on mount, which made 100 nested providers mount about 33% slower than on master. The result only depends on the themes, so cache it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Measures mounting a root provider, and 100 nested providers whose CSS variables are the same as or differ from the outer theme's.
@aarongarciah aarongarciah added the breaking change Introduces changes that are not backward compatible. label Oct 26, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change Introduces changes that are not backward compatible. customization: theme Higher level theming customizability. v10.x

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants