Stefan Hayden

Alt + Shift + Ctrl + K

CSS Caching Hack

If you change the HTML and the CSS of a page there is a decent chance that a user will get the new HTML but not the new CSS. This is especially true for sites with high usage and users that come back to the site several times a day.

If they only get the new HTML but not the new CSS then the site will break, the user will get confused, and you will look unprofessional. On the development site of this the problem is already solved. Having a Dev server as a place to test code is standard practice but how does this translate to CSS?

The problem is that the CSS is cashing on the client side and there isn’t an obvious way of telling the browser to un-cache it. Luckily the key word is obvious. Though it’s not in wide use there is a quick hack that will keep your CSS as fresh as your HTML.

The trick is to pass a variable on the end of the CSS file like so:

<link rel="stylesheet" xhref="http://www.stefanhayden.com/style.css?version=1" type="text/css" />

What does ?version=1 mean? This is what a URL looks like if it’s passing a GET variable from one page to the next. To the browser it means the page is dynamic and it needs to get a new version because code may have changed. The browser has no way of knowing if the CSS file is actually dynamic or not.The trick is to change the number each time you update the CSS file to make sure the browser always downloads the new code.

When a browser looks to see if it has anything cashed it compares file names. If you have “style.css” in your cashe then it’s not going to download it again. But if the browser compares “style.css?version=1” to what the new HTML is “style.css?version=2” then the browser thinks they are different files and needs to download the new CSS file.

The other reason this works is because you can add anything you want after the ? and the web page just ignores it unless it’s an actually variable on the page.

This seems to be a really good solution to version css and yet so few seem to use it. The only 2 sites I know of who do is Odeo and Sconex. Yet clearly we are in the middle of a big web boom with CSS being used every where. How are other people versioning their CSS so it doesn’t break the user experience?

In general I can’t see to many other solutions. You could make the CSS file parsed by the web server and pass headers with different cacheing info. I have not tried this but I’ll bet the browser would still cache the file as it does not know it is dynamic even if it is. You could rename the CSS file with .php but clearly no one is doing that and I’ll bet there is a browser out there that would not apply the styles because of that.

No every one gets to work on a large production site but with so many jumping in the area and quickly updating the service I’m surprised this subject has not been covered.

odeo, sconex, css, versioning, hack

122 Comments
Gravatar

very nicely written. Thanks a lot for sharing it

Gravatar

Hi,
I insert the date and time stamp after css path … and in this way every refresh is “new”

<link rel="stylesheet" type="text/css" href="style.css?” />

Gravatar

I see here not apear the parameter after “?” … (it is the date/time stamp) wrote in php …
tray it my forum … http://fhuba.ro/viewtopic.php?p=982#982

Gravatar

Good trick. You can even use it inside a , with the @import statement.

e.g.
printf(“@import \”%s/css/main.css?version=%d\”;\n”, BASE_URL, getCSSLastUpdate());

Where getCSSLastUpdate is:

function getCSSLastUpdate() {
if (defined(‘CSS_PATH’) && file_exists(CSS_PATH)) return filemtime(CSS_PATH);
return 0;
}

(add a CSS_PATH define to your env file so that it points to whatever CSS matters).

Gravatar

just realise you can simplify the code above by just going:

printf(“@import \”%s/css/main.css?version=%d\”;\n”, BASE_URL, filemtime(BASE_URL . ‘/css/main.css’));

Gravatar

I agree with William S. PHP is the way to go

Gravatar

great tips. keep it up

Gravatar

Is it just me or does internet explorer completely IGNORE css?

Gravatar

hell yeah this is great

Gravatar

I have seen many css files included with ?version=number, i always just wondered. Almost thought css gets some GET values :P Thanks for informations, now all doubts gone.

Gravatar

amazing….. thanks for tips

Gravatar

amazing….. thanks

Gravatar

great tips and nice information you have shared, i like it.

Gravatar

Excellent tip. and its not even a hack if you really think about it.

Gravatar

This is extremely helpful, You are an excessively professional blog writer. I have registered your feed and turn up for in search of even more of your great posting. Also, I’ve got shared your website within my social networks!

Gravatar

Why it is not used is because HTTP GET with a parm , i.e ?, is a non-cacheable item and so this works because it never get it from the cache which is not a good thing. If you do this you have to make sure the web server is marking the content as cacheable.

Gravatar

Hey nice tip…!
Thanks a ton ;)

Gravatar

Oh man – thanks for this!
Was tearing my hair out with IE9 seeming to cache the CSS no matter what I did.
Worked straight up just adding ?Ver=1 after the css file call :)

Gravatar

Very elegant. Incredibly simple yet completely effective. How did I not think of this?

Thank you!!

Gravatar

Really nice solution. Thank you very much!

Gravatar

I use a similar solution, but thank you for this its a lot simpler and pretty obvious. Not sure why more websites don’t use this?

Gravatar

[…] users weren’t getting updates to CSS and image files. CSS is rather easy to resolve using the well-known query string hack, but doing the same for images referenced from within the CSS files is a bit trickier. Luckily the […]

Feed Icon Comment Feed

Post a Comment