0

I have a shortcode, widget and template tag that need to load CSS. I am registering in init, and enqueueing as required.

The only problem is, it is adding the CSS loader at the bottom of the page, not in the head, so there can be an ugly lag where the content of the shortcode/widget/template tag is unstyled.

Given these can appear anyone in the flow of the page - and may not even appear - there's no way to predict before the page begins to render. It just has to wait til it encounters them, and then it's too late to hook the enqueue into the wp_head hook.

I can't think how it could be possible to avoid this, so at the moment hide the content until its css loads.

However would be great if someone knows some magic trick!

thanks

5
  • 1
    Can you post your code?
    – cybmeta
    Commented Apr 5, 2015 at 13:01
  • Thanks, cybmeta... not sure that would help. The problem is sequential. Commented Apr 8, 2015 at 8:35
  • Thanks, cybmeta... took too long to edit my comment! The shortcode, for example, fires during the post display, by which time, it is too late to add anything to the <head>. I need some way of knowing before the page starts that the shortcode or widget is going to be used. So, the shortcode or widget needs to load its own css. How do I make that CSS load on demand but still in the <head>? I could just load the shortcode or widget's css on every page, but of course, that is very naughty. How have others solved this? Commented Apr 8, 2015 at 8:44
  • Ah, ok. Now I understand your problem. See this question and answer.
    – cybmeta
    Commented Apr 8, 2015 at 9:31
  • Thanks, cybmeta! Both those are covering this issue. But not sure anyone really came up with a clear and definitive solution. The pre-search seems to be the preferred solution. Commented Apr 8, 2015 at 12:14

1 Answer 1

-1

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.

6
  • Wow! Thanks for the detailed answer, Andrei. I do like that solution. Commented Apr 8, 2015 at 8:18
  • I don't like this solution. As @Andrei said, there is no parameter in wp_enqueue_style() or wp_register_style() to load the css file in footer, so you are not using that functions. That means that you are not using WordPress dependencies manager and you are doing it wrong. This solution is just a work around to hide the mistake to users but actually it doesn't fix the problem.
    – cybmeta
    Commented Apr 8, 2015 at 9:22
  • @cybmeta To fix the problem one has to go inside their particular theme and plugins and determine which styles need to be loaded inside head so the page doesn't look broken when it's not fully loaded. And that is far from possible for the average WP user. A proper solution for this problem would have to come from WP themselves. You may not like it, but it's the only general practical solution I've come up with that applies to all installations. It's not done "the WP way" because there is no WP way to get rid of FOUC. Thanks for the vote down.
    – tao
    Commented Apr 8, 2015 at 14:45
  • And no, I'm not doing it wrong. I'm doing it exactly as WP would do it if this problem would be addressed at a core WP level and get fixed once and for all. They would too register some temporary styles in the head of the page, which wp_register_styles() does not need to know about, since they are removed when the page is loaded. Perhaps you should recheck your wrong and right definitions regarding WP, @cybmeta.
    – tao
    Commented Apr 8, 2015 at 14:54
  • See comments on the question to find links to other questions and answers about how to handle styles and scripts from shortcodes using a general practical solution. I'm sorry to say I don't like your answer, it seems that my comment bother you, but hiding the body until the document is fully loaded is not a general practical solution at all but a particular solution for a particular situation and for a particular developer that want that loading effect. I'm sorry but I have a different opinion than you. And remember that here we are developers, not just average WP users.
    – cybmeta
    Commented Apr 8, 2015 at 16:40

Not the answer you're looking for? Browse other questions tagged or ask your own question.