NOTES: control load order

This tutorial will show you how to:

Generate critical CSS
Defer CSS stylesheets
Inline the critical CSS from Step 1
So let’s go.

Step 1: Generate Critical CSS
The importance of this step will become evident after step 2. For now, just visit a site like like, enter your site’s URL or page, and click “Generate Critical Path CSS”. The tool will scan your website and eventually give you a blob of text like this:

Copy Critical CSS

Copy this and keep it safe. We’ll use it later.

Step 2: Defer CSS Stylesheets
Most CSS in WordPress is (and should be) enqueued properly using the “wp_enqueue_style” function. This will place a <link> element in the head that looks like this:

CSS Files Without Preload

As mentioned earlier, this CSS stylesheet is render blocking. If you plug your page into a tool like Google’s PageSpeed insights for example, it’ll complain that a lot of stuff is preventing the page from displaying – and those tools will be right.

About the rel=’preload’ Attribute
To solve this problem, browsers have started supporting the “preload” attribute for resources like scripts. Basically, it tells the browser that the resources marked in this manner can be downloaded simultaneously in the background and that they’re not terribly important for page loading.

Of course, that’s not true. The CSS stylesheets are important. They define how your site looks after all! But for the moment, we’re interested in using the “preload” attribute value to defer our external stylesheets.

You can do this by inserting the following code into your WordPress’s functions.php file:

[php] function add_rel_preload($html, $handle, $href, $media) {

if (is_admin())
return $html;

$html = &lt;&lt;&lt;EOT
&lt;link rel=’preload’ as=’style’ onload="this.onload=null;this.rel=’stylesheet’" id=’$handle’ href=’$href’ type=’text/css’ media=’all’ /&gt;
return $html;
add_filter( ‘style_loader_tag’, ‘add_rel_preload’, 10, 4 );


After you save your changes, your CSS stylesheets will have the “preload” tag attached to them like this:

CSS is Preloaded

Great right? Not so fast!

Step 3: Panic As your Site Breaks
Unfortunately, running the above code makes your site “unstyled” like this:

But the Page is Doesnt Display

This is because the CSS styles with “preload” haven’t been applied since the page went ahead and rendered without them. This is where the “critical” CSS from Step 1 comes in.

The “critical CSS” refers to only those CSS rules that apply to the “above the fold” content – namely the content that’s visible when your page first loads. This is typically a very tiny subset of the actual CSS contained in all the stylesheets.

In Step 1, we generated this critical CSS, and we need to insert it into the <head> of our webpage with following code:


function hook_css() {
[insert critical css here] &lt;?php
add_action(‘wp_head’, ‘hook_css’);

Replace [insert critical css here] with the code you copied from Step 1.

Note that this must include the <style></style> tags around it. If you’re using a different tool, it might just give you the CSS rules without the <style> opening and closing tags. Make sure you add them!

Once you’ve done this, your page will load normally and look the same. With the important difference that all your stylesheets are loading in a deferred manner! Say hello to fast page load speed scores!



[php] /*
You would add dependencies to your wp_enqueue_style() function calls.

function my_enqueues() {
wp_enqueue_style( ‘style-one’, ‘{path}’ );
wp_enqueue_style( ‘style-two’, ‘{path}’, array( ‘style-one’ ) );
wp_enqueue_style( ‘style-three’, ‘{path}’, array( ‘style-two’ ) );
wp_enqueue_style( ‘style-final’, ‘{path}’, array( ‘style-three’ ) );
add_action( ‘wp_enqueue_scripts’, ‘my_enqueues’ );

What this code does is make each style sheet dependent on the previous one. So they will load in the order style-one, style-two, etc.

Of course one of the {path} placeholders should be your style.css file called with get_stylesheet_uri();.

If you want to load one after a plugin has loaded one that overrides, then try using the plugins_loaded hook:


function my_plugin_overrides() {
wp_deregister_style( ‘plugin-styles’ ); // OPTIONAL
wp_enqueue_style( ‘plugin-css-overrides’, ‘{path}’, array( ‘deps’ ) );
add_action( ‘plugins_loaded’, ‘my_plugin_overrides’ );



So you are building a super duper cool plugin™ that, say, does something with widgets or shortcodes and you need to apply some CSS conditionally. No worries, that’s what wp_add_inline_style() is there for. But can you actually use it?

The problem
There are a few problems however. For starters, wp_add_inline_style() requires the handle of a registered style (via wp_register_style() or wp_enqueue_style()) as its first parameter. And that handle’s stylesheet, must not have been already printed. Now, assuming you are enqueuing your styles properly, the printing takes place during the wp_head action hook, which is a lot earlier than that place in the widgets that you hooked in.

You could perhaps force your style to print on the footer, but there is no such parameter in wp_register_style(). The only way you can do it is enqueuing after the during or after the wp_head action, but that means you are not properly enqueuing your stylesheets.

Or even worse, you might now have a stylesheet to load in the first place. Perhaps all your CSS is dynamic in nature, and a .css file just won’t cut it. Depending on the theme’s main stylesheet file (i.e. style.css) isn’t happening either, as each theme names its handle differently.

So, what do you do?

The solution
There’s a little-known workaround that we’ve used while building our MaxSlider plugin, where we needed to enqueue some generated CSS styles from within a shortcode, however all stylesheets were printed in the header. Without further ado, this is the gist of the workaround:


add_action( ‘some_hook’, ‘maxslider_enqueue_slider_css’ );
function maxslider_enqueue_slider_css() {
$css = ”;

// …

if ( true === $something ) {
$css = ‘body { background-color: ‘ . $color . ‘; }’;

// …

wp_register_style( ‘maxslider-footer’, false );
wp_enqueue_style( ‘maxslider-footer’ );
wp_add_inline_style( ‘maxslider-footer’, $css );


The last three lines are the most important.

First, we register a new style handle as usual, but without a file path or URL. This is perfectly valid and will be further explained later. Then, we enqueue that same empty style, and we finally provide it with some CSS to print. These last two lines can swap positions and it will still work just fine.

“But how can you enqueue a stylesheet without a path?“, you ask.

The theory is simple:
The wp_*_style() functions use an instance of the WP_Styles class, which extends the WP_Dependencies class. Similarly, the wp_*_script() functions use an instance of the WP_Scripts class, which extends (you guessed it!) the WP_Dependencies class.

Why does it matter? Well, you can pretty much do the same things with both styles and scripts. Take a look at this specific WordPress source code:

$scripts->add( ‘jquery’, false, array( ‘jquery-core’, ‘jquery-migrate’ ), ‘1.12.4’ );
That’s what really happens when you enqueue ‘jquery’. It’s not a real script file, but rather an alias/group that depends upon jquery-core and jquery-migrate. Scripts (and therefore, styles) don’t need a source file, as long as they have some kind of dependency attached to them, be it another script/style, or inline css/js code.

I hope you found the above information useful. Let me know in the comments section below if, where and how it helped you!



Registering the CSS Files
If you’re going to load CSS stylesheets, you should register them first with the wp_register_style() function:

[php] &lt;?php
wp_register_style( $handle, $src, $deps, $ver, $media );
$handle (string, required) is unique name for your stylesheet. Other functions will use this "handle" to enqueue and print your stylesheet.
$src (string, required) refers to the URL of the stylesheet. You can use functions like get_template_directory_uri() to get the style files inside your theme’s directory. Don’t ever think about hard-coding it!
$deps (array, optional) handles names for dependent styles. If your stylesheet won’t work if some other style file is missing, use this parameter to set the "dependencies".
$ver (string or boolean, optional) is the version number. You can use your theme’s version number or make up one, if you want. If you don’t want to use a version number, set it to null. It defaults to false, which makes WordPress add its own version number.
$media (string, optional) is the CSS media types like "screen" or "handheld" or "print". If you’re not sure you need to use this, don’t use it. It defaults to "all".
[/php] [php] &lt;?php

// wp_register_style() example
‘my-bootstrap-extension’, // handle name
get_template_directory_uri() . ‘/css/my-bootstrap-extension.css’, // the URL of the stylesheet
array( ‘bootstrap-main’ ), // an array of dependent styles
‘1.2’, // version number
‘screen’, // CSS media type


Registering styles is kind of “optional” in WordPress. If you don’t think your style is going to be used by any plugin or you’re not going to use any code to load it again, you’re free to enqueue the style without registering it. See how it’s done below.

Enqueueing the CSS Files
After registering our style file, we need to “enqueue” it to make it ready to load in our theme’s <head> section.

We do this with the wp_enqueue_style() function:


wp_enqueue_style( $handle, $src, $deps, $ver, $media );

The parameters are exactly the same with the wp_register_style() function, so no need for repeating them.

But as we said the wp_register_style() function isn’t mandatory, I should tell you that you can use wp_enqueue_style() in two different ways:



// if we registered the style before:
wp_enqueue_style( ‘my-bootstrap-extension’ );

// if we didn’t register it, we HAVE to set the $src parameter!
get_template_directory_uri() . ‘/css/my-bootstrap-extension.css’,
array( ‘bootstrap-main’ ),
null, // example of no version number…
// …and no CSS media type


Keep in mind that if a plugin will need to find your stylesheet or you intend to load it in various parts in your theme, you should definitely register it first.

Loading the Styles Into Our Website
We can’t just use the wp_enqueue_style() function anywhere in our theme – we need to use “actions”. There are three actions we can use for various purposes:

wp_enqueue_scripts for loading scripts and styles in the front-end of our website,
admin_enqueue_scripts for loading scripts and styles in the pages of our administration panel,
login_enqueue_scripts for loading scripts and styles in the WordPress login page.
Here are the examples for these three actions:



// load css into the website’s front-end
function mytheme_enqueue_style() {
wp_enqueue_style( ‘mytheme-style’, get_stylesheet_uri() );
add_action( ‘wp_enqueue_scripts’, ‘mytheme_enqueue_style’ );

// load css into the admin pages
function mytheme_enqueue_options_style() {
wp_enqueue_style( ‘mytheme-options-style’, get_template_directory_uri() . ‘/css/admin.css’ );
add_action( ‘admin_enqueue_scripts’, ‘mytheme_enqueue_options_style’ );

// load css into the login page
function mytheme_enqueue_login_style() {
wp_enqueue_style( ‘mytheme-options-style’, get_template_directory_uri() . ‘/css/login.css’ );
add_action( ‘login_enqueue_scripts’, ‘mytheme_enqueue_login_style’ );


There’s an important announcement in Make WordPress: “Use wp_enqueue_scripts(), not wp_print_styles()!”. It tells you about a possible incompatibility error with WordPress v3.3.

Some Extra Functions
There are some very useful functions about CSS in WordPress: They allow us to print inline styles, check the enqueue state of our style files, add meta data for our style files, and deregister styles.

Let’s have a look.

Adding Dynamic Inline Styles: wp_add_inline_style()
If your theme has options to customize the styling of the theme, you can use inline styling to print them with the wp_add_inline_style() function:



function mytheme_custom_styles() {
wp_enqueue_style( ‘custom-style’, get_template_directory_uri() . ‘/css/custom-style.css’ );
$bold_headlines = get_theme_mod( ‘headline-font-weight’ ); // let’s say its value is "bold"
$custom_inline_style = ‘.headline { font-weight: ‘ . $bold_headlines . ‘; }’;
wp_add_inline_style( ‘custom-style’, $custom_inline_style );
add_action( ‘wp_enqueue_scripts’, ‘mytheme_custom_styles’ );


Quick and easy. Remember though: You have to use the same hadle name with the stylesheet you want to add inline styling after.

Checking the Enqueue State of the Stylesheet: wp_style_is()
In some cases, we might need the information on a style’s state: Is it registered, is it enqueued, is it printed or waiting to be printed? You can determine it with the wp_style_is() function:



* wp_style_is( $handle, $state );
* $handle – name of the stylesheet
* $state – state of the stylesheet: ‘registered’, ‘enqueued’, ‘done’ or ‘to_do’. default: ‘enqueued’

// wp_style_is() example
function bootstrap_styles() {

if( wp_style_is( ‘bootstrap-main’ ) {

// enqueue the bootstrap theme if bootstrap is already enqueued
wp_enqueue_style( ‘my-custom-bootstrap-theme’, ‘http://url.of/the/custom-theme.css’ );


add_action( ‘wp_enqueue_scripts’, ‘bootstrap_styles’ );



Adding Meta Data to the Stylesheet: wp_style_add_data()
Here’s an awesome function called wp_style_add_data() which allows you to add meta data to your style, including conditional comments, RTL support and more!

Check it out:



* wp_style_add_data( $handle, $key, $value );
* Possible values for $key and $value:
* ‘conditional’ string Comments for IE 6, lte IE 7 etc.
* ‘rtl’ bool|string To declare an RTL stylesheet.
* ‘suffix’ string Optional suffix, used in combination with RTL.
* ‘alt’ bool For rel="alternate stylesheet".
* ‘title’ string For preferred/alternate stylesheets.

// wp_style_add_data() example
function mytheme_extra_styles() {
wp_enqueue_style( ‘mytheme-ie’, get_template_directory_uri() . ‘/css/ie.css’ );
wp_style_add_data( ‘mytheme-ie’, ‘conditional’, ‘lt IE 9’ );
* alternate usage:
* $GLOBALS[‘wp_styles’]-&gt;add_data( ‘mytheme-ie’, ‘conditional’, ‘lte IE 9’ );
* wp_style_add_data() is cleaner, though.

add_action( ‘wp_enqueue_scripts’, ‘mytheme_ie_style’ );

[/php] [If I’m not mistaken, this is the first tutorial ever written about this little—but useful—function.

Deregister Style Files with wp_deregister_style()
If you ever need to “deregister” a stylesheet (in order to re-register it with a modified version, for example), you can do it with wp_deregister_style().

Let’s see an example:

[php] &lt;?php

function mytheme_load_modified_bootstrap() {
// if bootstrap is registered before…
if( wp_script_is( ‘bootstrap-main’, ‘registered’ ) ) {
// …deregister it first…
wp_deregister_style( ‘bootstrap-main’ );
// …and re-register it with our own, modified bootstrap-main.css…
wp_register_style( ‘bootstrap-main’, get_template_directory_uri() . ‘/css/bootstrap-main-modified.css’ );
// …and enqueue it!
wp_enqueue_style( ‘bootstrap-main’ );

add_action( ‘wp_enqueue_scripts’, ‘mytheme_load_modified_bootstrap’ );


Although it’s not required, you should always re-register another style if you deregister one – you might break something if you don’t.

[There’s also a similar function called wp_dequeue_style(), which removes the enqueued stylesheets as its name suggests.

Wrapping Everything Up
Congratulations, now you know everything about including CSS in WordPress correctly! Hope you enjoyed the tutorial.

Do you have any tips or experiences you want to share? Comment below and share your knowledge with us! And if you liked this article, don’t forget to share it with your friends!