Reputation: 602
I wrote the code below and placed it just before the </body>
tag on each page of my site. It works great in that it turns the background of each page black and the text to white and remembers that setting until the user changes it back to "Day Mode".
<script>
var body = $("body");
var day = $("#day");
var night = $("#night");
var dayLi = $("#day-li");
var nightLi = $("#night-li");
var panel = $(".panel");
if(localStorage.night == "on"){
body.addClass("night");
panel.addClass("night");
dayLi.show();
nightLi.hide();
}else{
body.removeClass("night");
panel.removeClass("night");
nightLi.show();
dayLi.hide();
}
night.click(function(){
body.addClass("night");
panel.addClass("night");
localStorage.setItem("night","on");
dayLi.show();
nightLi.hide();
});
day.click(function(){
body.removeClass("night");
panel.removeClass("night");
localStorage.night = "off";
nightLi.show();
dayLi.hide();
});
</script>
The .night
class is as you might expect:
.night{
background-color: black;
color: white;
}
The problem I'm having with it is that when in night mode, it takes about a second for night mode to take effect, meaning there is a white flash on each page load.
I experimented with placing the above script higher up on the page, but still got the flash of white first on each page load. To be clear, the flash of white is very short or almost non-existent on pages that aren't loading as much data from my database. But on the pages where a lot of data is getting loaded from my db the flash lasts for about a second.
Is this something that can be fixed? Thanks in advance for any pointers.
Upvotes: 3
Views: 1716
Reputation: 21209
As I've mentioned, it's impossible to fully eliminate the flash, but you can reduce it greatly by doing it in the head and not using classes (since stylesheets are loaded asynchronously).
Add a script right after your <body>
opening tag that does this logic:
<script>
if(localStorage.night == "on") {
document.body.style.backgroundColor = "#000"; // color of your choice
}
</script>
Note that you can't use jquery because it isn't loaded at that point. This will minimize the time that your page is the wrong color.
Edit: Another possible solution is to do changes server-side using CSS, which should have the same effect. The catch is that you need to render the styles inline since CSS files are loaded asynchronously.
Upvotes: 3
Reputation: 91525
To prevent a Flash of Unstyled Content (FOUC) on the frontend alone you can use a "cloak" trick. AngularJS and VueJS both use this technique for single page applications.
In your HTML, set a style tag to hide your <body>
.
<style>
body {
display: none;
}
</style>
Then, in your existing code, or even a standalone script, you can do:
$(function() {
$(body).css('display', 'initial');
});
This works because the embedded styles will run first, hiding your body element. Then, once the javascript is loaded and the DOM is ready, the script will run, unhiding the body.
You could enhance this to always start as black by updating the embedded styles to:
body * {
display: none;
background: #000;
}
This will make the body black and hide all its descendants.
Upvotes: 2