WordPress Logo

I’m sure you’ve had the same problem. You make some changes to your sites CSS file and don’t get to see it until you hard refresh the CSS. Damn you Mr. Browser caching my stylesheet! Damn you .htaccess for setting long expire times on my assets. Well it’s all good as it speeds up the site for your visitors. However there is a nice little work around to still use the caching but also have a little trick to get your updated file pushed out as soon as you make the changes.

The WordPress function wp_register_style (which I use to register and then enqueue all my stylesheets) does have a parameter for version number which comes in very handy.

Firstly let’s have a look at my function which handles all my CSS.


function global_css() {

 wp_register_style( 'parent_main', get_template_directory_uri() . '/css/main.css', false, null, 'screen' );
 wp_register_style( 'child_main', get_stylesheet_directory_uri()  . '/style.css', false, null, 'screen' );

 if ( ! is_admin() ) :
 wp_enqueue_style( 'parent_main' );
 endif;

 wp_enqueue_style( 'child_main' );
 }

add_action( 'wp_print_styles', 'global_css' );

So what’s happening? Firstly I’m registering my main.css which is where I include all my css. I use style.css only for child theme overrides. Note I am using the correct WordPress functions to get the right URLs! This works great along with a little add_action. I do not have any dependancies so you can see the false. The null refers to the version so WordPress is not adding a version number to the URL.

Using a lovely little PHP function we can append the file’s last modified time. filemtime() is lovely! Here’s our updated code:

</pre>
function global_css() {

 wp_register_style( 'parent_main', get_template_directory_uri() . '/css/main.css' , filemtime( get_template_directory() . '/css/main.css' ), null, 'screen' );
 wp_register_style( 'child_main', get_stylesheet_directory_uri() . '/style.css' , filemtime( get_stylesheet_directory() . '/style.css' ), null, 'screen' );

 if ( ! is_admin() ) :
 wp_enqueue_style( 'parent_main' );
 endif;

 wp_enqueue_style( 'child_main' );
 }

add_action( 'wp_print_styles', 'global_css' );
<pre>

Now WordPress will output:

<link rel='stylesheet' id='parent_main-css'  href='http://www.mydomain.com/wp-content/themes/mytheme/css/main.css?ver=1344252157' type='text/css' media='screen' />

Note the ?ver= added to the CSS URL! When we update and save our CSS file this number will change and force the browser to re-download the file. We’re not forcing it to redownload the file unless the modification time has changed so browser caching and any caching plugins you have working will still work as expected!

Job done!

UPDATE: I noticed some mistakes in my code around get_template_path(), this has now been fixed. Sorry!
UPDATE 2: I am a major idiot. More errors fixed.

 Tagged with: , , ,

14 thoughts on “Get your WordPress CSS changes noticed immediately!

  • Great help, thanks! I’ve got the snippet adding a version number, but it’s adding the WordPress default of: ?ver=3.9.2 (or whatever version of WP I’m on), and it’s the same every save/reload, rather than a timestamp. Am I missing something?

     Reply

  • Hi MojoWill, very nice – i came across filemtime() for the first time today. In terms of build process, have you worked with a process where the stylesheet versions are updated during a Git deployment for example, in which case $ver is populated automatically?

    That’s the impression i get when looking at the $ver parameter for wp_enqueue_style() is that it was meant for a build process, for most WordPress sites, i’d be nice to see this done automatically part of core.

     Reply

    • I’m sure you could do but you would need to use a build script to package up your site which could then replace the variable with your version number. Not something I am familiar with though.

       Reply

  • Have you thought about submitting this into core as a default to enqueuing scripts/styles? Something like this?

    function wp_enqueue_script( $handle, $src = false, $deps = array(), $ver = ‘auto’, $in_footer = false ) {

    if ($ver === ‘auto’) {
    $ver = filemtime($src);
    }

     Reply

    • Thanks for your comment Ryan, it’s an interesting idea but has a slight issue to overcome. $src refers to a URL typically set using get_template_directory_uri();. filemtime() requires a file PATH not a URL hence why we use get_template_directory(). We would need to think about how to get the file path and pass that through to the core function.

       Reply

  • Thanks for this. It was exactly what i’m looking for but I can’t get it to work!
    I tried your code but it doesn’t validate and causes a white screen on the front-end. The below code works but doesn’t output the query string on the end.

    Here’s my code:

    function this_is_my_function() {
    if (!is_admin()) {
    wp_register_style( ‘stylesheet’, get_stylesheet_directory_uri() . ‘/style.css’, array(), filemtime(get_stylesheet_directory_uri() . ‘/style.css’), ‘all’);

    wp_enqueue_style( ‘stylesheet’ );
    }
    }

    add_action(‘wp_enqueue_scripts’, ‘this_is_my_function’, 999);

    Can you offer any help?

     Reply

    • Opps looks like I made a couple of stupid errors in the Code example. Take a look at it again specifically the get_template_directory() and get_template_directory_uri() which have changed!

       Reply

      • Nope, still not working. The code you’ve given doesn’t validate and returns an error – expected ‘)’.
        The below code validates but doesn’t append a query string:

        wp_register_style( ‘stylesheet’, get_template_directory_uri() . ‘/style.css’, filemtime( get_template_directory() . ‘/style.css’), array(), ‘all’ );

         Reply

        • Ah Ok re-check I made super stupid mistakes and have fixed them!

           Reply

  • Pingback: Об ошибках в разработке под WordPress и как их исправить | Wordpresso

  • The Versions plugin takes care of this automatically for scripts and stylesheets. It generates version numbers based on the files latest date of modification. It’s at: http://wordpress.org/extend/plugins/versions/

     Reply

    • Seems unnecessary to use a plugin when it only takes a couple of extra words in your theme.

       Reply

  • Pingback: Common WordPress Development Mistakes and How to Fix Them | Wptuts+

  • Pingback: Common WordPress Development Mistakes and How to Fix Them | Wordpress Webdesigner

Leave a Reply

Mojowill Avatar

Who the Hell am I?

I'm Will, a full time web developer, geek and musician. I develop using PHP and MySQL and spend most of my time working with WordPress or CakePHP. When I'm not buried in code I'm gaming, cooking or writing and recording music in my studio. I like sci-fi, pancakes and coffee and am totally prepared for the zombie apocalypse...

Stalk me on these other sites...

Why not be super creepy and check me out on all these other sites, I think they call it social media?