How to remove unused CSS in WordPress

In this post you will learn how to find and remove unused CSS on your website and prevent WordPress from transferring megabytes of unused code without any plugins.

Why should you remove unused CSS in the first place?

Come on, let’s be serious, you know why you should do it. 

You wouldn’t be here if you didn’t want to optimize your web page performance. You’ve probably run your website through a PageSpeed checker and received a suggestion to remove unused CSS.

Many websites use lots of 3rd party libraries or some pre-built themes, with lots of features and code to cover all possible scenarios, while only a small portion of it is really used. You end up transferring megabytes of unused CSS (dead code), which makes your website take really really long to load. 

How to find unused CSS?

If you use WordPress, unfortunately there isn’t an easy way to find unused CSS, like by just installing a plugin and clicking through some configuration steps. Although there are some tools online, that help to find the needed CSS by submitting your URL. 

Purifycss.online, for example, crawls your web page and checks all CSS files and inline styles as well. But caution: it will remove all CSS rules that aren’t used on the specified page, even though some of them might be used on sub pages. You have the possibility to insert multiple URLs, but if you manage a site with hundreds of pages, it might get quite cumbersome.

purifycss.online with multiple URLs and results

Disclaimer: purifycss.online is made by me. The JavaScript library purifycss, which the online tool is based on, is not.

How to use the purified CSS code on your WordPress website

1. Upload purified stylesheet

Now, if you already have your clean CSS code, let’s copy & paste it in a new file and name it styles.pure.css and upload it to your theme folder (if you’re using a pre-built theme, I hope you already created a child theme).

2. Remove existing stylesheets

Now you’ll have to remove all stylesheet references from your web page. You can do this by iterating through all queued styles and dequeue them. Add this to your functions.php:

// set a variable to make it easy to enable and disable the purifycss feature
// while testing, just append this parameter to your url: http://www.yourwebsite.com/?purifytest
$purifyCssEnabled = array_key_exists('purifytest',$_GET);

// when you're done, set the variable to true - you will be able to disable it anytime with just one change
// $purifyCssEnabled = true;

function dequeue_all_styles() {
    global $wp_styles;
    foreach( $wp_styles->queue as $style ) {
        wp_dequeue_style($wp_styles->registered[$style]->handle);
    }
}

if ($purifyCssEnabled) {
    // this will remove all enqueued styles in head
    add_action('wp_print_styles', 'dequeue_all_styles', PHP_INT_MAX - 1);

    // if there are any plugins that print styles in body (like Elementor),
    // you'll need to remove them as well
    add_action('elementor/frontend/after_enqueue_styles', 'dequeue_all_styles',PHP_INT_MAX);
}

3. Make sure all styles have been removed

Now open your web page URL with the ?purifytest parameter appended and you should see only the raw content your page. Open the source code viewer in your browser and make sure there is no <link rel="stylesheet" ...> and no <style>...</style> block left.

4. Remove inline styles if any exists

Unfortunately there is no WordPress hook to remove inline styles, as they are not enqueued like the stylesheet file references. 

The only possibility that comes to my mind (please let me know in the comments if there is a better way), is to go through the HTML that is about to be rendered and remove inline styles with regular expressions. To catch the full HTML, we need to do a workaround with output buffer.

Add this to your functions.php file:

/* Remove inline <style> blocks. */
function start_html_buffer() {
    // buffer output html
    ob_start();
}
function end_html_buffer() {
    // get buffered HTML
    $wpHTML = ob_get_clean();

    // remove <style> blocks using regular expression
    $wpHTML = preg_replace("/<style[^>]*>[^<]*<\/style>/m",'', $wpHTML);

    echo $wpHTML;
}
if ($purifyCssEnabled) {
    add_action('template_redirect', 'start_html_buffer', 0); // wp hook just before the template is loaded
    add_action('wp_footer', 'end_html_buffer', PHP_INT_MAX); // wp hook after wp_footer()
}

5. Enqueue the purified CSS

function enqueue_pure_styles() {
    wp_enqueue_style('pure-styles', get_stylesheet_directory_uri().'/styles.pure.css');
}

if ($purifyCssEnabled) {
    // enqueue our purified css file
    add_action('wp_print_styles', 'enqueue_pure_styles', PHP_INT_MAX);
}

6. Test your changes thoroughly!

Please keep in mind that you might have thrown away CSS code that is being used on sub pages or that is dependent on some user interaction, like a modal dialog, form validation messages, AJAX callbacks etc. 

Some tips what to pay attention to:

  • Hover over and click on each element
  • Try submitting your forms with incomplete or invalid data
  • Also test pages that are not linked from your home page or through your main navigation
  • Test on different screen sizes – not just by resizing your window, but also on different physical devices
  • Test in different browsers!
  • Please comment below with other frequent cases that might be missed by purifycss.online

7. Adjust purified CSS code

If you detect styles that are missing in your purified code, make sure first, that you added the URL of the page to the “additional URLs” on purifycss.online.

If that’s the case, then copy the corresponding HTML code of your unstyled element (like a modal popup) and add it to “custom HTML code”. 

For this, right click on the element, click “Inspect Element”, then in the Element view, right click on the tag and click Copy > Copy outerHTML

Copy element as HTML in Chrome Developer Tools

Then in purifycss.online paste the code into “Add custom HTML code”.

Add custom HTML code in purifycss.online

And then repeat from step 1 😉

Bonus tip: Optimize for First Contentful Paint (< 2s)

Now check your PageSpeed score again. You’ve done a really great job so far!

But there is one more thing you can optimize. It’s not just the PageSpeed score that matters, the perceived speed of your site matters much more. If your site takes longer than 2 seconds to show the first meaningful content, your users will be annoyed and might leave before your page even starts to render.

Even if the unused CSS is removed, your styles might still be too large. While the browser loads the CSS file, your web page remains blank. On slow connections (mobile 3G), this could be longer than we would like. 

Wouldn’t it be much better if the browser could load the CSS that is necessary to show the first visible portion right away? The rest could be loaded after the most important content is already visible. This technique is called Critical Path CSS. You’ll basically include the styles needed for the above-the-fold content as an inline-style and load the rest asynchronously. Read more about how to find critical CSS in detail.

Need a No-Code-Solution for PurifyCSS as WordPress Plugin?

Do you feel overwhelmed or unconfident with messing around in your PHP code?
I agree with you: the simplest way would be to run this purification process through a WordPress plugin. Unfortunately, there isn’t a PurifyCSS WordPress Plugin yet, but it’s on my plan.

Oh, no! I just noticed that I’m running out of coffee. 😱 I desperately need some coffee before being able to continue coding!
If you need this feature, please go to purifycss.online and buy me a coffee by clicking BuyMeACoffee in the top right corner. Thanks
😉

2 thoughts on “How to remove unused CSS in WordPress”

  1. hello,
    thank you for this tutorial,
    i have wordpress bundled with wpforo forum with di theme, i tried your tuto, but i have an issue with wpforo css and tinymce, can’t force them like elementor
    any suggestion?
    thank you

    1. Hi, the CSS calls you’re seeing in your DevTools Network tab, are initiated by tinymce.min.js. I don’t think you can do much about that, but it doesn’t necessarily harm your performance, as they are loaded asynchronously after page load. What I would suggest instead (not sure if that’s possible) is to try disabling tinymce for the pages where the editor is not needed, e.g. homepage.

Leave a Comment

Your email address will not be published. Required fields are marked *