Neither wp_enqueue_style()
nor wp_register_style()
have a parameter to allow them to be loaded in the head, rather than the footer, as their script
counterparts do. The only solution is to have some of your CSS (or all of it - which would be bad) inside a style
tag inside head
, added with the wp_head
action hook. I used this technique for a while but at some point I got tired of trying to figure out what rules I need in head
for each particular theme, so I developed a more general solution, that I can apply to almost any theme, on any website.
Using the same action hook, I just apply a temporary style until the page has loaded, effectively hiding or at least fading the entire page before it has fully loaded and then I fade it into view with a simple javascript. Here it is, and it should go in functions.php
of your child theme:
add_action('wp_head', 'fix_fouc_problem');
function fix_fouc_problem() {
if (!is_admin()) {
echo '
<style type="text/css">
body {
opacity: 0;
transition: opacity .25s ease-in-out;
-moz-transition: opacity .25s ease-in-out;
-webkit-transition: opacity .25s ease-in-out;
}
</style>
<script type="text/javaScript">
function showTheBody() {
var body = document.getElementsByTagName("body")[0];
body.style.opacity = 1;
}
if (window.addEventListener) { /* W3C standard */
window.addEventListener("load", showTheBody, false);
} else if (window.attachEvent) { /* Microsoft browsers */
window.attachEvent("onload", showTheBody);
} else { /* this is for any future browser that might not know any of the
* methods above, just in case, showing the body:
*/
showTheBody();
}
</script>
<noscript><style>
/* If javascript is disabled, I'm changing body opacity back to 1,
* via CSS, but over an entire second, to give the page time to load
* past the fouc point
*/
body {
transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-webkit-transition: opacity 1s ease-in-out;
opacity: 1;
}
</style></noscript>';
}
}
If you don't like the backgound color while the page loads, add a loading background-color
property to html
inside the style
tag above and, if needed, change it in the function that executes when the page has fully loaded: showTheBody()
. Beware that, most likely, jQuery has not loaded at that point, so you're limited to javaScript.
Also, if you think the time needed to load the page is too long, you might change the opacity of body
during loading time from 0
to .25
or even .35
so the user sees the faded elements loading. With page being faded and having a swift CSS opacity transition, the fouc becomes hard to spot.
The only drawback I can think of when using this method is on pages that take very long time to load, as they're faded or not visible until they fully load. However, this doesn't apply to pages that load content using ajax (think infinite scrolling and such) as those are separate, asynchronous calls, and the load/onload event usually fires quite fast on those.