dark-mode-switch
dark-mode-switch copied to clipboard
Delay in dark mode detection
It is more a suggestion than a real issue : when my website theme has just loaded, and dark theme was already activated, I can quickly see white theme before dark theme is activated. I understand why I can see it considering that main theme is loaded before dark theme tag is added to body. Do you have an idea how to not see this quick blinking on page load ?
Similar issue 😒
Any Update?
This is a known issue, to lessen the impact I suggest to put the switch and the script as high in the body as possible.
so... I did a workaround this (basically I'm only using the project's .css)
- I have a "fa-adjust" icon on the top
<a href="{route}"><i class="fa fa-adjust fa-rotate-180"></i></a>
and the route will change the current theme (light->dark, and dark->light) - At the top of the page I check for the user's theme in the database. If it's dark, I load the css, if it's not, I don't. Which in Laravel is a plain
@if(Auth::user()->theme=='dark')
<link href="{{ asset('/bootstrap/css/dark-mode.css') }}" rel="stylesheet">
I know it might not be the best way (and it's required to reload the page) but I thought the drawback would be less worst than the white flash when the page loads (which was seriously hurting my eyes).
Best regards.
Any Update?
Hello,
Thanks for great project. It was a breeze to add dark mode to an existing web site with help of this project and most of the time was used to tune colors, not for implementing code.
To prevent light flash during page load, I had to split dark-mode-switch.js into two parts; a theme-init part which is inlined into html and executed as early as possible and switch-init part which initializes dark mode switch functionality same as original.
dark-mode-init.js :
function initDarkModeTheme() {
var darkThemeSelected =
localStorage.getItem("darkSwitch") !== null &&
localStorage.getItem("darkSwitch") === "dark";
darkThemeSelected
? document.body.setAttribute("data-theme", "dark")
: document.body.removeAttribute("data-theme");
}
inlined this script and called very high up within body tag.
<script>inlined content of dark-mode-init.js<script>
<script type="text/javascript">initDarkModeTheme();</script>
changed dark-mode-switch.js to only include code about switch initialization
dark-mode-switch.js:
var darkSwitch = document.getElementById("darkSwitch");
window.addEventListener("load", function () {
if (darkSwitch) {
var darkThemeSelected =
localStorage.getItem("darkSwitch") !== null &&
localStorage.getItem("darkSwitch") === "dark";
darkSwitch.checked = darkThemeSelected;
darkSwitch.addEventListener("change", function () {
resetTheme();
});
}
});
function resetTheme() {
if (darkSwitch.checked) {
document.body.setAttribute("data-theme", "dark");
localStorage.setItem("darkSwitch", "dark");
} else {
document.body.removeAttribute("data-theme");
localStorage.removeItem("darkSwitch");
}
}
calling block is same as the original. below code is bootstrap 4 sample
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="darkSwitch" />
<label class="custom-control-label" for="darkSwitch">Dark Mode</label>
</div>
<script src="dark-mode-switch.js"></script>
Regards,
heya @modabas - thanks for posting your solution - this works great! I've been testing it on: https://tests.christianoliff.com/dark-mode-switch-v2/ and switching between 'Another page' and 'Yet Another page' on the navbar. I simulated a slow connection by disabling cache and throttling to slow 3g and didn't see a single flash of white screen while in dark mode. Great work! I'll do a bit more testing and then make a PR for this later and give you a shout out in the credits for the next release.
I drafted the following snipped and run it directly after the body tag:
(function () {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.body.setAttribute("data-theme", "dark")
} else {
document.body.removeAttribute("data-theme")
}
})();
or as closured:
(function(){let a=window,b=document.body,c="data-theme",e=a.matchMedia;e&&e("(prefers-color-scheme: dark)").matches?b.setAttribute(c,"dark"):b.removeAttribute(c);})();
I drafted the following snipped and run it directly after the body tag:
(function () { if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { document.body.setAttribute("data-theme", "dark") } else { document.body.removeAttribute("data-theme") } })();
or as closured:
(function(){let a=window,b=document.body,c="data-theme",e=a.matchMedia;e&&e("(prefers-color-scheme: dark)").matches?b.setAttribute(c,"dark"):b.removeAttribute(c);})();
This worked well for me @basteyy Thanks a bunch 🙏
Hi! I have seen that something similiar happens with the switch button. When dark mode is enabled, if you refresh the page, the little ball inside the switch appears for a moment on the left, and then switches inmediatly to the right. Is there a way to keep that ball directly on the right if dark mode is enabled? Thanks!!
Hi! I have seen that something similiar happens with the switch button. When dark mode is enabled, if you refresh the page, the little ball inside the switch appears for a moment on the left, and then switches inmediatly to the right. Is there a way to keep that ball directly on the right if dark mode is enabled? Thanks!!
Just implement this early in your code.
https://github.com/coliff/dark-mode-switch/issues/22#issuecomment-1117820571
I drafted the following snipped and run it directly after the body tag:
(function () { if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { document.body.setAttribute("data-theme", "dark") } else { document.body.removeAttribute("data-theme") } })();
or as closured:
(function(){let a=window,b=document.body,c="data-theme",e=a.matchMedia;e&&e("(prefers-color-scheme: dark)").matches?b.setAttribute(c,"dark"):b.removeAttribute(c);})();
it work for me many Thanks!! @basteyy