If you update your WordPress theme’s style.css
, you may have noticed that you have to “force-reload” your site in your browser to see the changes. This is because your browser keeps a copy of the CSS cached on your hard drive. Depending on how your server is set up, it may not check for a new version of the stylesheet for a couple hours, or longer! And even if you force-reload to see the changes, visitors who have previously accessed your site may still get the old CSS. One way to solve this is to “version” your CSS file, by adding ?v=123
to the URL in the <link />
to your stylesheet. This is rather a pain to have to do by hand every time, so here is a much better way:
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); echo '?' . filemtime( get_stylesheet_directory() . '/style.css'); ?>" type="text/css" media="screen, projection" />
This automatically updates the ?12345678
ending part every time you modify the file. Boom. Now everyone instantly sees your changes.
Does this method even need “v=” in between the ? and the variable? Just thinkin’ of ways to simplify even further.
Either way, this is a great method. Ever since I’ve heard about it about a year ago, I’ve used it everywhere.
i like setting long future expires headers and this is an excellent solution for reloading files. can also extend out to javascript files just as easily.
Thanks for this simple solution to a frustrating problem.
Thank you! This was ticking me off earlier in the day when I was editing CSS like a banshee.
Aha. That makes this a lot easier.
Would this also work for JavaScript files? I often make changes to JS and have users report that they are getting errors caused by outdated versions of functions… it’s a PITA! 😉
That’s just awesome man. Cleverest solution I’ve ever seen about CSS changes.
Awesome! Thank you very much! 😀
Great trick, better than putting a ?1 or ?2 after the file path 🙂
Yep, this will work for JavaScript. Yes, you could drop the
v=
part to save two characters. 🙂That’s a great tip. If you know your CSS URL will change when you update it, you can set it to be cached for a long time and reap the performance benefits.
I believe there’s a plugin for this even.
I have WordPress running on Apache on it’s own server, and a separate server running Nginx that serves static files such as the CSS.
Is there a way to check the file time stamp from the WordPress/Apache server to the Static/Nginx server over http without PHP running on the Nginx server?
Also, since many of the static theme files run on the Nginx server, which also serves images, the Turbo function will not work in my WordPress control panel. It would be nice to be able to define a path to files for Gears to search for the files on remote, and local, servers at the same time.
WOW..Thats simply great trick. I always used to make changes to my css. this one is super cool.
Really Great Tip. Thanks for that – I think I will featuere it in my blog.
Nice tip. Thanks!
Is there a reason you use:
/style.css?v=
instead of:
?v=
?
The second works with child themes too and it is also a few bytes shorter. 😀
(Repeating last comment without the PHP tags.)
Nice tip. Thanks!
Is there a reason you use:
bloginfo(‘template_url’) + /style.css?v=
instead of:
bloginfo(‘stylesheet_url’) + ?v=
?
The second works with child themes too and it is also a few bytes shorter. 😀
There’s still a gotcha: it seems that some browsers don’t cache files with a query string
@demetris: you’re right, that should actually be calling bloginfo(’stylesheet_url’). Also, instead of using the TEMPLATEPATH constant, get_stylesheet_directory() would be much better, since it takes into account any plugins that hook into the ‘stylesheet_directory’ hook.
@Will: There is a STYLESHEETPATH constant too, whose value is get_stylesheet_directory().
(So, if stylesheet_url is used, the file to check the modification time for is: STYLESHEETPATH + /style.css)
@demetris: sure, but you still have the same problem of bypassing any plugins that may be using the ‘stylesheet_directory’ hook to pull the stylesheet from some place else entirely.
Thanks. Love little incremental theme improvements.
Will, Demetris,
Updated to use
get_stylesheet_directory()
andget_bloginfo('stylesheet_url')
and to drop thev=
part. Thanks!Or, now that I think about it… you could just add a filter on the ‘stylesheet_uri’ hook to append the timestamp. Then it would work on any theme without modification, provided that they are properly calling bloginfo(‘stylesheet_url’), which I think most do.
Yes, yes, there are a number of different ways you could do it. 🙂 Regardless of what method you use, a great idea. Thanks Mark!
couple of typos in that last snippet of code, but you get the idea.
i think this very useful…….. thanks
Dude, this rocks! When I am developing in WP I always have to have the CSS file loaded in a tab and force refresh. This will save me lots of F5ing! thanks!
I used this on my site, not a wordpress site, but works all the same!! love it..
I believe according to http spec, browsers should not cache URI’s with GET parameters in it. Not sure what browser implement this correctly.
A solution would be to embed the file version number in the filename itself. E.g.: my-css-file.v123.css.
@Pim, I don’t see that in the spec. I’ve heard that some proxies do this, but regular browsers should cache such URLs just fine.
where the heck do i paste that code???
hmmm, strange
does not work for me (tested in Chrome 2 and FF)
before:
after:
but the old css is still used until i hit [F5] (manuel forced refresh)
any ideas why?
i think this very useful…….. thanks
very nice..
very good code
burhaniye,ören
çan,ilçesi,resimler,haberler
This is not a very good solution. You lose the advantage of caching which is one of the benefits of having an external stylesheet. Now your stylesheet has to be downloaded and parsed on EVERY PAGE LOAD which means longer page load and rendering times. This hurts your users’ experience on your site. It also means your eating unnecessary bandwidth. And for what? So your users get a new styleheet IF you happened to have made changes to it recently? Does your stylesheet really change THAT often? Is caching really that much of a problem? Almost certainly not.
Browsers caching stylesheets is rarely a real problem and this solution is overkill. I definitely don’t recommend it to anyone who doesn’t have a VERY dynamic stylesheet (i.e. ones changes very, very frequently. I mean every few minutes or so).
John, are you referring to the solution in the very first post? If so, it’ll only invalidate the cache if the style sheet is modified. If you only modify it every six months, then for those six months, the address to the style sheet will remain unchanged and it’ll be cacheable.
A change to the style sheet will change the modified time appended to the URL, which the browser sees as a “new” address and so will load the style sheet freshly from the server.
so how can it be, that i dont see any effect in my browsers?
they still use the same cached file, even
if layout.css?1 is now layout.css?2
any ideas?
I see the same problem in IE7, it’s not working. I have to manually visit the css file’s url then it works.
I have to agree with Ozh, “There’s still a gotcha: it seems that some browsers don’t cache files with a query string”…
Simplest solution we’ve used is to version number your CSS, so it might be
master1.css
after some changes you don’t want cached, name it:
master1.1.css
Its a whole different file, and will force your browser to load it.
Good luck.
Thanks for this simple solution to a frustrating problem.
Good luck.
Wouldn’t a plugin work better? http://wordpress.org/extend/plugins/css-cache-buster/
State of the Word – WordCamp Mid-Atlantic
Thank You ! 🙂
thanks. super
Thank You Mark! 🙂
Nice try…
Awesome Mark!
Oh, yeah, oh, yeah, this is cool, I marked my files using time(), but this is much better, as this only forces a reload when the file changes.
But isn’t there a way to make the browser “do the right thing” via .htaccess file? I think it would be better.
Thanks so much!
It only goes to show where there’s will there’s a way. Keep on trying.
thx thx thx
thanks – works well
outstanding!
Excellent , thanks very much 🙂 working very well , y saved my a lot of time 🙂
most useful, jsut what i was looking for – thanks!
Great tip, thanks a lot!
thanks works well
Good information. Thank you.
Good grief, this is one of the most useful tips I have ever come across! Why didn’t I learn this years ago?
Massive thanks.
Unfortunately that’s not the recommended way, please see http://code.google.com/speed/page-speed/docs/caching.html#LeverageProxyCaching.
Much better solution is to automatically include some unique information in the filename itself, like md5, version number or maybe a timestamp.
One possible solution can be found here: http://stackoverflow.com/questions/118884/what-is-an-elegant-way-to-force-browsers-to-reload-cached-css-js-files
Thanks a lot, you’re a life-saver!
Excellent tips .I really appreciate all these points, and I agree completely…
11
Thank you, thank you, thank you. You have no idea of how much grief this has caused me with different people being served by different ISPs.
Great post. Just curious how would this work if u wanted to load multiple stylesheets? doesnt stylesheet_url direct you to the main style.css of the parent theme?
PHEW!!! thank you Mark, I have this problem about editing my CSS live and the edited CSS wont take effect everytime i refresh… you’re my life saver 😀
Thanks for this code!
Great Mark, always a good post
Thanks 😉
Very good! It also works for regular PHP projects with/without frameworks =)
Thanks, man!
InFog
WordPress enqueue_style function outputs css with time stamp ( using filemtime( get_stylesheet….)
like this
href=’http://127.0.0.1/brand/wp-content/themes/brand/css/default-layout.css?ver=1294031380′
and posted tutorial outputs like this
href=”http://127.0.0.1/brand/wp-content/themes/brand/style.css?1309415833″
no VER=
which way is better, if any?
Either way works just as well as the other; the point is that the browser sees each as a specific URL so that when the string of numbers changes, it’s recognized as another distinct URL. This results in the style sheets being loaded fresh from the server.
Thank you Rick ! So I added ver= to Mark’s code.
Perfect! Thank you!
cheers for this
Perfecto … muy interesante.
Ya estaba loco con el CSS y la personalización de un fan box de Facebook
Thanks mate!
YOU HAVE ABSOLUTELY HOW MUCH THIS HELPED ME.. WordPress was taking 5-10 minutes to reflect CSS changes no matter WHAT I did, even what computer or theme I used. It was driving me insane. This fixed it. It should be added to WordPress.. Thank you so much!
thank you.
I just put a large site live, and when I noticed how badly the old css mashed the layout, I went in to adrenaline mode, and you save the site with only 20 seconds of mash-d time.
Thanks. Hopefully not to many people saw it.
I’ll use this from now on
Just wanted to say thanks a lot for this solution. Used now and will use again in the future.
Cheers
Thank you so much for this, I’ve been updating the css on my site like mad today and panicked when it wasn’t reloading, even on a force-refresh.
Sorry I am a newbie.
Please can you tell where to add this code – In header.php or style.css ? Also which part of the file ?
Thank you very much
IQ
thanks for the tip… I used this style in my non-wp site:
<link rel="stylesheet" type="text/css" href="/css/home.css?”>
That way it uses the file modified time of the stylesheet and only changes the get request param when the file is changed. However if browsers really don’t cache any get requests, then I suppose you might as well just use ANYTHING in the query string and it will work in the same non-efficient way
oops, the php code was stripped out of my comment. I guess you’ll never know what i posted! lol sorry