CSS Lint open sourced

Nicholas Zakas and I spoke at Velocity a few minutes ago. First we talked about CSS 3 and it’s impact on performance, then we demoed and open sourced CSS Lint! I really couldn’t be more excited (or relieved, I was super duper nervous before this presentation).

CSS Lint is a tool to help point out problems with your CSS code. It does basic syntax checking as well as applying a set of rules to the code that look for problematic patterns or signs of inefficiency. The rules are all pluggable, so you can easily write your own or omit ones you don’t want.

Rules currently tested

  • Parsing errors should be fixed
  • Don’t use adjoining classes
  • Remove empty rules
  • Use correct properties for a display
  • Don’t use too many floats
  • Don’t use too many web fonts
  • Don’t use too may font-size declarations
  • Don’t use IDs in selectors
  • Don’t qualify headings
  • Heading elements should have a consistent appearance across a site.
  • Heading styles should only be defined once
  • Be careful using width: 100%
  • Zero values don’t need units
  • Vendor prefixed properties should also have the standard
  • CSS gradients require all browser prefixes
  • Avoid selectors that look like regular expressions
  • Beware of broken box models

(We’ll allow you to turn off rules that hurt your feelings soon!)


Many people have expressed an interest in contributing to the CSS Lint project. We were waiting to have a solid plugable architecture and API before taking contributions. The exciting news is that we are now ready! There are several ways you can contribute:

  1. If you are comfortable with CSS, submit rule ideas. You must provide the rule name, a human readable explanation, browsers affected, and a test case.
  2. If you are comfortable in JavaScript, fork the github project, code up a rule, and submit a pull request. You’ll need to provide all the same documentation requsted in item 1.
  3. If you are comfortable with Node, test out the command line version, submit feature requests.

CSS Lint for Node.js

If you’d like a command line version of CSS Lint, you can install CSS Lint for Node.js using npm using the following:

sudo npm install -g csslint

Once installed, you can pass in any number of CSS files or directories containing CSS files to see the results. For example:

csslint test.css dir_of_css/ test2.css

You’ll receive the same errors and warnings as you would with the web interface.

20 thoughts on “CSS Lint open sourced”

  1. Do you plan to you share your slides or even the talk? I’d love to see it!

    CSS3 impact on performance is an important subject for me. It often affects the performance *after* page load which can be easily missed. If a page loads fast but feels sluggish in use because of e.g. huge box shadows, one should consider using a png for example. It’s an additional request but it can make a huge difference in the overall feel and smoothness.

    CSS Lint seems to be a great companion for less.js, which we use more and more. Both run on Node.js, and with using Less you let slip away quite a bit of control over the resulting CSS code.

  2. Don’t qualify headings

    What is the alternative to using qualified headings?

    e.g. .sidebar .widgetName h2 {}

    P.S: Wow my code is soo much smaller and cleaner since I learnt about OOCSS on the big web show! -_-

  3. Hey Nicole! This looks really promising.
    Not quite sure though why margin (or padding for that matter) shouldn’t be used on inline elements – “margin-left can’t be used with display: inline.” I can’t find any mention of it in the w3c specs.

  4. @Arunan: You should only declare h1-h6 in general and add classes to get more variants. Declare .h1-.h6 the way you declare h1-h6 in terms of font size etc. Then you could define e.g. .boxHeading for an additional variation, say a different color.

    If you do it this way, you have a heading variant for your widgets. If you might want to use that heading style elsewhere later, you don’t have to add more CSS code. You can simply apply the .boxHeading class to more headings.

  5. This is excellent. Well done!

    “2 IDs in the selector, really?” — love that description! I can hear you saying it.


    1) The documentation link is hidden away at the bottom of the page, beneath my 717 (!) warnings. It would be useful to have that more prominent.

    2) It would be useful to group the warnings by type (you know, like an expandable / collapsible list), so I can get a high-level overview of the kinds of mistakes I’m making.

  6. @Nicole — done!

    And here’s one more (also gitted):

    I’m hearing some concern in the community that CSS Lint is “forcing Nicole’s OOCSS beliefs on designers, by stealth”. I don’t agree (you’re not forcing anyone!), but it might be helpful to make the connection between the CSS Lint and OOCSS clearer. I can’t see any reference to OOCSS on the CSS Lint website.

  7. CSS lint is nice! Great work!

    I wondered: did I spot an error? Underneath my 392 warnings and 1 error, there was a bit of content which begins with “55 lines 1 errors 392 warnings”. It displayed what I think is the example code instead of (what I expect it should do) my own CSS which was 1323 lines long. Is this feature an error or a feature? For debugging reasons I made a screenshot of the thing. If you want it, I can send it to you.

    But anyway: Great work! It’s a good thing this CSSlint is here and performing so well! Thanks a lot!

  8. I have a question regarding heading styles.
    Say h1-h6 will have the same font-family, but different font-sizes, is it really wrong to do so:

    h1, h2, h3, h4, h5, h6{font-family: ‘font-family’;}
    h1{font-size: x;}


    Or it would be better to declare font-family separately for each heading even if they are the same?
    If so, why?

    Thanks! (:

  9. Excellent project! First impressions:
    At first it didn’t seem to work on my stylesheet (finding 0 errors), but when I removed the @font-face rules for webfonts at the start of the stylesheet, then CSS Lint was giving me a nice list of errors and warnings that I still have to go through.

    * Please check if multiple webfont implication like this gives problems:
    @font-face {
    font-family: ‘CharisSILRegular’;
    src: url(‘../fonts/CharisSIL/CharisSILR-webfont.eot’);
    src: url(‘../fonts/CharisSIL/CharisSILR-webfont.eot?#iefix’) format(’embedded-opentype’),
    url(‘../fonts/CharisSIL/CharisSILR-webfont.woff’) format(‘woff’),
    url(‘../fonts/CharisSIL/CharisSILR-webfont.ttf’) format(‘truetype’),
    url(‘../fonts/CharisSIL/CharisSILR-webfont.svg#CharisSILRegular’) format(‘svg’);
    font-weight: normal;
    font-style: normal;

    @font-face {
    font-family: ‘CharisSILItalic’;
    src: url(‘../fonts/CharisSIL/CharisSILI-webfont.eot’);
    src: url(‘../fonts/CharisSIL/CharisSILI-webfont.eot?#iefix’) format(’embedded-opentype’),
    url(‘../fonts/CharisSIL/CharisSILI-webfont.woff’) format(‘woff’),
    url(‘../fonts/CharisSIL/CharisSILI-webfont.ttf’) format(‘truetype’),
    url(‘../fonts/CharisSIL/CharisSILI-webfont.svg#CharisSILItalic’) format(‘svg’);
    font-weight: normal;
    font-style: normal;

    @font-face {
    font-family: ‘CharisSILBold’;
    src: url(‘../fonts/CharisSIL/CharisSILB-webfont.eot’);
    src: url(‘../fonts/CharisSIL/CharisSILB-webfont.eot?#iefix’) format(’embedded-opentype’),
    url(‘../fonts/CharisSIL/CharisSILB-webfont.woff’) format(‘woff’),
    url(‘../fonts/CharisSIL/CharisSILB-webfont.ttf’) format(‘truetype’),
    url(‘../fonts/CharisSIL/CharisSILB-webfont.svg#CharisSILBold’) format(‘svg’);
    font-weight: normal;
    font-style: normal;


    @font-face {
    font-family: ‘CharisSILBoldItalic’;
    src: url(‘../fonts/CharisSIL/CharisSILBI-webfont.eot’);
    src: url(‘../fonts/CharisSIL/CharisSILBI-webfont.eot?#iefix’) format(’embedded-opentype’),
    url(‘../fonts/CharisSIL/CharisSILBI-webfont.woff’) format(‘woff’),
    url(‘../fonts/CharisSIL/CharisSILBI-webfont.ttf’) format(‘truetype’),
    url(‘../fonts/CharisSIL/CharisSILBI-webfont.svg#CharisSILBoldItalic’) format(‘svg’);
    font-weight: normal;
    font-style: normal;


    * Alot of errors came from media queries. e.g.:
    Expected LBRACE at line 1861, character 8.
    @media (min-width:711px) and (max-width:1024px) {

    * Expected RBRACE at line 1827, character 3.
    @page { margin: 0.5cm; }

    * The line numbering was far off

    * Also it would be nice if the logo header was clickable and leading to the homepage. Thanks for the service. I’m gonna check my

  10. Can you please explain the limit on floats rule? How is that bad?
    Many times I have an icon followed by some text. To get the text to line up with the icon/image then I float the image and adjust it with margin to the top and right.

    I don’t get the consistent headings across a site.
    Many times I create page class, article class and aside classes for my page structure and then I’ll have use the different headings in the different sections, for example if h1-h6 is used in my .article class and I want something of the same size in the .aside section a different color then I’ll do an .aside h6 { } to change the color or other attributes.



  11. @Justin:

    Floats: you can float as many HTML elements as you like, and CSS Lint won’t care. The problem comes when you’re repeating the same CSS code (float declarations) again and again. Use a class instead. What you described sounds like a media block object, so write the code for making a media block. Write it *once*, and reuse it.

    Headings: “.aside h6 { }” is location-specific styling. If you do it this way, your styles become less predictable (because they vary depending on location). You also have to keep declaring new exceptions when you want the same styling in a different location. This doesn’t scale well.

    Use a class instead. Let’s say you want this h6 to look the same as your standard h4. Simply add a .h4 class. When you write your main heading styles, just add a corresponding class. For example:

    h4, .h4 {
    /* level-4 heading styles go here */

  12. Hi, Nicole and everyone!

    I’m eagerly waiting from June 15th to grab your Velocity 2011 slides. I’ve looked at Slideshare but don’t find them. Could it be possible to have them?

    Thanks in advance and keep oocssing, great job!

Comments are closed.