uncss: Find Unused CSS

By  on  

You know what's better than adding features to a website or app, from a code perspective?  Removing stuff you don't need.  Whether it be code, images, or dependencies, getting rid of the crap stale code is like the first sip of a big glass of wine after a long day of stressful work.  Running a directory of images through ImageOptim is a euphoric experience, am I right?  What if there was a tool, however, which would allow you to find unused CSS for a given website?  There is, and it's called uncss, a NodeJS powered utility.  Let's take a look at how uncss works!

A basic usage of uncss's command line tool would be:

uncss https://davidwalsh.name > styles.css

The output of this execution is a stylesheet featuring only the used CSS rules -- unused rules are removed.  So how does uncss work?  I'll let them tell you how:

  1. The HTML files are loaded by PhantomJS and JavaScript is executed.
  2. Used stylesheets are extracted from the resulting HTML.
  3. The stylesheets are concatenated and the rules are parsed by css-parse.
  4. document.querySelector filters out selectors that are not found in the HTML files.
  5. The remaining rules are converted back to CSS.

Like just about every NodeJS-based utility, you can also take advantage of its JavaScript API.  Here's an example usage:

var uncss = require('uncss');

var files   = ['my', 'array', 'of', 'HTML', 'files'],
    options = {
        ignore       : ['#added_at_runtime', /test\-[0-9]+/],
        media        : ['(min-width: 700px) handheld and (orientation: landscape)'],
        csspath      : '../public/css/',
        raw          : 'h1 { color: green }',
        stylesheets  : ['lib/bootstrap/dist/css/bootstrap.css', 'src/public/css/main.css'],
        ignoreSheets : [/fonts.googleapis/],
        urls         : ['http://localhost:3000/mypage', '...'], // Deprecated
        timeout      : 1000,
        htmlroot     : 'public'

uncss(files, options, function (error, output) {

/* Look Ma, no options! */
uncss(files, function (error, output) {

/* Specifying raw HTML */
var raw_html = '...';
uncss(raw_html, options, function (error, output) {

There's no arguing that years of maintaining, adding, and removing from a site will add excess code to the codebase.  That excess code comes at the cost of users who have load the extra code, so eliminating the dead code is important.  Give uncss a try -- it's an easy to use, automated helper to keep your codebase as tight as possible!

Recent Features

  • By
    5 Awesome New Mozilla Technologies You’ve Never Heard Of

    My trip to Mozilla Summit 2013 was incredible.  I've spent so much time focusing on my project that I had lost sight of all of the great work Mozillians were putting out.  MozSummit provided the perfect reminder of how brilliant my colleagues are and how much...

  • By
    6 Things You Didn’t Know About Firefox OS

    Firefox OS is all over the tech news and for good reason:  Mozilla's finally given web developers the platform that they need to create apps the way they've been creating them for years -- with CSS, HTML, and JavaScript.  Firefox OS has been rapidly improving...

Incredible Demos

  • By
    NSFW Blocker Using MooTools and CSS

    One of my guilty pleasures is scoping out the latest celebrity gossip from PerezHilton.com, DListed.com, and JoBlo.com. Unfortunately, these sites occasionally post NSFW pictures which makes checking these sites on lunch a huge gamble -- a trip to HR's office could be just a click away. Since...

  • By
    Advanced CSS Printing – Using JavaScript Double-Click To Remove Unwanted DIVs

    Like any good programmer, I'm constantly searching around the internet for ideas and articles that can help me improve my code. There are thousands of talented programmers out there so I stumble upon some great articles and code snippets that I like to print out...


  1. This looks awesome David, gunna give it a whirl tonight and see what gaping hue holes there are lol

  2. Does this take into account prefixes? If so, this would make a great addition to my Grunt builder!

  3. If you’re in the browser, you can use Google Chrome for this. Open the Web Dev tools, Click on the Audits tab, click Run, and then look through the “Remove unused CSS rules” list.

    Only for a single page though.

    • Which if you have more than 4 or 5 pages on a site, is a true pain in the arse.

  4. Slightly different, but I have always used “Dust me selectors”, its a browser plugin that helps to find and build a list of unused selectors.

  5. Does this work for a single page ? Or for the entire website. Because there may be few styles that are written in a common .css file but of which say 40 lines of css are written exclusively for page 1 and 20 lines of css exclusively for page 2.

    Is that handled ?

  6. I also use Dust-Me Selectors in Firefox. You can crawl your whole site supplying it with a sitemap.

    While these housekeeping tasks of clearing out images, js, css, have lower priority for many, it would be handy to have a sophisticated solution to make it easy to maintain overall

  7. how does this handle a CMS (such as WordPress) with dynamically generated URLs?

  8. What about class names that are added dynamically using javascript? If it filters out rules that are not being used in the initial HTML load then any user actions which cause class name changes will loose their styles as they will be filtered out.

  9. Very useful Nodejs utility. Let me add in my workflow with Gruntjs. Thanks David!

  10. Mick

    I’m with Norcross. This sounds like a fantastic tool, and works well in my tests on static html, but what about WordPress?

    I’ve search high and low for a solution for this, the closest I have come is suggestions to use PhantomJS in tandem with UNCSS, but no further explanation.

    It was my understanding that uncss was already using phantomjs to find all the unused selectors, so how does one crawl a dynamic site?

  11. srigi

    Nice tool, I’m considering to use it in future. However I have two practical questions:

    1. How to use this on responsive sites? This tool will definitely return different sets of styles when run in for example xsmall & large screen mode. There must be some kind of login on the server, that provide correct styles for the device, or some kind of merge of different styles sets.

    2. What then? Everybody is proposing this new coolnes, but nobody is blogging what to do after. Should I load full CSS asynchronously? Or should I put before ending ? Or should I do diff between uncss & full CSS and load this diff?

  12. srigi

    *Or should I put <link rel=stylesheet>before ending <body>?

    • Greg Davis

      Check out this post for WordPress integration:

      Here show’s a way to ignore classes like .hidden-xs in the Gruntfile.js:

          uncss: {
                dist: {
                  options: {
                    ignore       : ['.hidden-xs'],
                    stylesheets  : ['wp-content/themes/SBWordpress/style.css'],
                    ignoreSheets : [/fonts.googleapis/],
                    urls         : [], //Overwritten in load_sitemap_and_uncss task
                  files: {
                    'wp-content/themes/SBWordpress/style.clean.css': ['**/*.php']
  13. Thanks David, nice to get a short run through / how to for using uncss, I still need to give it a whirl as I saw it mentioned in another article that I read recently, but its on a very long list of things to look at :(

  14. If anyone uses Ruby On Rails and does extensive Integration Testing, my Headhunter Gem does exactly what you need to find unused CSS automatically (see my website link).

  15. I did the same with python.
    Also uses PhantomJS.
    You can run it with a list of URLs.

  16. I did not read the whole article but the comments seems more interesting, never thought theres so much on this subject. Good work guys !!

  17. Dan

    This is good but needs to be a web app to be quicker and easier by uploading your CSS file and then viewing the results.

  18. Thomas Semmler

    Does this also work with php files, or does it only support *.html?

    • Supports all types of files — it analytics script *output*.

    • Carlos Rico

      But if I want to integrate this as a task in build time of my project, where my templates have not yet been processed, would it be possible?

  19. For this to work on Foundation 5, had to add this to options:
    ignore: [/meta\..+/]
    Otherwise Syntax error, unrecognized expression: [data-'Times New Roman'-abide] is thrown.

  20. Derek

    This looks cool, but there are so many valid unanswered questions. Sigh…

  21. Ian

    Wish someone could make a GUI app for this that, say, you could integrate with a browser and manually browse a dynamic site like WordPress, ending up with all the used CSS that you could then combine and minify. Maybe then it could go with a plugin that would handle some kind of output of the app, automatically deregister stylesheets and scripts not in use, and use the minified CSS/js to then run the site. I don’t know why this is still a far-off dream for the layperson. Speeding up the web in a simple way would be great for everyone.

  22. Andrew

    David, any ideas on how to use uncss with a site that has a “members” area that you login to via the http post request. I have managed to login and get screenshots of the members area using PhantomJS directly, but can’t see anyway to do this when using uncss. Thanks.

  23. Mark

    I ran this on a larger site and it seems like it removed all the JS injected CSS Classes. For example Bootstraps .collapsing, .collapse.in, btn.disabled etc …

    I’ve had a somewhat easier time with PHPStorm using “Inspect Code” and checking ‘unused css’ and cleaning it up that way. The ease of letting something else do it for me is appealing, but not at the expense of termites.

  24. For those wondering how to use this with WordPress I highly recommend checking this out:


  25. does this functional codes remove all unused css-s from entire a website with a root address?

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!