[Feature/Proposal] Add support for dynamic theme switching
See original GitHub issueWhat problem does this feature solve?
The Angular CLI provides less compilation which works with the latest NgZorro. The Angular CLI also supports building style files lazily so they are separated into different files. This might sound good for theme switching but by default the lazily built styles are in .js in dev and .css in prod. So we cannot lazy load ant themes without switching all style generation to use .css files via angular-cli “extract-css” option.
There is an old issue about supporting dynamic themes (#1957) but here I have an idea and would like to get feedback. I could provide a PR if the solution seems reasonable.
What does the proposed API look like?
One easy way of supporting dynamic theme switching (of css at least) is to use different theme selectors on preferably the top-most selectable element html. Our use-case follows the selectors html.classic-theme and html.dark-theme. Each theme css would be triggered depending on which theme class we’ve set on the html element.
Now this is a bit tricky to accomplish with NgZorro because the selectors used when compiling the less styles are using the html selector inside the NgZorro specific styles and the normalize/reset styles (which also applies theme styles).
To support dynamically switching themes we could:
- Make sure styles are scoped within the
htmlselector likehtml body {/** reset **/} - Make a configurable
htmlselector override which- Defaults to “html”
- Enables to specify a theme-specific selector such as
html.dark-theme - Provides a way of applying ant styles within specific selectors
I’d love to hear some feedback. 🙂
Issue Analytics
- State:
- Created 5 years ago
- Reactions:9
- Comments:9 (8 by maintainers)

Top Related StackOverflow Question
@vthinkxie Components can adapt to the theme by scoping their styles with the
:host-context()selector:But for components using
ViewEncapsulation.Nonethe style specificity is too low to override the global styles so we would need to prefix those with:rootto ensure they their specificity is higher. This issue only affects those who will try to apply the custom prefix.In short: For this to work properly with NgZorro we need to prefix component styles, that uses
ViewEncapsulation.None, with:rootto make sure it has enough specificity.More details…
Since the ant component styles are not using the theme prefix selector it’s specificity will be lower than the theme prefixed styles. For instance if we have a theme scoped within
.angular-dark-themeit will have the following global styles for dropdowns:While the dropdown component itself will inject these styles:
This will make the dropdown render at
top: -9999px;left: -9999px;. To fix this we would need to adjust the component styles to be prefixed as well. Since the component is unaware of the theme prefix we can specify:rootas the prefix to ensure it has higher specificity than the custom prefix:We have updated our documentation and demonstrate how to switch themes dynamically.