CodeinWP CodeinWP

How Do I Force the Browser to Use the Newest Version of my Stylesheet?

If you’re a beginner and you’re developing HTML and CSS using an external stylesheet, you might notice that in some browsers, under some circumstances, the changes you’ve made to your CSS don’t take effect immediately.

Sometimes it’s necessary to do a hard refresh to see the updates take effect. But it’s unlikely that average web users know what a hard refresh is, nor can you expect them to keep refreshing the page until things straighten out.

So how can you ensure that any updates you’ve made to your CSS will take place immediately for all users? In other words, how do you force the browser to update your CSS? Here’s one way to do it:

<link rel="stylesheet" href="style.css?v=1.1">

Notice that I’m pointing to my CSS using the commonly known <link> element. But I’ve also added what’s called a query string to the end of the file name.

The browser will view a file name of style.css as different from a file name of style.css?v=1.1, so it will generally force the browser to update the CSS. So, each time you update your CSS on the server, you can incrementally update your version number.

If you’re new to query strings, just know that the part before the equals sign is like a placeholder, and the part after the equals sign is the value put into that placeholder. This will have no effect on the CSS. It will only serve to make the browser think it’s a completely different file.

You could add many types of characters to the query string value, but numbers are a logical way to do it, because then you can just increase the number, and even add decimal places if you want. And of course, if you don’t change the value for a while, the browser will continue to cache (or preserve) the file, and won’t attempt to download it unless other factors force it to, or you end up updating the query string value.

77 Responses

  1. Rich McNabb says:

    Great tip. Is it possible to do something similar in static html pages?

    • Of course. The tip is not just for dynamic server-driven pages. It should generally work to force the updating of any file, even an image file. And in virtually any type of web page, including a static page with a “.html” extension.

      • Frank Rowley says:

        Css and JavaScript does not update on my mobile phone.
        This is not a work around using JavaScript. You have tried every script you can find but all do not seem to work. What if I told you that you are looking in the wrong place for an answer? This works for both js and css . Your external scripts have their own web address. Copy the address and put it in an email and send it to yourself. On your phone open the email and click/tap the link to open it. Now you have the full code in view. Now just sweep down once to refresh the code. Now when you reopen the main page everything has updated.

    • Yes you could use this technique on static HTML pages but I would advise against it. First off it’s bad for Search Engine Optimization unless you are using canonical tag to prevent search engines from viewing the pages as different pages which can cause ranking issues. Secondly when you include a style sheet you will usually update a template so it forces your browser to look at the updated URL, with an HTML file best you can do is link to it and let people click through. The benefit of doing this for HTML pages isn’t worth it but for CSS, JavaScript, Zip files and Images using a file includes it’s perfect solution.

      • To be honest, I’m not sure if he means on the actual links to the pages, or if he’s just referring to adding the query string value to the CSS file inside of a static HTML page (as opposed to a PHP page).

        So yes, I agree — don’t use it on links to HTML pages, otherwise Google will view them as different pages.

    • peeyush says:

      Does we have to add version everytime when we upload css.

      I mean

      and so on..

      It will be static for every upload

      Looking forward reply.

      • No, you don’t have to add a version number. Most times it won’t really matter. But if you add some styles that you think will break pages if they don’t appear, it might be a good idea.

        Sometimes the browser will load the old version of the style sheet with the new markup, so it’s safe to add the version.

  2. Paddy Horgan says:

    Another way to try this is to put the hour, minute and second as a variable.

    /css/style.css?v=<?php echo date('his'); ?>

    This way you won’t have to change the value every time you want to refresh! :)

    • Agreed! This is great for development, but the reason I don’t mention it for beginners is because this should not be used in production. You don’t want no caching, you just want to control caching.

      So for beginners: Don’t use a time stamp in the live web page, only use this when you’re testing, so you don’t have to keep changing the value manually.

    • Alexei Humeniy says:

      This is recommended when the content changes a lot, such as AJAX requests or other dynamic content. CSS sheets aren’t supposed to change often so this “version” solution is a much better one.

    • Chris says:

      I really appreciate this comment, hadnt thought of that!

    • Patrick C says:

      that worked so well thank you

  3. stroke says:

    No manual refresh and no too much refresh, just the right refresh.

    
    <link rel="stylesheet" href="style.css?<?= filemtime('style.css') ?>”>
    
    • Good tip!

      For those wondering, he’s referring to this PHP function:

      http://php.net/manual/en/function.filemtime.php

      According to that page:

      This function returns the time when the data blocks of a file were being written to, that is, the time when the content of the file was changed.

      • The code will most likely eat up disk i/o everytime a request is made, for a busy website, this should be disastrous. One way to handle this is to offload the files into /dev/shm for linux servers, it’ll serve the files from memory.

    • Mark Branscombe says:

      I’ve been developing an online web game for 6 months now, and I have had to get my testers to HARD REFRESH every single time I make a change. I would’ve loved to have found this thread 6 months ago! Thank you sooo much!

  4. lush says:

    great tip!
    just one question, does this query string work in javascript files?

    I mean something like this:

  5. lush says:

    sorry, this is the code:
    <script src="/js/script.js?v=1.1"></script>

  6. Cory says:

    Awesome, i had always wondered why people put the version numbers in the link tag.

  7. You could also disable Caching in Firebug/Dev Tools Settings

    • Alexei Humeniy says:

      Please, read the article. Off course we as developers should work with caching disabled, but we can’t expect end users to disable cache just to see our website.

  8. Matt says:

    Steve Souders details why you should change the file name rather than revving files using the query string here: http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/

    Might be worth bearing in mind.

    • Good point, Matt, I didn’t know about this.

      Although, from what I understand, what he’s saying is that users on proxy services will not have any caching occur on querystringed URLs, so the performance of the site could suffer a small hit.

      My question is: How common are these proxy services? I guess you’d have to asses the situation for each site and decide if it’s a valid concern.

  9. I don’t think it’s the best option, because static resources that include query string may not be cached by the browser. I often rename the file appending the current timestamp (only when I make some change). Optimizing Cache – Leverage proxy caching

  10. Good article! You can also look into the html5boilerplate project by Paul Irish & Co. The project has a build script included, which updates the linked souces automatically. This solves the caching issue.

    Anyways, the proposed way is really good!

  11. Samuel says:

    An alternative to the timestamp method as described above is to use the first seven characters of the md5 string of the css file:

    <link rel="stylesheet" href="<?php $css_path = ‘css/style.css’; echo $css_path.‘?’.substr(md5_file($css_path), 0, 7); ?>">

    I think this method is cool to use automatic versioning instead of changing the version number every time.

  12. Peter Müller says:

    While using version numbers or even dates to bust old cached versions of a file, they are really not a good final solution to optimal cache control. You have go go one step beyond that.

    Version numbering requires manual updates and timestamps only work correctly under the assumption that you are working directly on the affected files, and not going through VCS, deployment scripts etc.

    A better metod is to have a build step that renames the file itself to a hash of its content. This way the file name become an identifier of both the file and its content at the same time. Most sites have a build step for minification and bundling anyway, just add this into the process.
    This way you could for example build and deploy your new versions of static files into the same directory as the ones that are already in production. They will just be there and be ready for being linked to by a new version of your html. Great for running multiple simultaneous versions for split testing.
    You also avoid busting the cache by having always updated your time stamp on the minified files that are generated on deployment by the build system.

    While this article mentions CSS specificly this method can and should be used for building any static asset of your page. This will give you a much more effective cache control mechanism, assuming that you have already set all static files to be served with a far future expiration date.

    There are lots of tools out there that can do this job for you.

  13. Ahmed Nuaman says:

    While this approach works, I think it’s very short sighted. One thing that developers ought to do is take time to minify their assets and package them up as collected files thus reducing the load time of their site. What we do is we package all our CSS and JS into one file, respectively, and we then change the name of that file to suit the commit version that’s being deployed, for example the SHA-1 that git provides. This is a nicer solution in my opinion.

  14. Peter Müller says:

    About busting your cache to get the newest CSS during development I can recommend setting up a development environment where your web server specificly doesn’t send any caching headers on static content.

    Refreshing the page during development still takes some time though, especially when you , like me, are doing a web application and are working on improving a part of the app that can only be seem after several clicks.

    For this case I can recommend making a setup where you can refresh only the css in the browser, not the page itself. This has improved my development time immensely.
    At work we have a development web server that tracks local file changes and tells the browser to refresh the updates css files through a websocket. This works extremely well.
    You don’t have to go all the way there though. You could for example install https://github.com/auchenberg/css-reloader in your browser of choice and just hit the CSS reload button, which gives you the same effect, though with a bit more overhead since it reloads all CSS.

  15. Tom says:

    Be aware of the performance impact when doing filemtime() or md5_file() on files. You are hitting the filesystem with “useless” stat() calls. If you are running a popular site, this matters.

    • Peter Müller says:

      Yup. Better to rename your file and update the template that includes them. The template for including static assets should be static itself anyway.

  16. Sujay says:

    i am new to this type of functonality.

    a final confirmation

    by mentioning like this as you mentioned <link rel=”stylesheet” href=”style.css?v=1.1″>

    this is just to bypass the browser cache right. and we don’t need to wait for reflecting the changes made in CSS.

    and the browser will treat the css file as a new one every time the page loads. is it just a tweek for web developers ?

    • No, it will not work every time you reload the page. It will only work if you update the “v=1.1” part each time. So if you have “v=1.1” and you make some changes, to ensure all users see the changes, just change it to “v=1.2”. But if you make more changes, then you have to update the version again. So you’ll end up with “v=1.3” then “v=1.4”, and so on, for each set of changes.

      The “v=1.1” part can actually be anything. It doesn’t have to be numbers. You could do “style.css?v=hamburger” if you want. As long as the part after the “?” is different, it will view it as a different file and reload it automatically.

      Of course, a few people mentioned that this won’t work for all users viewing the site, and it has other drawbacks, so keep that in mind. It’s not a perfect solution, just a quick and dirty one.

  17. Ashish Diwakar says:

    Well we also are using this technique in our project but, if firefox & crome a issue has been occurred, that is, CSS files with query string are considered as text/html files not as css files. Therefore the design is rendered very ugly.

  18. subhakar says:

    hi,
    i am updating my style sheet every day, some browsers don’t take Css effect immediately. So every day i want to change style sheet name dynamically. how can do it. plz give me suggestion.

  19. Steve says:

    Thanks a lot for posting this useful tip and having a website that is easy to read, you just saved me a ton of time.

  20. Tapas manna says:

    Actually I am adding the brower refresh css in website….

  21. kelvin says:

    any other solution which we got new updating content a static html , not css. the browse will detect and load latest we changes the static html page?

  22. Jonathan says:

    just use:

    style.css?version=<?php echo time();?> – this will add a timestamp (always different for every page reload) to the version number

    Use it only during testing though, otherwise you’ll get no benefits from caching

  23. Ashutosh says:

    Hey Louis, Thanks for such a time & effort saving article.

    I’m pretty novice and have made few changes in my style.css file.

    Changes have been saved on server and are visible on style.css file but not on style.css?ver=3.7.1 (the file that my web browsers are showing.

    I’m kinda newbie. Will anyone out here let me know where to add this code

    in style.css file or in header.php or in function.php

    Sorry I know I’m asking silly question

  24. dibeesh says:

    Great Tip its really helped me…

  25. sandy says:

    I’am using this tip on a wordpress site. But the issue is that, the page having the css link is itself cached by the browser. Which means that while I have updated the version in the query string, but this is not reflected in the page (checked with view page info ) unless you reload. This defeats the objective. Any pointers how to tackle this ?

    • There’s not much you can do about that unless you tell your web server not to cache certain types of pages. You could get around that yourself by simply adding a querystring to the page URL, but that’s not ideal, obviously.

  26. J. Brown says:

    Don’t know if this is helpful to anyone but I have a wordpress site that is mostly static except for an events widget that changes daily on the homepage. I ran into problems with larger cache plugins not refreshing the home page and noticed that the page speed was the same without so just stopped using them. But noticed that I would always have to refresh the page in order to see the updated schedule and feared that folks would land on a browser cache and not refresh. So I messed around and tried a simpler plugin called “Quick Cash.” It has a completely paired down functionality compared to other plugins but it automatically purges the cache whenever I make changes and forces my browser to show a refreshed page (not entirely sure why.) Problem solved though. For whatever it might be worth.

  27. nevek says:

    Thanks for the tip!!!

  28. Juan says:

    where do i place the line of code in my styel sheet?

    g

  29. Ritu Sharma says:

    Greats Tips Really Helpful for Me.

  30. Riya Yadav says:

    I should Try these step because i am a developers

  31. Marek says:

    Your solution with the line which is mentioned on top of this page is for static html pages I suppose.

    What can I do during development while making changes in the style.css file and uploading it to the server. How can I quickly view the changes?

  32. Marek says:

    addition to the comment above:
    I’m looking for a solution while making these changes in a WordPress website

    • If you’re doing this in WordPress, then you can use PHP. See this comment.

      Basically, it looks like this:

      css/style.css?v=<?php echo date('his'); ?>
      

      But don’t use that for your final production page. Remove that line once you have you are done. You want the browser to cache the page normally, whereas this will prevent any caching.

      • Marek says:

        Thanks, but where do I put that line of code?? I’m totally unfamiliar with PHP :-(

        • You have to find where WordPress inserts your stylesheet and the link to your stylesheet should have that PHP at the end of it. If that’s too complicated for you, then I recommend you learn a little more about CSS, WordPress, and PHP before attempting to do this.

          You can also do this using the querystring tip in this post, but you have to change the query string every time you upload a new stylesheet.

  33. What is the default time for the browser to update the css file automatically.

    Thanks,
    Amjath

    • I don’t think there’s a default time. I’m not 100% sure, but I understand that browsers will, by default, always look for a cached version if the same URL is requested. It will then only update the page if a cached version is not found or if an expires header is used to tell it not to look for a new version of the file.

      But the user can set the browser to always look for a new version of the file, which would override any expires headers. Also, if the user’s cache is cleared, this would also force the browser to look for a new file.

      So again, I don’t think there’s a default time, but eventually in every case the browser will look for a new version of the file.

  34. Surabhi Mittal says:

    I have done versioning in my project using gulp. How do i make sure that the latest version of js and css files will only be picked ?

  35. Sarah says:

    Great Tips I’ll use them for sure.

  36. Mark says:

    Where is the code, “” get placed?

  37. i think i can use this guide in future. i have some confusion about using tags in CSS how can i overcome that problem

  38. Luca Perico says:

    My solution is to add in httpd-boilerplate.conf these lines:

    
    <IfModule rewrite_module>
       RewriteEngine On
       RewriteCond %{REQUEST_URI} !(.*)/media/(.*)$ [NC]
       RewriteCond %{REQUEST_FILENAME} !-f
       RewriteRule ^(.+)\.(\d+)\.(js|css|png|jpg|gif|ico)$ $1.$3 [NC,L]
    </IfModule>
    
    

    And then include files in this way:

    css/style<?= $version ?>.css

    When I want clients to reload the resources, I have only to increment $version value.

  39. Simon says:

    Brilliant. Thank you so much, this saved me a whole lot of trouble!

  40. Pabodha says:

    The problem I have is, the css is not getting updated unless the developer tool window is opened. Is there a way to update the css while the developer tool window is closed?

  41. Rajesh Kumar says:

    Thanks for sharing these tips. I’ll try this..

  42. Richard Rozsa says:

    If the HTML page that references the versioned file (CSS or whatever) is in the browser’s cache, then the new version reference won’t be seen until the user manually refreshes the page. This is especially the case for the home page on a static site, or any page that the user bookmarks.
    Additionally, in the cached HTML, if referenced files have the version embedded in the filename, and the old version of the file is removed from the webserver, there’ll be an error!
    How do you allow the HTML to be cached but new versions to be downloaded?

    • AFAIK, there’s no way to guarantee that the HTML is cached while serving the updated stylesheet. I don’t think it’s possible because like you said, the version reference would be the old one. Maybe there’s a trick to this that I’m not aware of, but I also don’t think it’s that big of a concern. You’re going to be way more concerned about the CSS being cached than you are the HTML.

  43. lana crow says:

    Thank you so much!!! you totally saved the day!!

  44. Adam says:

    There are some issues with cache refresh when the CSS includes @import rules to other css files. Even if you add a random key to the end of the parent css file (style.css?key=randnum) only the parent is refreshed when the key changes. The browser still goes in and sees that the other urls for @import are the same and does not refresh them.

    Chrome mobile has this issue at the moment.

  45. Sumner says:

    I see this ?ver=2 query string solution all around the web, and I admit it works, but it’s such a kludge, since you have to change the source reference to your css file every time the file is changed.

    If you’re maintaining a non-trivial website, along with a team of other developers, and the reference to that css file exists in hundreds of configuration-controlled html or php and javascript files. Every time a developer touches that css file, all the other developers need to checkout and change their code to reference a new version number, then document their changes.

    The whole point of a css file, is to collect style definitions in one place, so that a single change can automatically take effect in the many pages that reference it, and this caching fiasco really messes that up.

    I have a vague memory of a technique I used to set a modification timestamp in a css or js file, so it was automatically refreshed after a change, but it was years ago, and I can’t remember what I did, darn it. I ran across your (and many others’) solution while searching for it.

    If only the server-client interface took care of retrieving items that have changed since they were cached, this wouldn’t even be an issue. While testing my css changes, I’m using ctrl-F5 to force a refresh, but that’s not much help for the end user, unless you’re already relying on them to clear their cache for your site to work, in which case they’ll probably breathe a sigh of relief, at how much easier it is to do the ctrl-F5 shortcut.

    Thanks for your efforts! If you figure out a way to automate this without having to change the css reference, I’d love to hear about it!

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field and deep URLs are not allowed in the "Website" field. If you use keywords or deep URLs, your comment or URL will be removed. No foul language, please. Thank you for cooperating.

Markdown in use! Use `backticks` for inline code snippets and triple backticks at start and end for code blocks. You can also indent a code block four spaces. And no need to escape HTML, just type it correctly but make sure it's inside code delimeters (backticks or triple backticks).