I've been noticing issues with flashes of unstyled content lately, and wanted to find a go-to solution to build into all my future sites.
After some Googling, I found this article by Stephen Petrey that presents a couple of effective solutions:
The Javascript Approach
The Javascript-based approach goes something like this:
- Load the page with a
no-js
class on the<html>
element- Use CSS to hide the
<html>
element
- Use CSS to hide the
- Replace the
no-js
class with ajs
class using Javascript- Use CSS to make the
<html>
element visible again once thejs
class is added
- Use CSS to make the
The downside, as Stephen mentions, is that if Javascript is disabled, the page will load but be invisible. For many sites, this may be perfectly acceptable, but I don't love the idea of the page being invisible to no-JS visitors. On to the next one!
The CSS Approach
A clever comment on that article by electrotype provides a CSS-only solution. The gist is:
- Inline CSS styles into the
<head>
to hide the<html>
element - Add styles to the end of your last CSS file to reverse those styles and make the
<html>
element visible again
This is much more my style - once all of your CSS styles are parsed, the site will become visible without any flashes, all without Javascript!
However, there's still a weakness - if your CSS fails to load, the site will still be invisible. That's probably pretty unlikely, but it still doesn't sit well for me to depend on that file loading successfully for the site to be visible.
My Modified CSS Approach
My ideal solution combines the CSS-only approach with a fallback in case the stylesheet fails to load.
CSS Animation to the rescue!
You'll need to add this to the top of the <head>
:
<style>
html {
animation: fouc-fix 5s steps(1);
}
@keyframes fouc-fix {
0% { opacity: 0; }
100% { opacity: 1; }
}
</style>
And this to the end of your final CSS file:
html {
animation: none !important;
}
Let's break that all down:
- Immediately upon loading the
<style>
tag in the<head>
, thefouc-fix
animation begins on the<html>
element, setting its opacity to 0. - Once the CSS file is fully parsed, the animation is forced to
none
, immediately resetting the opacity to default (1). - If the CSS file fails to load, the animation will complete itself after 5 seconds, setting the opacity back to 1.
- The
step(1)
parameter makes the animation jump straight to the final state, rather than changing gradually. - You could set the animation time to whatever you want - 5 seconds seemed like a good amount of time to wait for the CSS to load.
- The
Let me know in the comments if there's anything I missed or if you have a solution that works even better!
Top comments (0)