question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Feature/Proposal] Add support for dynamic theme switching

See original GitHub issue

What 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:

  1. Make sure styles are scoped within the html selector like html body {/** reset **/}
  2. Make a configurable html selector 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:closed
  • Created 5 years ago
  • Reactions:9
  • Comments:9 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
krokofantcommented, Apr 10, 2019

@vthinkxie Components can adapt to the theme by scoping their styles with the :host-context() selector:

:host-context(.first-theme) {
  button {
    background-color: red;
  }
}

:host-context(.second-theme) {
  button {
    background-color: blue;
  }
}

But for components using ViewEncapsulation.None the style specificity is too low to override the global styles so we would need to prefix those with :root to 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 :root to 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-theme it will have the following global styles for dropdowns:

.angular-theme-dark .ant-dropdown {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    color: #ccc;
    font-size: 13px;
    font-variant: tabular-nums;
    line-height: 1.5;
    list-style: none;
    font-feature-settings: 'tnum';
    position: absolute;
    top: -9999px;
    left: -9999px;
    z-index: 1050;
    display: block;

While the dropdown component itself will inject these styles:

.ant-dropdown {
    top: 100%;
    left: 0;
    position: relative;
    width: 100%;
    margin-top: 4px;
    margin-bottom: 4px;
}

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 :root as the prefix to ensure it has higher specificity than the custom prefix:

:root .ant-dropdown {
    top: 100%;
    left: 0;
    position: relative;
    width: 100%;
    margin-top: 4px;
    margin-bottom: 4px;
}
0reactions
hulliscommented, Mar 24, 2020

We have updated our documentation and demonstrate how to switch themes dynamically.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to add a theme switcher to Storybook | by Varun Vachhar
This article shows you how to add a theme switcher to your Storybook. Use a decorator to pass the theme object to your...
Read more >
Implementing Dynamic Color Themes in Your iOS App - Infinum
By using them anywhere in the app, you have support for changing themes without the need to add any additional logic for changing...
Read more >
Changing the application theme dynamically - SAP Community
Hi All, Is there any way to change the Analysis Application theme dynamically. We would like to use the same application for Mobile...
Read more >
[Feature Request] Switching profiles based on system ... - GitLab
Hi, It would be helpful to have a simple selection of default profiles for dark/light mode or using one that adapts like default...
Read more >
Dynamic theme switching in Drupal 8 - Jim Conte
Whether it is something simple like controlling the theme for user profile pages, or something more complex like switching themes depending on a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found