Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Color mode switch flash issue (dark theme) #37774

Closed
2 tasks done
Tracked by #37549
tang2087 opened this issue Dec 31, 2022 · 4 comments
Closed
2 tasks done
Tracked by #37549

Color mode switch flash issue (dark theme) #37774

tang2087 opened this issue Dec 31, 2022 · 4 comments

Comments

@tang2087
Copy link

Prerequisites

Proposal

I'm proposing to add a optional flag which controls whether to use CSS variables when switching among color modes. Instead, pre-calculate CSS values for predefined theme colors. This will potentially increase the size of final CSS files but can remove the 'flashing issue' when using dark theme.
Refer to the context section for more details.

Motivation and context

By default, the color mode is light. I use cookies to record user's preference about colors. Based on the cookie values, my website will pre-populate data-bs-theme attribute for root element.
If I choose to use Dark theme mode, I can observe a flash of changing from light to dark theme though it is almost invisible. I believe this is because CSS variables are used instead of static computed color variables. Before BS5.3.0, I was creating dark-theme CSS override by myself and encounter no such issue.
You can find this issue in my website by choosing dark theme mode and then navigating through pages: [Kontext] (https://kontext.tech/)

image

@mdo
Copy link
Member

mdo commented Jan 1, 2023

This has nothing to do with CSS variables and everything to do with loading JS to make the switch. This is why we put the JS so early in the document and make it a blocking script. Only way to have no flash is to be 100% media query driven, but that doesn't scale beyond the basics of light and dark mode.

@tang2087
Copy link
Author

tang2087 commented Jan 1, 2023

This has nothing to do with CSS variables and everything to do with loading JS to make the switch. This is why we put the JS so early in the document and make it a blocking script. Only way to have no flash is to be 100% media query driven, but that doesn't scale beyond the basics of light and dark mode.

Thanks for the clarification, Mark. It makes sense. I don't want js to block the main UI thread (as it will impact web core vitals) hence I am planning to add my own CDN for my website's CSS and JS files and then generate two sets of CSS files: one for light theme and one for dark theme. Since my website is not SPA and it is server side rendering, I will use cookie to decide which CSS file to include for each request as I only need light or dark theme (as most of other websites do). When user change settings, I will then dynamically replace CSS file and set the cookie. I guess the drawback of the approach is that - I'll have to remove the Auto theme selection as that will be only become known to the server side after the first load.

Any other suggestions beside the media query?

@mdo
Copy link
Member

mdo commented Jan 4, 2023

If you don't need an explicit toggle override, I'd do the media query and build it without compiling two separate stylesheets. Instead swap CSS variable values like we're doing. You can reconfigure Bootstrap to use that approach fwiw. See https://getbootstrap.com/docs/5.3/customize/color-modes/#building-with-sass.

@mdo mdo closed this as not planned Won't fix, can't repro, duplicate, stale Jan 4, 2023
@tang2087
Copy link
Author

tang2087 commented Jan 4, 2023

If you don't need an explicit toggle override, I'd do the media query and build it without compiling two separate stylesheets. Instead swap CSS variable values like we're doing. You can reconfigure Bootstrap to use that approach fwiw. See https://getbootstrap.com/docs/5.3/customize/color-modes/#building-with-sass.

Is there an easy way to include all Bootstrap defined CSS for all elements/components but replacing the color schemes with dark theme ones? I don't want to rewrite all components.

$color-mode-type: data;

@include color-mode(dark) {
  // Include all BS classes
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants