Color mode switch flash issue (dark theme)
tang2087 opened this issue · 4 comments
Prerequisites
- I have searched for duplicate or closed feature requests
- I have read the contributing guidelines
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/)
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.
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?
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.
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
}