Hacker News new | past | comments | ask | show | jobs | submit login
CSS Lint (csslint.net)
239 points by nephics on June 15, 2011 | hide | past | favorite | 72 comments

The About[1] page, which explains the linter's rules, should be more prominently linked I think.

I am very much an amateur at CSS. I know the basic rules (I hope), but I'm definitely not a designer or an expert. After running some CSS through the linter, though, and reading the About page, I have a few questions.

First: Why are IDs bad? The About page says:

>> Don't use IDs in selectors

IDs shouldn't be used in selectors because these rules are too tightly coupled with the HTML and have no possibility of reuse. It's much preferred to use classes in selectors and then apply a class to an element in the page.

I don't quite follow. Isn't the whole point of an ID that it is like a class, but unique? Why exactly would it be better to change all ids to classes with only one member? (I don't even see how that would be different, except for making it less obvious to me that they're unique.) Edit: the context about OOCSS which Jacobr mentions below helps explain this.

Second: Why is it so important that heading styles be declared in exactly one spot. Again, the About page:

>> Heading styles should only be defined once

Heading elements (h1-h6) should have exactly one rule on a site. CSS Lint warns if it finds more than one.

I ran into this because I had one ruleset for h1, h2, h3, etc. to make all the headings use the same font and color, but then I had distinct blocks for settings that I wanted to be different. (Example, I wanted the h1 to be larger and have a different bottom margin from h2 or h3. And so on.) I could easily duplicate things so that each set of rules was in exactly one block, but that would make the stylesheet less DRY.

(Edit - putting my cards on the table, here's the CSS I checked: http://ithaca.arpinum.org/css/screen.css. I definitely don't doubt it could be improved.)

[1] http://csslint.net/about.html

Don't pay attention to that tool. Nicole has her own and peculiar view on CSS and many rules in CSS Lint make very little sense.

There is nothing wrong with .foo.bar. There are problems with outdated versions of IE, should that stop you?

There is nothing wrong with ID selectors.

There is nothing wrong with having display:inline on the floated element. No harm done, fixes double margin bug in IE6 if you need that.

It is ok to have many rules for heading no matter that CSS Lint says.

It is ok to have width, padding and borders defined. I do that all the time and surprise surprise, result is just as I intended. I am not sure if CSS Lint knows anything about box-sizing rule.

Etc., etc.

Unit-less zeroes, no empty rules do make sense, but I guess decent CSS compressor would take care of those.

The purpose of these lint tools is to attempt to standardise your opinions as the correct way of doing things. Without a tool that 'checks for correctness' (against someone's opinions), they're perceived as just that: opinions.

It's a very clever way to convince others of your ideas. The same thing has happened with JS Lint. Suddenly many people agree 'this is the correct way to write javascript', you ask them why and they point at the tool as if the correctness is self evident.

Agreed -- almost all its complaints about the first css file I passed it were "don't use id selectors".

I suspect some of the complaints are valid, but simply saying "broken box model" doesn't explain why.

Ditto. Funnily enough you also get some rules that tell you to use id selectors:

    Overqualified Elements	Element (a#galleryLink) is overqualified, just use #galleryLink without element name.
    a#galleryLink {
This was given as a warning, but it's spot on too - https://developer.mozilla.org/en/Writing_Efficient_CSS for example.

I think it's actually saying a#foo is worse than #foo (assuming you're not reusing #foo in which case, conceptually, shouldn't it be a.foo?).

Indeed, I'd argue it ought to say that you EITHER ought to use a.foo or #foo depending on what you're doing in the page.

I'm not an efficiency nut, but it's quite possible #foo runs faster than .foo and this might be important to you, even if giving multiple things the same ID makes you feel dirty.

I agree. most of these "rules" are frivolous. simply removing the 3 @import lines in the example file would be a much bigger win than worrying about ids and "overqualified elements"

I'm curious what folks do who follow the no-qualified-headers rule. When they have things that act like headers but which need to be styled differently than the single header style used on the site, do they just use classed P's or DIV's? Confused.


>Isn't the whole point of an ID that it is like a class, but unique?

The argument against IDs is to encourage a mindset for making reusable rules. Obviously, in any project of even basic complexity, you're going to run into elements that only appear once per document. Having a class rule that's used only once is not only acceptable, but probably an inevitability.

In my projects, I use IDs purely for Javascript identification. I never use IDs to style things because 1) they complicate CSS specificity rules and 2) I get an urge to couple the element with JS, which creates this weird bind between JS and CSS that shouldn't exist.

The other end of the argument will suggest that it makes for better code readability: an element with an ID guarantees the author intended for this element to appear only once in this document.

There's the whole "IDs are faster than classes" argument; the renderer has to do a substring match instead of a full string match on classes, which you can imagine with today's processors is a relatively tiny hurdle given the scale of an average HTML document.

The whole thing is a trivial matter, but there exists a group of people who focus a good portion of their career on, specifically, CSS, and like any master of the craft, arguments at their end of the knowledge spectrum is going to boil down to things that seem like minor details to laymen. So don't worry about IDs vs. classes too much.

Speaking of specificity, maybe using !important should also give a warning.

Just submitted this as an issue on GitHub, clearly !important is a bad practice for application-native CSS.

Great points huckfinnaafb thanks for sharing.

Don't worry... CSS Lint is just anal. Your usage of those is fine in my book. I do the same stuff and I've been doing front-end development for something like 7 years now.

Fair enough and thanks for saying so. I suppose I just wondered what (if any) explanation there was for these particular preferences. That is, I understand that a linter (by definition) might be very picky and strict, but usually there's some basis for the rules. In the case of the two rules I asked about, I just don't see the rationale.

Nicole Sullivan, one of the creators of CSS Lint, is a proponent of what she calls Object-oriented CSS. It mean you define "objects" or "modules" that you reuse. The concept is not necessarily new, but she popularized it.

You could for instance define some shared "widget" styles, and then some custom additional styles for a search widget and other additional styles for a filter widget. That way you only have to define the shared styles once, resulting in less CSS (DRY), easier maintenance and more consistency. She helped reduce the CSS of many Facebook pages massively using this technique.

Read more at http://oocss.org

Also, just because you only have an element once at a page right now, you're not necessarily sure it will stay that way. Especially if the HTML code is in some shared template file that you use across your site.

And I recommend SCSS (http://sass-lang.com/ instead. It solves many problems you can come across when dealing with CSS and in much more elegant way.

E.g. rules reuse in SCSS can be done with @extend: http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#ex... That way instead of adding classes to your HTML you just group selectors in your CSS appropriately.

Seriously, if you do CSS and did not try SCSS do it now.

Yeah, the id thing is just bs. That's the point of id's, to be used for non-repeating tags in the html. While you could try to generalize and find all instances where id's shared similar properties, then extract those and apply them to classes, then add those classes to the elements, that just seems like a ridiculous approach to achieve reusability. In addition, if you move that direction, you start to deal with class bloat, which is no better than just adding inline styles (ie div class="red centered absolute fullwidth", etc)

Except that would be declaring styles, and not content, in the markup which would not be something Nicole Sullivan would approve of. It would rather be div class="post" and class="post featured" or something like that.

In practice you wouldn't actually create just a red class or a centered class... I just meant to demonstrate that as you get more and more granular in the shared attributes of a module you can start getting css bloat... ie: you may have a lot of uses of color:red + position:absolute + top:0, which is then reduced to class = module1, and another set of reused rules reduced to module2, etc... It depends on how complex your css is really, but it's something to consider as you start to apply the rules more and more and make your css completely DRY.

Of course, the absolute extreme of reusable classes would be if each class applied exactly one CSS rule. Then you could mix and match them in any possible way, at the cost of having 18 classes per element.

But no one would do that. You don't need every possible combination because you want some consistent styles throughout your site. In Nicole's examples, she's getting pretty sophisticated effects, and I don't see her applying more than 3 classes to any element. (http://oocss.org/module.html)

"the id thing is just bs."

By no means am I a CSS expert, but I'd hesitate to call someone's ideas "bs" if that person has the kind of experience Sullivan has.

I may not like all of Douglas Crockford's suggestions in JSLint, but you know what? He's way more experienced with JS than I am, and doing what JSLint says has saved me pain on more than one occasion.

Nicole Sullivan has nowhere near the experience in CSS as Douglas Crockford has with JavaScript. Compare their writings and their talks on their specialist subject matter. Also compare what their peer say about them. For Crockford the negatives are his opinions as to what constitutes good JavaScript, but not against his knowledge and experience.

Peer review is also an essential component. Crockford's contentious points are his opinions as to what constitutes JavaScript best practice, but his underlying knowledge and understanding is rock solid.

I've found Nicole's understanding and knowledge of CSS falls short of the standard necessary to advocate CSS best practice with tools such as this. So she's failing at working with the strengths of CSS.

Pick your role models carefully, and please, don't follow blindly.

Neither Crockford nor Sullivan is a role model for me, and I'm not following blindly. I'm merely observing that Sullivan successfully refactored the CSS on Facebook and got them onto a better development path. That's pretty hard.

I'm not going to blindly do whatever she says, but if someone wants to call her ideas "BS" and I don't know who that person is, I'm more likely to discard their opinion than hers. If that person is Eric Meyer, well OK then.

You say her "understanding and knowledge of CSS falls short." Can you point to facts she gets wrong (not just opinions you don't share)?

is there any good way to avoid using IDs as selectors?

i'm working on my first large web project in a while. i'm using Compass/SASS (looks like you are too, or at least blueprint) to try to make things easier but i am finding that the HTML/CSS part of this site is such an incredible time sink.

my approach has been coupling the HTML and CSS almost 1:1 except where there are obvious re-use cases (which i'm not yet great at identifying, two pages in). this is probably bad but is there really a better way? i'm finding everything needs its own div in order to be positioned correctly across browsers and so i end up with container divs, then inner divs for padding purposes, then divs for each element, etc. it's a mess.

and don't get me started on the complete impossibility of consistent selector naming scheme...

Regarding your first question: you can perfectly replace every id with a class. Writing object oriented is another thing. Personally I don't. Most CSS is very specifically written. It makes sense for real huge projects though.

There are many different ways to solve problems in CSS, and those problems include things such as how you organise your CSS as well as how you make a two column layout.

A lot of the time, it isn't hard and fast what the "best" way to do things is. What's important is that you realise everyone has reasons for doing things how they do, and that they are trying to solve particular problems with their approach. If you don't have the same problems, or solve them in different ways, you may disagree with their approach or even find it nonsensical.

Of course, this shouldn't be used as justification for remaining entrenched, you should always try to understand where people are coming from and see if you could learn something.

Curious. Running csslint.net's CSS through itself resulted in 65 warnings. I would expect them to use their own tool on their own code.

They possibly did - a warning is not an error.

The tool flags these issues for the [OO]CSS writer to attend to. If I say "look out walking on that floor it's wet" that doesn't mean you can't choose to walk on the floor nor even that I'm telling you not to.

The rules are too frivolous and personal-standards flavored, it's difficult to care enough to look for anything actually wrong amongst the ton of "I don't do it like this" warnings.

Using float for layout isn't a great idea, but sometimes you have to. CSS Lint simply checks to see if you've used float more than 10 times, and if so, displays a warning. Using this many floats usually means you need some sort of abstraction to achieve the layout.

Why is using floats bad, and what are the abstractions one would use in place of floats? Tables? Or grids?

I don't know either.

I've posted a bug report demanding a clarification of the documentation on that point.


Demanding justification for things a tool you got for free, is a bit ungrateful. Why not 'request' or 'ask', you might get a better answer. Demanding things from open source is a pointless venture.

The person you replied to might not be a native English speaker. Demand shares a common ancestry with the verb "to ask" in some languages. Take French's "demander" and you might see why someone could use "demand" in a way that sounds confrontational in English but quite normal in another language.

AFAIK all grid systems use float, maybe the suggestion is that you shouldn't be floating things constantly and instead use a grid system.

Wouldn't that constrain you to fixed-width layouts then? Or are there grid systems for fluid layouts these days?

Float has no say on the matter with regards to width. I use an extremely simple 14 line grid system that uses % widths, is nestable, and works in every browser I test it against.

Not surprisingly this "system" (this word really makes it sound more than it is) can be found on one of the CSS Lint creator's Github: https://github.com/stubbornella/oocss/blob/master/core/grid/...

While simple, it's definitely way more elegant than some of the grid systems I've seen built, such as the popular 960 fluid grid layout that ultimately generated nearly 800 lines of CSS for 5 columns.

It also goes hand in hand with the core principles of OOCSS, which essentially states to extend classes and use multiple classes per element.

Sorry, I should have clarified in stating fluid width layouts. I'm a much bigger fan of pages that specify the width as a percentage. Or that at least use max-width/min-width so I can expand the pages as needed. Every grid system I've encountered fixes the width at 960px or 980px. I've found floats are the best, but by no means, only way to achieve a fluid layout with a variable width.

Floats were originally intended to be used for floating images inside text blocks, not for layout purposes.

The usage of floats all over the place is no longer justified since all major browsers support now inline-blocks and CSS tables.

A sub-question, if you don't mind my piggy-backing: Don't most grids rely on floats anyhow?

    Heading (h1) should not be qualified.
Yes it should, especially if you are using HTML 5 and are using different heading sizes for different parts of your site... Otherwise an h1 in a header (tag) would look the same size as a h1 in an article (tag).

I could be mistaken, but I think the idea is you only have one h1 per page. If you use an h1 in different contexts on different pages, the rules for those pages should probably be in different stylesheets as well, obviating the need to qualify them.

In HTML 5 you can use the h1 element multiple times. For example, lets say you are writing an article

That is perfectly valid, now lets say you have an header that gets added before each article that contains some information such as author, time created/published

      Article Title
This is valid HTML 5.

In HTML5, not only is it valid, but doing otherwise would break the document outline.

I'm entering the CSS found on major websites. The following is a rough feel for how many errors and warnings csslint is detecting.

this page = 1 errors and 2 warnings

craigslist.css = 4 errors and 340 warnings

facebook's css files' = 0 errors and 140 warnings

google home page: 0 errors and 0 warnings

ebay = 0 errors and 64 warnings

Are these results meaningful? I don't know. Thoughts?

Don't forget the 65 warnings thrown... on CSS Lint's CSS code.

I'm not going to say it's useless, but it certainly isn't as good as a real CSS validator.

csslint css = 0 errors and 2 warnings.


Well, that was impressive. 82 warnings, and every single one was wrong. This is not a useful tool.

The biggest problem with CSS today is that the source code is the product. One possible solution to this problem is to use SASS (http://sass-lang.com), thereby separating the concerns of the quality, structure, reusability (etc) of code from the aspect of browser rendering efficiency.

Many of the aspects of CSS Nicole is trying to improve with OOCSS/CSSLint simply vanishes when you use SASS (though some still stand). Some of the points as they pertain to CSSLint: https://github.com/stubbornella/csslint

Take for instance the issue of reuseability. Nicole's solution to that is less CSS selector specificity, to not use IDs, and to sprinkle containers with several modular CSS-classes. By using SASS functions, mixins and extends you can achieve that without doing either of those things.

I much prefer using SASS to manage my source code and the related concerns, without resorting to these kinds of sacrifices.

I know some of the things that SASS gets you, but I'm curious: how DRY and light is your generated CSS?

Anecdotally, the designer where I work uses SASS, but in our last iteration of our web app, his compiled stylesheet was something like 10,000 lines.

It depends on how you use SASS. Used correctly, with @extend rather than @include for big swatches of styles that reoccur in multiple places, it will be DRY and light.

Your designer colleague probably didn't have a sufficient understanding of the difference between @extend and @include. It's not hard though, a few tests using the different methods and analyzing the results should be enough to understand when to use each.

It is utterly impossible to generate worse CSS with SASS than by just writing CSS directly, as SASS does not deprive you of any CSS feature. SASS provides you with a bigger and more capable toolbox, but won't stop you from using the wrong tool in any given situation.

I don't see any reference to a CSS standard, for example pylint follows PEP 0008. This looks like the experience of a developer.

I know it's just picking nit, but seeing as that's basically the entire point of CSS Lint... https://github.com/stubbornella/csslint/blob/master/lib/pars... The entire library is in a single ~4700 line file with ~80 line long functions... Ugh.

The included parselib is actually sourced/built from the following: https://github.com/nzakas/parser-lib/

As well, the functions and built lib are chock-full of comments, which any decent IDE should be able to fold away.

Note: I paid no mind to how integrated libs are made as dependents of CSS Lint project. Then again, I have a feeling javascript projects are only more recently warming up to the idea and being built around the idea of dependencies, cross-party builds, etc.

During their presentation at Velocity today, they made the github project public:


Linting (where you're going wrong) without explaining why (you're going wrong) is one of the most pointless exercises ever.

Maybe too much attention put on aesthetics, less on code (nice start though)

Owing to the lack of options, this is only useful for linting CSS written by the authors or anyone who happens to agree with their opinions on what constitutes good CSS.

Crockford may be an opinionated cantankerous old goat, but at least he gives you options to dial down some of the crazy he's baked into JSLint.

* He's also awesome, but anyone who's worked at Yahoo! or glanced at the JSLint Issues list or Pull Request queue can attest that he has strong opinions.

You can't remove all the craziness in JSLint. The warnings about using == instead of === and not having your var statements at the top of the function, for example.

width: x; padding: 0 produces "Broken box model: using width with padding." Same for height. Isn't it exactly the opposite of using padding?

"CSS lint found 0 errors and 0 warnings. How can you fix it? See the details below." Um, right. Whatever.

The rules that this tool follows appear to be based on the creator's own personal opinions. Personally, I'd advise against at least several of the rules.

Reading "JavaScript: The Good Parts" is an excellent crash course in writing decent JS but JSLint regularly ensures that you stay on the right track. Reading through CSSLint's guidelines, I agree with the bulk of it and am excited to have CSSLint keep my stylesheets on the right track. Hopefully an analogous TextMate "run csslint on save" bundle is right around the corner!

It seems like this is useful in generating critiques of CSS for web pages in development, but user-style CSS (the primary sort I work with) has a different set of priorities that lead to selectors that seem to be considered poor style and warned against accordingly. It did point out several valid points I hadn't noticed and should fix, though.

I like it, but it'd be really nice if it linked each rule to some kind of explanation on why is the rule right.

I've been using paddings and left and right margins on inline elements and this tool tells me I can't.

"Don't use IDs in selectors".


I need my CSS fast, Ferrari fast.

I don't need toddlers to be able to have a mental model of all my style rules.

I don't agree with this suggestion either, but I don't think IDs have significant speed advantage:

• browsers support duplicate IDs already (try `<p id=foo></p><p id=foo></p>` and you'll find that `#foo` styles both)

• both IDs and classes can be preprocessed and looked up using hash tables or similar

https://developer.mozilla.org/en/Writing_Efficient_CSS — suggests that Gecko optimizes class lookup as well

An obvious next feature is to allow submission of a URL, and it parses out the linked stylesheets and runs itself on those. i.e. lint my site

Hah, I was just sitting in the talk at Velocity where they announced and open-sourced this.

Eh, command line output is a bit weird. Still, trying to get it work in Emacs... :)

It's useless, too many stupid or plain WTF rules, like

1) "Don't use IDs in selectors"

2) Most "Overqualified Elements"

3) "Broken box model: using height with padding"

The "Don't use IDs in selectors" was really random.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact