CSS Lint is harmful
Tools like CSS Lint, and CSS Lint in particular, are mainly about checking your CSS for browser performance. Performance at the cost of everything else. Performance as the altar at which all the other benefits of CSS are sacrificed. Unless you work at Google, or Yahoo, and are styling a mammoth ultra-ambitious project inside a team of dozens, where each developer is an island, it is very unlikely you need to optimise the performance of your page to the extent this tool aims, or pay the penalties required by CSS Lint’s rules.
In short: don’t blindly follow the crap these tools tell you. Chances are very high you’ll do yourself more harm than good, ending up with harder to maintain, bloated code, with nary a change in how fast your site feels.
Here are the rules CSS Lint currently checks for:
- 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
Of those the following are bad:
Don’t use adjoining classes.
(Don’t use div.classone.classtwo { something }
)
If you’re having to worry about IE6 then this rule is good. Otherwise it’s bullshit. And frankly, it’s just plain bullshit anyway because every other browser can handle it and you can fix IE6 using an IE6 stylesheet and a line of jQuery.
Ability to chain classes is a feature, not a flaw - although times when its needed are generally rare. Chaining classes allows for smaller, more maintainable CSS. Otherwise you need to create a new selector to apply in any instance where you would otherwise want to apply both of the existing selectors. This duplicates code, meaning larger files sizes and longer download times, as well as complicates the maintenance of the stylesheet and HTML.
Ignore Lint, use multiple classes, and then fix IE6 in an IE6 stylesheet, using JS to dynamically patch redundant selector names onto the element. e.g.,
$(".classone.classtwo").addClass("ie6-classoneandtwo");
Don’t use too many floats
Arbitrary, and impossible to test for. All Lint is doing is counting how many times you declare “float” in a stylesheet. It doesn’t matter that you may only ever use one float on a given page. And given that, you should ignore this entirely. It’s not measuring anything real.
Don’t use too many web fonts
See “Don’t use too many floats”. Besides, this makes no distinction between loading different fonts, or simply different weights of the same font. Of course the more fonts you load the slower things get, but the warnings Lint flags do not relate to how many fonts are used or loaded on your page, just how many are declared in the stylesheet.
Don’t use too may font-size declarations
Utterly arbitrary. Use as many as you need to get whatever result you’re after. You’re the designer, you know what’s appropriate, and it has little to no impact on performance.
Don’t use IDs in selectors
Absolutely the most wrong advice I have ever heard in my life with regard to how to author CSS. This rule comes from the author’s absolute raging hard-on for “Object Oriented CSS” (hard-on is a bad term given Nicole is a woman, and “Object Oriented CSS” is a bad term given the likely confusion with actual OO coding). OO-CSS, used the right way, is great. But to suggest that you never use ID’s is simply throwing the baby out along with the dirty bath water. ID’s are extremely useful and you absolutely should use them. They are the fastest way a browser can select a given element. They are useful for in-page anchoring and if they’re already there in the markup then use them as style hooks. They are also, oddly enough, perfectly correct to use as long as they’re only ever one instance of that ID on any given page.
Arguments about “selector specificity” are at best a stretch to justify a bad rule. Author your CSS properly and you won’t fall into any specificity traps. I can count on my hand the number of times that’s been a problem for me in 6 years of coding CSS and HTML for a living on various different types and scales of website.
The only time this rule could be called accurate is if you are using ID’s to style a specific chunk of HTML with intent to allow its use anywhere on the site. e.g., if you’re using it to style a HTML gallery widget that a user can include on any page via their CMS. They may specify more than one on a page. But, that’s the one and only time it’s a concern.
Don’t qualify headings
i.e., don’t style any h2 differently to any other h2 using a selector that terminates in a h2
The idea is that this is the only way to ensure that a CMS user (or HTML hacker moving chunks around the page) can get a heading to look the way they expect. Following this logic it actively encourages CMS users and HTML-hackers to choose headings based on how they look, rather than if they’re semantically appropriate. This is utterly wrong behaviour to encourage. You are the one who’s job it is to make sure a heading looks right, wherever it is. And that requires qualifying headings.
Heading elements should have a consistent appearance across a site
and
Heading styles should only be defined once
Both of these are related to the above rule, supposedly to improve predictability. Ignore it, and this one. Reasons should be obvious given the above. It may be wise to ensure that what looks like a major heading be styled the same on all pages, but that doesn’t mean the heading levels should be the same. Obvious example is a H1 on the homepage should be the title of the website, necessitating that all other heading levels drop by one. That would mean heading on all other pages would be out of whack if you followed Lint’s advice.
General issues
CSS Lint generally goes with the idea that it’s better to specify a display class of some sort, and then apply this class to whatever HTML element you want styling. That’s utterly wrong. CSS is about de-coupling style from mark-up, not about defining a bunch of values to then sprinkle through your mark-up. Doing this is the same type of thinking that lead to HTML elements with style attributes embedded directly in them.
The take-away
Using tools like Lint is dangerous unless you know enough about CSS that you don’t need the tool anyway. Don’t blindly rely on tools like Lint, and don’t believe that just because Lint is right for specific use cases it’s right for yours.
And lastly: Performance is a browser level issue, it is not something for HTML/CSS authors to fix or work around. As long as we are authoring valid and sensible HTML and CSS, we should not need to resort to such ridiculous rules simply to enhance the speed at which a given page renders. Nor need we, these things are getting faster with every release. It’s the JS boys that need to worry most about optimising their code for performance. If you want to optimise your HTML/CSS - do it for best-practices, not for performance. “poor” performace will fix itself as new browsers come out, but shoddy hard-to-maintain and obscure code won’t.
Entry Information
- Posted:
- Sat, 9th Jul 2011 at 19:07 UTC
- Filed under:
- Tags:
Comments
skip to comment formIn many years of authoring CSS, I have never felt the need to to run my work through a tool like lint… and after reading this I'm glad.
Whilst there's always good and practice, there's rarely a categoric right or wrong way to do things. In fact there's different styles and flavours of blending HTML and CSS and often the approach amounts to nothing more than personal preference.
For example, I personally prefer NOT to litter my markup with classes, so often use IDs on root level elements and use selectors that are often two or three levels deep. I suspect Lint would throw a wobbly at that, but I don't think I'm wrong to do it that way.
It seems to me that Lint prescribes a very specific style of writing CSS. In claiming to "help you code better", it's actually just helping you code to a specific style, which is no better or worse than other styles.
Is this in any way related to not declaring a charset in the HEAD section of HTML documents?
FYI "alter" in the opening paragraph should probably be "altar".
Matt says: Nope, nothing to do with that, what’s your thinking? And cheers for the grammar heads-up, don’t know how I missed that.
Thank you!
I saw mention of CSS Lint a while back and felt bad about having a bad taste in my mouth after reading it, especially the id bit.
Another article I had read at the time mentioned she was heavy on 'object orientated CSS,' and since this article backs that up and expands on specifics, I feel just fine treating it as I do; interesting, but not something I'm going to follow.
Matt, thanks for writing this. I couldn't agree more. Ever since Lint emerged, I've felt funny about it - and haven't used it much. You've taken the time to actually comment of some of the advice that felt very wrong to me.
So - great post, and good job!
yet another post telling me to fix CSS issues with JS… ugh -_-
Yeah… I'm all with you. I have expressed the same opinions multiple time IRL and in twitter since the last burst of buzz related to CSSLint. Never had the time to write it down in the form of a blog post, unfortunately.
Most of CSS Lint recommended "optimizations" are for maintainability, absolutely not browser's performance. The typical cases - and you said it very well - are IDs selectors or multiple classes; CSS Lint's recommendations here just don't make any sense.
Daniel Glazman
W3C CSS Working Group, Co-chairman
I wish you hadn’t advocated using JavaScript to work around IE6’s CSS parser issues.
@seutje - In only one case, and only if you still need to support IE
Amen.
If I actually updated my blog I would have written something similar about a month ago. CSS Lint was written with good intentions, but ultimately relies too heavily on the author's own personal CSS methodology and not what is truly effective or efficient.
Writing efficient CSS is a process that often differs based on the size and type of site you're creating. To think that you can just arbitrarily throw away something as important as IDs at the alter of "efficiency" is a bit silly.
If you're still supporting IE6 or IE7 you are part of the problem. See here:
http://j.mp/deA6VA
… for an easy-to-implement blue screen of death for ancient browsers.
Matt says: I agree with the sentiment, but not the suggested action to fix it. Part of the idea of being a good web designer is to allow for graceful degradation - everyone should be able to access content. Banning anyone from seeing content is bad. Just use Conditional Comments in such a way that IE6 doesn’t get any CSS at all. No design to support, and yet the content is fully accessible. More about that technique here: http://forabeautifulweb.com/blog/about/universal_internet_explorer_6_css.
although the overall tone is pretty attacking and nonconstructive, I do agree with most of the points about csslint. It's really for folks who subscribe to an OOCSS pattern of development. If you don't use or like OOCSS, you'll find a ton of shortcomings in the application.
Lastly, performance is not something we should remove from our list of checks. The reason things like 1 css file, 1 js file, sprites, not using document.write and minimizing http requests have become "best practices" are for the simple fact that it's better for performance. To say they're completely separate things is a little inaccurate. If you build a site of application that performs terrible you don't say "well, that's the browser's fault"; you fix it so it performs better.
The basic idea of this article is not about 'how to work around IE6'
Very nice article, exactly the way how I think of it . I also taste some emotion in it .
About the IE6 issue.. I dislike the js solution too. But I think it is bad to put the focus on that.
This is what I use in my html to make sure I can have a difference between the IE versions
so IE6 css can be addressed like .ie6 #main-nav.
@beverloo pointed out that .button.right-angle works perfetly in IE6, it just does not add weight to it. So make sure it is the last selector.
Thanks for posting this and the breakdown of each 'issue'. I knew the "Don’t use IDs in selectors" one was BS. CSSLink is lacking a very heavy dose of disclaimers on their claims.
Hi everyone, thanks for your thoughts on this issue. I'd like to address the "fix IE6 with JS" issue that's popped up in the comments.
There is no clean fix for this. IE6 is broken, not CSS.
To fix this issue you must either pollute the mark-up with new class names - forcing all browsers to download that extra mark-up, and forcing you to maintain extra classes - or you use JS to add those new class names. Although I didn't add a conditional check in the article (for brevity) I would only execute that JS if IE6 was detected. Either by hiding the JS inside a Conditional Comment, or using agent sniffing. I prefer the former to the latter.
Any solution has collateral mess. But as it's IE6 that's broken, I prefer to have only IE6 deal with the collateral mess required to patch it.
@xfinx - you're right and wrong. IE6 can indeed deal with two chained selectors - but it's patchy as to whether it gets the rule right, and it will not chain any more than two. So there isn't a pure CSS solution for IE6's mis-handeling of chained selectors. Read more about the bug here: http://paulirish.com/2008/the-two-css-selector-bugs-in-ie6/
You clearly don't get it.
JSLint and OOCSS are intended for larger teams working on larger sites. If you ever want to scale up CSS, you will need to change the way your write CSS. I'm not going to explain the details, simply trust that I know what I'm talking about or don't based on who I am.
If you care about writing scalable CSS, go read everything Nicole has ever written an watch her videos. If you are only ever a one man show when it comes to CSS, you can happily stay ignorant forever.
Great post. I've never felt the need to run my code through anything other than the validity checker.
I'm not the sort of person who would normally be arguing with a post like this – god knows my personal abhorrence for the W3C validator made me persona-non-grata in a lot circles for a long time – but I really can't make heads or tails of the basis for your "considered harmful" conclusion – other to think think you either didn't see all the checkboxes and/or haven't read this: http://meyerweb.com/eric/comment/chech.html
So you're annoyed that someone has built an (optional) tool that recommends things you don't agree with – likely because you haven't been in the teams and scenarios that Nicole has, dealing with accumulated technical debt and studying its causes? Hrm.
The web *is* too slow. CSS *is* hard to maintain at scale and specificity *is* the culprit. Some devs *do* still have an IE burden, and adding JS to the page to fix it will only make things slower – JS fetches are synchronous unless marked async/defer and using the JS for this sort of fixup creates either a large FOUC or blocking rendering. Lose-lose. Now, supporting IE 6 isn't my preferred solution either, but encouraging the use of JS like that (vs, say, a custom re-writing CSS expression in a conditional comment) is just out-and-out bad practice.
This tool helps encourage folks to do things that keep themselves and their teams out of the gutter, either in terms of performance debt or structural debt (ID rules, etc.) Maybe you think web pages load too fast on average these days? Or maybe you think most webdevs are endowed with magical powers of browser insight – a finding not born out by looking at the waterfall graphs of most top 500 sites?
In any case, performance isn't just a browser-level issue. It's *also* an author issue. Good engineering is about building in your constraints, and that includes caring about your latency budget. That you don't seem to acknowledge that you have at least *some* agency in the situation should be worrying to your employers. Yes, those of us working on browsers should be – and are – working hard to improve the performance of the engines, but as a web developer, the thing that any browser vendor ships next week to improve performance isn't going to define your median and 90% latency buckets any time soon. Not even if that browser is Chrome. You have agency in the breech and not using it – or worse, using it to add unneeded JS that might be blocking download and rendering on your already-slowest clients – is making the web slow.
Oh, and those checkboxes at the bottom of the CSSLint page? They're there to let you turn off the stuff you don't agree with.
>Don’t use too many floats
Means you should perhaps use some kind of abstraction for this (e.g. grids + media block or something similar). The warning message should be a bit clearer nowadays.
>Don’t use too may font-size declarations
It's just a metric. If you got 900+ font-size declarations you are probably doing something very silly.
>Don’t use IDs in selectors
IDs don't provide any benefits. Matching is indeed very fast, but this is only relevant for the key selector (rightmost simple selector).
E.g. "#foo .bar" isn't any faster than ".foo .bar".
Typically there are only 3-6 id key selectors per page. There is absolutely nothing to gain there (not even one lousy msec). The potential performance improvement is a red herring.
>Don’t qualify headings
The current implementation isn't very useful. Ignore it.
–
Well, I for one really *love* CSS Lint. As a framework for static code analysis, that is. I don't intend to use any of its default rules.
I'm using a far stricter concept than OOCSS, which provides far more "attack surface" for static code analysis. Unlike OOCSS it's build around automatic QC and very mechanical decision making.
CSS Lint is f-ing awesome for this.
Well written and quite informative. I won't mind scanning through CSSLint but I feel CSS is more like your signature, the way your write code - pretty much how a programmer writes her program. There are best practices one can follow but strict yes/no to your code ain't that good.
I used it to detect duplications in my code.
I ignored the rest.
BTW ids are known to be the fastest selectors, so I really don't understand that rule.
People claiming I don't get it:
I clearly state that for large organisations, in big teams, on mamoth projects, Lint WILL be suitable. I then go on to state why, for everyone else (and they're the large majority) it isn't.
Use the right tools in the right scenarios. The problem with Lint and the way it's put forward is it encourages blind following of rules that are, for the majority of people, harmful. You MUST understand the caveats and intended audience to get any positive use out of it.
Thank you! I looked rather quickly at CSS Lint, and decided not to use it because, frankly, conforming to those particular best practices looked like an absolute pain in the ass.
That's not the noblest of reasons, I know, but still, I'm glad I turned out to be right.
A great post, I agree in vast amounts. Especially with the bit about IDs. Just like you sometimes "need" singletons while programming, you are often faced with singletons when designing a website. Some of the CSS Lint things are good ideas, however, but I don't think you need a tool like this to employ them. If you don't understand to use the things yourself, you probably won't need the things anyway. Object Oriented CSS is however a good thing to some extent, trying to avoid redundancy is not a bad idea, but use of common sense before all. If you have 120 different selectors that employ box shadow, and they are all different "objects" (with that I mean, you can't do anything about that fact, which would be a pretty shitty place to be), it makes the code quite unreadable if you put them all into a single selector. In such a case, I think you should use another language that already has object-oriented approach built-in, and then translates to CSS. Code readability above all, it costs much less to purchase more bandwidth than to waste countless developer hours on trying to figure what the heck is going on in the CSS code.
Thank you for writing this, because you've expressed my sentiment exactly, particularly the rules about headings and IDs.
Often, you really do need to have a set amount of CSS namespaces by an ID. Also, I'd argue that code with an ID is often easier for long term maintenance and collaboration with others, if your naming conventions don't suck.
The CSSLint thing most certainly pushes for the OOCSS philosophy, which I have never fully agreed with. If you want actually useful OO, use the @extend method in SASS and call it a day.
@Cesare
See reply #18. You won't see any kind of performance improvements in real world scenarios by using IDs over classes. There are simply too few id key selectors to make a difference.
@Jussi Kalliokoski
>Just like you sometimes "need" singletons while programming […]
You don't. Singletons mean global states, global states means it's hard to test.
More:
http://code.google.com/p/google-singleton-detector/wiki/WhySingletonsAreControversial
>[…] you are often faced with singletons when designing a website.
Not really. E.g. only one left column, only one right column, only one header, only one footer. I already made websites which had two of those. I won't gain anything by making restrictive assumptions.
Another example from the last discussion:
"#loginbox - there can be only one"
Is this really the right abstraction level? Do you really want some big non-reusable structure?
E.g. you can break it into several smaller pieces like a box, label & textfield/password pairs, a button, and things like that. Those bricks can be reused to build other boxes and forms. Consistency! Woo!
Alright, lets say you want that the login box looks kinda special. E.g. it should have a different background than all the other boxes. Just add another class.
If you then, at a later point, decide to reuse this kind of highlighting elsewhere, you actually can!
That's the basic idea: Create a library and use it. (Instead of creating a pile of one-offs, which were made up on the spot.)
Hi Matt,
As one of the creators of CSS Lint, I'm always excited when people take the time to write feedback and reviews, so thanks for adding to that. I'd like to point out a few inaccuracies in your statements, as I think this will help explain some of the design decisions made in CSS Lint.
First and foremost, the rules in CSS Lint are devised for two main purposes: performance and maintainability. The former is easy to understand, the latter is more difficult for people who've never worked on large web development teams. Nicole and I have both worked on and with large teams and many of these rules are derived from problems either she or I (or both!) have found while doing so. I will freely admit that we don't have enough documentation explaining the rationale behind the rules, and we are actively working to fix that. I don't believe, though, that these rules only make sense for large teams, as we've also used them with smaller projects and groups. Maintainability through good coding practices are a benefit to any project.
Second, CSS Lint is open source. Since our first release last month, we have had three more releases. We've eliminated rules that people found serious issues with, we've added rules that people have submitted, and we've fixed user-submitted bugs in rules that are in the tool right now. There are a lot of ways to contribute, and if you think there are ways that rules can be made better, we'd love to hear from you (it sounds like you have some thoughts over the web fonts and font sizes rules that could make them better). There's a mailing list at css-lint@googlegroups.com and you can file issues at http://github.com/stubbornella/csslint/issues.
Third, you listed all 17 rules that we currently have on CSS Lint and then said that you disagree with six of them. I take that to mean that you find the other 11 rules to be tolerable, if not useful. This is precisely why we provide the option to turn off rules. You've found some rules that you disagree with, as I'm sure others do as well, and hopefully some that you do agree with. Even if you use CSS Lint strictly to check your syntax, then we're happy because you're doing a sanity check before checking in or deploying your code.
Ultimately, we just want to provide a tool that is completely customizable to everyone's needs. We know that everyone has their own preferences for coding style, and we're not trying to change that. We do want people to benefit from our experience if they so choose and would never include any rule that doesn't have some measurable positive benefit, whether that be a performance improvement, reducing the likelihood of error, or anything else. So certainly, feel free to disagree with any rule, but saying any one (or all) are harmful is inaccurate.
Great post. I remember seeing CSS Lint for the first time, running some of my pages through it, and being frustrated with it for a lot of the same reasons you pointed out here. Glad to know I'm not alone.
Matt says: "I clearly state that for large organisations, in big teams, on mamoth projects, Lint WILL be suitable. "
That statement is incorrect. I've worked as a web developer on Yahoo Sports, Yahoo Finance and Yahoo News during my time at Yahoo, and nothing CSS Lint provides would have been useful, except to provoke a discussion with my peers about what makes good maintainable CSS.
CSS Lint is useless in both encouraging best practice from experienced web developers (because they clearly know better), and trying to educate engineers who think web development is trivial and that any engineer can do it just as well. Those engineers unfortunately clearly won't know any better and will follow CSS Lint's advice without scepticism because they clearly don't know any better.
Do not be swayed into thinking that because the two people behind CSS Lint worked for Yahoo that automatically translates in that they know about web development issues with CSS and maintenance.
Granted Zakas is the first to put his hand up to not being a web developer (just a JavaScript programmer).
Nicole, well, I've never come across any of her web development contributions, and I'm even struggling to name a Yahoo site she actually did some web development on. I've even asked around other fellow ex-Yahooers.
Sure, she was part of an "Exceptional Performance" team at Yahoo, a nice shiny ivory tower that caused more problems to web developers than solved. We web developers had to push back on that team multiple times over the years, and we largely ignored them as a source for constructive advice on how to build high quality websites. The problem with "Exceptional Performance" is that it's focused far too much at the performance aspects at the expense of other more important factors of high quality web development.
You've accurately picked up on the point about performance without a consistently strong regard for the more important factors of web development.
My constant worry is that it gives the strong overriding (and misguided) impression that it's performance uber-alles. But then, what else can you reasonably expect from a member of an "Exceptional Performance" team?
Glad to read I'm not the only one with objections, specifically about the use of id's.. phew..
>nothing CSS Lint provides would have been useful
If all tests are disabled, you'll get at least a syntax checker, which can be easily integrated into build/test scripts. That's useful.
You can also use it as a framework for static code analysis. Just add your own rules and you're ready to go. This is amazingly useful.
Blindly discarding it, because you don't agree with its default rules, is pretty foolish. It's a very powerful and robust framework which offers just the right amount of flexibility. There also aren't any alternatives available (as far as I know).
Sure, you can roll your own, but that would be a waste of time and money.
>CSS Lint is useless […]
You should really differentiate between the framework and its default tests. You don't need to use those default tests and you don't need to agree with all (or even *any*) of them.
>[Nicole's contributions]
Again, you don't have to agree with her solution to those problems. It's fine to disagree, really.
However, you shouldn't ignore her observations and findings. She is absolutely correct there. There are indeed very popular patterns which lead to degeneration of code quality over time.
You can see those patterns (and the train-wrecks they left behind) in the CSS of almost every website, which stayed alive for a year or two (or even much longer). I've seen those problems on *every* website I maintained. It's a very real problem and it does indeed happen for those reasons she mentioned in her talks.
If you create guidelines and conventions which tackle those weaknesses, you'll end up with very nice CSS which is a lot easier to maintain, because it stays virtually cruft-free till the end of time.
That's the takeaway.
>performance uber-alles
It's actually higher productivity and lower maintenance costs über alles. Better performance is just a side-effect from keeping the CSS cruft-free and thus very compact.
Performance is just often cited for marketing reasons. Just look at the things the people said here about IDs in selectors. Their blind trust in potential performance gains makes them ignore all facts.
@Jos: I have to disagree on your statement about singletons. Quite often, it makes no sense not to use a singleton while programming. If you would rather use multiple instances of printf in C++ or in the case of web development, multiple instances of jQuery, YUI or whatever it is you're using, then be my guest, but I don't want to be the one fixing your code. Being object oriented, nice, but don't force something object-oriented just for the sake of being OO.
You're right, it often makes more sense to make things OO, but all I'm saying is that sometimes it simply doesn't. Sure, loginbox is something that's safer to make a class. But people aren't stupid. They know that if there's a "fork me on GitHub" button in the corner, it's not like they're going to have multiple instances of that. Sure, it might sometimes be a good idea and make that a class called upperRightCorner.
However, the thing I like about CSS Lint is that just like JS Lint, it hurts their feelings and makes them think for themselves. However, if someone lacks the basic knowledge required, I fear they're going to accept these things as the absolute truths, which they most certainly aren't, they even aren't all the best practices, they're just opinions, just like JS Lint.
> "The problem with Lint and the way it's put forward is it encourages blind following of rules that are, for the majority of people, harmful."
I'm going to have to disagree with that. Some of the most educational experiences I've had programming was when I discovered JSLint and started running all my code through it. I didn't just blindly "fix" the suggestions and move on. I investigated why that was a good/bad idea and made a determination on whether to ignore that rule or not. Through that process, I learned a lot about how the language actually works and how JS programs are interpreted.
Lint tools like JSLint and CSSLint are not meant to be blindly followed. If that's what a person is doing, then they are using them incorrectly. That's why there is documentation on all the options in JSLint, and why Nicolas said they were working on improving the documentation with CSSLint, so people can pick and choose what works best for them. Like Alex said, that's what all those little checkboxes are for.
And I'm not even sure where to begin with Isofarro's comment. The fact that he/she discredits NCZ as "just a JavaScript programmer" and not a web developer is laughable. And if you are serious about web development and are not familiar with Nicole's work or presentations, you have some learning to do.
> If all tests are disabled, you'll get at least a syntax checker
http://jigsaw.w3.org/css-validator/ already does that, and it's already available in both Continuous integration scripts and browser extensions.
> You can also use it as a framework for static code analysis.
> Just add your own rules and you're ready to go.
> This is amazingly useful.
CSS Lint is written on top of a SAX processor. This is 2011, and someone thinks SAX is useful for processing text? Especially for a language where best practice / useful rules are not a direct left-to-right, no backward references patterns.
The architecture has been the root cause of a number of raised issues: counting the number of float properties without taking note of their value, or their affect within the set of CSS rules, looking for padding and width in the same style rule, without taking into account the values, or whether two separate selectors provide one property each.
The architecture is so flawed that it would be counter productive to keep using it and coming up with a more useful set of rules. You'd have to start from scratch on a structured data approach, like an Abstract Syntax Tree, or something document-object-like.
CSS Lint in it's current form is not a sustainable long-term platform for efforts to improve the quality of authored CSS. As you point out, the best that can be achieved is already achievable with the W3C CSS validator, and since that's just an HTTP request away its quite straightforward to make that part of a build or continuous integration system.
cf: http://thecodetrain.co.uk/2009/02/running-the-w3c-css-validator-locally-from-the-command-line/
> However, you shouldn't ignore her observations and findings.
That's your incorrect assumption. I've watched her talks, read her material, talked to my peers, identified what works, identified what doesn't, reflected and drawn my own conclusions.
> It's actually higher productivity and lower maintenance costs über alles.
No, that's typical engineer prattle designed to isolate engineers from concerns such as accessibility, usability, internationalisation. Code quality is just one factor alongside those factors. And performance, that should only be taken into account when all these other factors are sorted properly.
> I've seen those problems on *every* website I maintained.
Have you tried hiring better web developers?
> The fact that he/she discredits NCZ as "just a JavaScript programmer" and not a web developer is laughable.
That's what Zakas said of himself on an internal Yahoo mailing list (devel-frontend of all places). I'm just quoting him, but agree that it's a fair statement of his capabilities.
@Jussi
>If you would rather use multiple instances of printf in C++
printf is a static function, not a singleton. Big difference.
>multiple instances of jQuery
The jQuery library provides a stateless global "jQuery" object. There is no other way to do it (with today's run-of-the-mill JavaScript, that is). With common.js modules/require you can give it any name you want though, which also means that you can use different versions in parallel if you really want to do that.
Including a JS library (or a CSS file or whatever) just once also isn't a singleton.
A singleton is an object of which at most one instance can exist.
A static class which only acts as namespace for a bunch of static functions/methods (like Java's Math class) also isn't a singleton. You can't instantiate it. Not even once.
I also liked the singleton pattern in the past, because it's so simple, but it does introduce a global state and that does indeed make it very hard to test, because there can (=non-deterministic!) be side-effects whenever you do anything with it.
So, for example it may cause test A to fail if it was done after B or it makes test C succeed, because test B happens to be executed beforehand. That's really f-ing nasty.
I suggest to google around a bit if you want to know more. There are many articles about this topic available.
>They know that if there's a "fork me on GitHub" button in
>the corner, it's not like they're going to have multiple
>instances of that.
Let me put it this way: What do you gain by "ensuring" on the CSS side that some kind of structure can only occur once?
And the other side of the coin: What are the drawbacks?
The answers to those questions are:
A) You don't gain anything whatsoever. It's not even 1msec faster. It doesn't prevent you from copy/pasting the same markup twice into one page and it also doesn't make identifying that issue easier. The course of action is exactly the same either way. Site looks wrong -> oh, it's the markup -> fix it.
B) You've added a 3rd digit to the specificity of selectors. This extra digit needs to be carried over to anything that should be at least as specific or more specific. It also means that these rules absolutely cannot be reused. No matter what.
So, given that there are no upsides and only downsides, why would you want to do this?
All of your technical decisions should be backed up by technical reasons. This is science, not religion.
@Derek
+1
@Isofarro
>http://jigsaw.w3.org/css-validator/ already does [syntax checking]
Yes, it does, but it also does validation. It will complain about vendor prefixes and things like star/underscore hacks.
(This can be addressed with a fairly simple filter though.)
>CSS Lint is written on top of a SAX processor.
It's a SAX-style sequential event-emitting parser, yes. Works for me, but yea, it does make some things a little bit annoying. Not a deal-breaker from my point of view though.
>The architecture is so flawed that it would be counter
>productive to keep using it and coming up with a more
>useful set of rules.
Feel free to create your own framework for this. I'll check it out if you make it open source.
>That's your incorrect assumption. I've watched her talks,
>read her material, talked to my peers, identified what
>works, identified what doesn't, reflected and drawn my
>own conclusions.
My assumption was based on your overly aggressive hate-filled rant, but I'm glad that you learned something.
>Have you tried hiring better web developers?
Since >99% of the websites out there have these kind of problems, it looks kinda difficult to find people who are better.
Well, "better" isn't really the best way to put it. Some education can fix this problem. Needless to say that this is easier to do if you have tools which enforce a specific style.
Agreed. I don't know how Nicole has developed this reputation as a CSS expert, but after reading her blog and watching her lectures and reading her code, I think her skills could not be more overrated.
> Since >99% of the websites out there have these kind of problems, it looks kinda difficult to find people who are better.
You probably shouldn't be basing your hiring criteria on where they've worked / sites they worked on, but on their individual skill and ability. Keep in mind that a website can be built from anything from one person, to a team of people, to a number of teams of people, handover from one group to another, ongoing decline because of maintenance by another team; so judging / prejudging an applicant's skills based on just a website isn't fair, and most likely exclude a rather large number of web developers who clearly know how to do the right thing, but the environment itself isn't conducive to demonstrating it. You seem to think you have the solution to the environment problem, and just need a careful eye on the potential candidates.
The talent is very much out there. Yahoo built a world class team of 40-50 web developers in London (plus Munich). Only a handful were known by the web development community, the rest were virtually unknown, but they were certainly not lacking in skill, talent and experience.
Who is still pandering to IE6 users? They are the same people still using AOL email addresses.
Hey Matt,
I’d like to explain some of the CSS Lint suggestions you had issues with from a design (not performance) perspective, as they may make more sense that way:
* too many floats probably means you don’t have a grid. You may repeating the same code (not DRY), or even worse doing things slightly different each time (bad design)
* too many font-size/font-family declarations = potential for the ransom note effect. Good design works best with a limited palette — that’s part of the reason you’d make a style guide. Having lots of these declarations suggests a potential lack of design consistency
* consistent heading styles, qualifying headings etc. Headings should work when your content is unstyled. I’m a little confused by your argument, as this _would_ be choosing them on their semantic appropriateness _and_ how they look (user agent styles). Again this is might hint at the lack of a style guide.
Also, you write “Obvious example is a H1 on the homepage should be the title of the website, necessitating that all other heading levels drop by one”. This is not true — there’s nothing in HTML 4.01, XHTML 1.0 or HTML5 restricting you from h1 for branding _and_ h1 for page title. Check out http://html5doctor.com/document-outlines/ for more info.
In XHTML 1 one place you would want to qualify headings is for a subhead. In HTML5 you’d just use the heading levels of the appropriate weight with an hgroup wrapper. The HTML5 spec explicitly states “authors are encouraged to … use elements of the appropriate rank for the section’s nesting level” http://developers.whatwg.org/sections.html#headings-and-sections
Finally, this post is pretty link-baity :/ Rather than ranting, why don’t you try redoing your site’s styles based on OOCSS and CSS Lint? This would give you solid data to draw comparisons from (which would make for a far more informative post), and trying new stuff might give you some insight in to why CSS Lint is the way it is.
@Oli,
Thanks for taking the time to explain these issues. I am, however, well aware of them, and have tried OO-CSS before - I wouldn't be writing a post like this if I hadn't. I still find it more of a hindrance than a help. I disagree that there's any help to be found in checking for "too many floats/font-sizes" for example. A dumb checker has no idea what I'm trying to do, and the way Lint checks this doesn't even work for a page but for the entire style sheet. It's useless.
Heading should work with content un-styled, correct. But part of CSS Lint is that you only style them once - expressly for predictability so users can know what heading style to expect from a given heading level. That is chronically bad, because it leads to people choosing the heading level that looks right and not the one that's semantically appropriate. Suddenly what should be a h4 is a h2 because of the way a h2 looks. That's wrong, really wrong, bad for accessibility wrong. As for h1 - it's the most important heading on a page. There should be one, and only one. That's the page title. The spec may not forbid the whole page being made of nothing but h1 elements, but that doesn't mean it's a good idea. There's a difference between valid and best practice.
The hgroup wrapper is, frankly, redundant for most of the code I write. I may change my mind on this as user agents get better at dealing with them, or the semantic arguments become stronger, but at the moment I almost never want to group headings - to me if you're grouping headings it's very likely because you're mis-using headings.
“A dumb checker has no idea what I'm trying to do … It's useless”
So I take it you don’t like tools like these in general?
“Suddenly what should be a h4 is a h2 because of the way a h2 looks”
Umm, can you give an example of this? I can’t think of an instance where you’d want an h4 to look like an h2, with the caveat of subheads which I already addressed.
“The spec may not forbid the whole page being made of nothing but h1 elements”
lol
“I may change my mind on this as user agents get better at dealing with [hgroup]”
Out of curiosity, what change in behaviour are you expecting from supporting user agents?
@jos: You're absolutely right, but there are two pros in using IDs.
1) URI reference
2) The lowest level fallback scheme and also a slightly faster speed of ID selectors, when using JS as well. Meaning, if you've ever written a JS framework, you know how much code you have to write to get stuff like getting by class name working in IE8 or Safari, not to mention IE6. If you use getElementById, you need no framework, enhancing your load speed quite a lot. Not to mention that the getElementById works much faster than any of the fallbacks for getElementsByClassName. When we get rid of the current Safari and IE8, only the URL reference argument stands. However, according to Microsoft's promises, that's over half a decade from now.
As for the singleton pattern, use it where it fits. Like you said, it's a science, not a religion. Magic isn't necessarily bad if it's used for a good cause, so let's not burn people at stakes just because they can do magic. Same applies to programming patterns, there's no pattern that always fits and there are hardly any patterns that never fit. Of course it might seem good advice for the not-so-adept to avoid the less general patterns, until they understand what they are suited for.
But this is headed to a CS philosophical argument I can't possibly win, so I withdraw. Good article, especially for raising such good discussion.
@Nicholas C. Zakas - you are living in Yahoo's inept little microcosm. Come back to the real world. The rules included in this tool are just opinions. It doesn't matter how many big teams you've worked on - opinions are still subjective.
Sorry but your tool is garbage and wrong.
I think this would have been a great post if the tone had been different.
Imho, the "problem" with this tool is its lack of "explanation" concerning each rule or some disclaimer that would help people who do not know better to make informed choices (I believe Nicole and Nicholas are working on this already).
As a side note, I think it's fine to use IDs when they are meant to be unique (i.e. structural markup for the site's layout). Let's keep in mind that this helps maintenance as authors can edit rules without worrying of styling some other element(s) elsewhere.
One rule I'd like to see in CSSLint is about z-index, I think it should flag "high" values (i.e. anything greater than two digits).
Well, CSS very important for me. It help me alot of. In future, CSS can barter flash. Thaks for your post.
Wow. This article was very eye opening. I find it unfortunate that so many people are so utterly offended by CSSLint. Let's face it, any "Lint" is going to hurt your feelings. But you need not take it personally. First I want to say that I have watched many of Nicole Sullivan's talks and read many of her articles regarding OO-CSS. Object Oriented CSS offers a new way of thinking about how we design the code for our pages and encourages developers to create more concise and reusable code.
"Nicole and I have both worked on and with large teams and many of these rules are derived from problems either she or I (or both!) have found while doing so." And I am thankful that they have shared what they have learned from these experiences. You can't just arbitrarily take your CSS, dump it in CSSLint and not expect a ton of errors to be spit out. OO-CSS requires a more granular break down of a site's design and the ability to recognize those repeating objects.
Statements such as this, make me wonder how much time was invested in understanding the "why" behind CSS Lints rules.
"Don’t use too may font-size declarations. Utterly arbitrary. Use as many as you need to get whatever result you’re after. You’re the designer, you know what’s appropriate, and it has little to no impact on performance."
This is from the "About" portion of the CSSLint site.
"Don't use too may font-size declarations. A site is typically made up of a finite number of font treatments, including font size. If you have 10 or more font sizes specified, you probably want to refactor into a standard set of font size classes that can be used in markup."
The idea behind this, is that if you are constantly declaring font sizes (as with many of CSSLint's rules) maybe you need to reexamine your CSS and condense some of your style declarations. If you have 10 instances of font-size : 10px, maybe that is cause for a class that defines a style object.
Myself and my team completely agree with the ID selector rule. We uses IDs for JS hooks. Which means if I want to style the element, I use a class. "They are useful for in-page anchoring and if they’re already there in the markup then use them as style hooks." This is where it seems the thinking is short sighted. Often the style of an element may change but not necessary it's functionality. By reserving the ID selector for JS functionality only, I keep a clean separation between the page's form versus it's function.
Reading this article reminded me of a quote from a video from a talk at Yahoo by Douglas Crockford: "yeah, I take the scissors and I run like this, and I haven't gotten hurt!”
One of the things I keep getting confused about by feedback on this issue is how people are talking about "feelings". Software isn't going to hurt my feelings - if it does then I suggest you're in the wrong industry.
The fact of the matter is that CSS Lint's rules are activly harmful and oppose the purpose of the technology though mis-use of that technology. For example: "you probably want to refactor into a standard set of font size classes that can be used in markup" is a completely incorrect use of CSS. If ever you're adding classes to markup simply to control a single display feature (be that font size, float, or whatever) then you are abusing the point of CSS. There is no difference between adding a class for font size and using inline styles. They're both wrong in the same way. CSS is about de-coupling styling from the mark-up. Classes should be named to describe content or context. CSS is then applied to the context or the content - not directly to mark-up. CSS is about abstraction from the mark-up.
@Matt
>For example: "you probably want to refactor into a
>standard set of font size classes that can be used in markup"
>is a completely incorrect use of CSS.
It conforms with the specs. Just like using IDs. Technically, both things are "correct".
But is it a good thing? You decide.
If there are over 900 font-size declarations (Facebook used to be like that if I remember correctly), you probably have some architectural problem.
>If ever you're adding classes to markup simply to control
>a single display feature (be that font size, float, or
>whatever) then you are abusing the point of CSS.
Never forget the reason behind separation: You should keep content and presentation separated, because it makes changes easier (or possible).
However, the reverse is also true: If the markup you're talking about resides in a few templates and therefore it's very easy/quick to change, there is no reason to treat it as something holy, which cannot be modified ever.
There is nothing wrong with following "golden rules" as long as you keep their raison d'être in mind. Only then you'll be able to tell when it's fine to break them.
Basically, keep your content clean and do whatever you want with your (manageable) pile of templates.
(To be honest, this is also a oversimplification. If you use some sort of markup which 100% accurately describes your content [e.g. your own XML schema], it's in a transformable state, which means you can output it in any flavor you can imagine. This includes HTML with presentational garbage. You can adjust the transformation whenever you want.)
Yeah, I took one look at CSSLint a while back and said, "um….no…" for some of the same reasons. I can see how it may be useful to check for duplication errors. But I tend to be mindful of what I'm working on, so that's not usually an issue for me.
It doesn't seem especially useful or helpful. It wants to disallow things I don't feel to be an issue or that I think are perfectly valid to use (Floats?? IDs?? Really??). Didn't care to waste the time. I kinda laughed when I first saw it.
Well. IDs are bad. Why? Well, you don't get any performance by using them. Right, they can be used only once… but browsers are optimized to deal with invalid code. And duplicate IDs still happen. Also, you can link to using #header which is pretty weird, and I don't think it's accessibility technique. IDs are supposed to make unique links, for example you can make Why IDs are bad? and link to them using #why-ids-are-bad at end of link. Also, in CSS IDs have bigger specificity than classes, which might be sometimes annoying.
The adjoining classes? Any reason to use them. Heck, I don't even care about IE6. If you're using more than one class on element, you're doing something wrong. You should always try to use semantic elements before using classes. Classes are even less semantic than element. It annoys me to see stuff like or . You could easily skip menu-position, by referencing to higher object, whatever it is of HTML5 or just plain old by using things like .nav li{}.
Too many web fonts? Well, font files are pretty big and take considerable part of bandwidth. You shouldn't expect that everybody will have very fast connections.
I have been writing css at least since 2001 (probably before that). I always used ID's without thinking about it. Last year I read about how classes should be used over IDs in most cases, so I tried to switch. Basically you would think it doesn't really matter, but I found one thing that becomes more difficult once you use classes over ids:
Specificity. In the past I hardly ever had problems getting an element styled. I never had to use !important and in the odd situation where specificity was an issue, I simply added an extra level to my css selector. But with classes, this is not so simple. I am constantly reminded of specificity and need to rewrite my selectors accordingly. Maintainability has become an absolute horror!
performance is good, people really do care about it. i.e. when I first started my images weren't optimized, and were taking a while to load. About 500kb or so worth of images. After optimizing I got that down to something like 40kb, and my conversions doubled. But some people do get ridiclious about it, i.e. cutting corners left and right just to get the css file from 50kb to 40kb
I'm a little late to join the conversation here, but thank you Matt. You read my mind. I used csslint a couple of times, and there's just no freaking need for me to code based on someone else's guidelines. Some things are helpful, but some others are truly utterly bullshit.
I'm still a proud user of the the W3C CSS Validation Service. If my code validates there, then I'm good to go, obviously apart from testing for older browsers etc etc.
Thanks for the post again.
I am still trying to decide the rights and wrongs about Lint, but i do like that it checks for empty rules, duplicate rules, zero do not need units, as CSS files grow in number and size, it is easy to lose track. And the rule helps you achieve some sanity.
CSS lint can still be useful.
ShiftEdit automatically points out CSS lint errors and allows you to disable the rules that you don't agree with.
http://shiftedit.net
Disclosure: I'm the author of ShiftEdit.
IDs are bad.
Pages on the web sites and web applications that are created dynamically by for example ASP.NET contain HTML elements whose IDs are created by the ASP.NET and therefore not known to the developer. IDs will also be different depending on where and how you use the ASP.NET web controls (groups of HTML code and logic)
Serge: Cart before the horse there. Your ASP is being bad. No server script should spit out unknown mark-up.
Serge: ID has it's place, and so do classes. You need both if you want to get any sort of interactivity out of your site with javascript…just need to know when to use them.
xun yes CSS can get complicated but you can make your life a whole lot easier by keeping everything organized. Too many developers juts write css code without any actual structure. If you have a separate area just for the header…its easy to change things, without having to sort through the entire css file looking for that .header-image class
@Thomas Atlott
Sorry. Who are you again? Ohh, just some arrogant idiot with a bad case of illusory superiority. You and Nicole Sullivan are equally clueless hipsters with absolutely no coding chops whatsoever.
Good to read an educated opinion about "Never use IDs, always use classes". Also good to see that it fits with my own thoughts about it thanks!
People needs to move out of the dark ages, its the people who Complain about IE6 that are probably still using floppy disk drives and complaining that computers no longer support them. Give me a break and move on!
I've only just discovered CSS Lint and have installed the command line version on my computer; like most things, it deserves to be taken with a pinch of salt.
It seems to be useful for situations such as the one I just found myself in: one of my stylesheets wasn't behaving as expected, and I couldn't see what was wrong with it. I'd adapted it from another CSS file, and really couldn't see any difference.
CSS Lint very quickly pointed out what it was: a mere missing semi-colon.
If I run it from the command line like so:
$ csslint –rules=errors style.css
it only notifies me if there are any critical errors. If my website then works in IE, Firefox, Chrome, Opera and Safari, then as far as I'm concerned it's OK.
I like csslint for finding lost brackets and hash tags on colour codes. It helps me to narrow down issues more quickly.
So I use it for suggestions but ultimately I know what is best. On some sites classes make more sense when I want to use the same style over and over again. This helps keep my sites feeling consistent.
Recently I have been developing a theme under wordpress and I found many default ID's as selectors but in this situation it made a lot of sense. The ID's are already well described in my skeleton theme and while building a child theme I'd rather drag in as few content php pages as possible to make things easier to maintain later on when the skeleton template improves with changes.
While designing from scratch where I have full control from start to finish it is more fun to write fully optimized css and the lint tool does a good job at helping me achieve that. I wouldn't throw this tool to the wind and Nicole is a world renowned developer that many of us can learn from. In most situations there is no reason not to write optimized css. It is always easier to write fairly optimized in the beginning than trying to fix optimization issues later on with a big file. Sure most of us aren't dealing with the same amount of page requests like yahoo or google where Nicole has made her mark in the world but you have to assume other designers will be looking at your styles and maybe even copying pieces of it for their own. In this way we all teach each other new things so I think we don't want to pass off another messy kitchen sink to someone who may not be at the same level. Should we all be writing to set an example? Maybe not on every project but it sure is more rewarding when possible.
Insightful article and I really enjoyed that someone has taken the time to look at the most common errors more critically.
I came across this post looking for tools for minifying cleaning up CSS - not a bad post, but I do think you are looking at this from the wrong angle.
CSSlint has many great features and I absolutely agree with many of your points, for clarification ID's are ideal for elements which are never expected to repeat - the hardest part is they are painfully overused by many and I personally feel they are best suited for a core structures like header and footer containers.
Anyways, if CSSlint were to support inline operands like jslint, it would be great as a "preprocessor" prior to minifying. Sadly CSSlint doesn't have those features and with the CSS trickery I'm working on - CSSlint would absolutely scream at me.
So, that said - I took a look through the source of CSSlint and it's got some great internal features and checks. It's very promising, but not for me until it gets some more flexibility for build scripts. Also, their documentation is very lacking - the structure of it allows for easy implementation of custom rules - it's quite amazing!