I recently used this selector as an example in a blog post:
.article #comments ul > li > a.button {
/* Crazy town */
}
There was a few comments to the effect that this seemed perfectly reasonable. I think if we step through it backwards the craziness comes out more clearly.
- It’s an element with a class of
button
. - But it has to be an anchor link, otherwise it won’t match.
- And it has to be a direct descendant of a list item. That list item better not have a paragraph tag inside of it or this won’t match.
- That list item has to be a direct descendant of an unordered list. It better not be an ordered list or this won’t match.
- That unordered list needs to be within an element that has an ID of
comments
. And remember this only applies if that is within an element that has a class ofarticle
or it won’t match.
So, do you have elements that are of a class of button that are direct descendants of list items that are direct descendants of unordered lists that are children of #comments that are children of .article, but that aren’t anchor links so they need to be styled differently? Crazy town.
Chances are, the selector should be:
.button {
/* Happy town */
}
If you need to change up the button styling later, you can write selectors that are only gently more specific than that to override things.
article .button {
/* Buttons within articles are slightly different */
}
Or add an additional class to the button to be more specific about it.
<input type="submit" class="button big-button">
<!-- I have mostly the styles of buttons but a few overrides to make me bigger -->
Very related: Shoot to kill; CSS selector intent by Harry Roberts.
Harry Roberts (@csswizardry) posted a great article on this yesterday: http://csswizardry.com/2012/07/shoot-to-kill-css-selector-intent/
Totally. That’s why I linked it up at the end =)
Doh! Shoulda read properly huh? :P
Bette specify your classes not the selector:
a href=”” class=” button button_big icon_arrow-right ”
and then do the css like:
.button { background:blue; height:30px }
.button_big { height:60px }
.icon_arrow-right { background-image:url(icon_arrow-right.png); background-position: center left }
then you can combite like class=”button icon_arrow-right” and every kind of variations
This is a technique we use at my work, granular css. This really helps when we pass projects off to web producers who know enough CSS to be dangerous.
This is definitely the way to go if you have expert content creators (i.e., people who know css and html and are trained in your system), but in many organizations, amateurs will be creating content, and you can’t rely on them to use *any* classes, let alone multiple classes.
I think this is why selectors end up getting ridiculous sometimes.
I understand selector intent but I also feel as though there’s some mixed messages in the community.
On one hand people are saying you should specify elements as closely as possible for efficiency – solid argument.
On the other hand people are saying you should utilize semantic markup and not ‘over-class’ or ‘over-id’ for the sake of reusable code – another solid argument.
I read articles like @csswizardry’s post and I wonder if there shouldn’t be a caveat about finding a happy medium.
Semantic markup has almost nothing to do with classnames though. I think semantic markup, and using granular classes can live together.
Semantic markup to me means using the right elements in the right places, and not including extra elements. It shouldn’t have anything to do with how many or how you use classnames.
Using more classnames, and fewer deep selectors actually increases maintainability and flexibility in my experience. Yo u can far more easily reuse `.button` where as `.foo li a` is requires a very specific HTML subsection to be re-used. Longer selectors also more tightly couple your CSS and HTML together, which eventually will burn you.
+1
Absolutely. These concepts don’t need to be at odds.
Chris, Mark – You are missing the point of Fluidbyte’s post. He is referring to “classitis” which is something the experts have been preaching against for years.
From the well-known book CSS Mastery:
“Due to the flexibility of classes, they can be very powerful. At the same time, they can be overused and even abused. Novice CSS authors often add classes to everything in an attempt to gain fine-grained control over their styles.”
A quick google search on “classitis” and up comes a link on how to identify this condition:
“If the styles are predominately classes (i.e. are “.className”) with ancestor selectors being few and far between, then you have classitis.” (http://www.steveworkman.com/html5-2/standards/2009/classitis-the-new-css-disease/)
Now given that Chris and Harry Roberts are clearly not novices, my question is this: What’s changed recently that’s suddenly got you giving advice that is contrary to conventional CSS wisdom on not loading up your markup with classes all over the place and using descendant selectors instead?
Dave,
To understand better why there is a shift back toward using classes on elements (but not promoting classitis), I recommend you read SMACSS.com. Jonathan Snook provides a solid explanation about scalable, modular architecture for CSS.
On small, brochure style websites, this approach seems like overkill – and it probably is. However, when trying to work with larger teams on large scale websites, inheritance and the cascade can actually work against your ability to maintain the CSS without wanting to go on a killing spree.
As in all things, moderation and planning are key. The SMACSS concept isn’t about classifies – it leans more toward a well balanced approach.
From what I’ve seen of OOCSS, working with lots of classes seems to be the best way; as – if I remember rightly from ShopTalk – FaceBook managed to make their CSS files 50% smaller with that.
As I just added on the CSS Wizardry post, I think this comment in his post sums it up the thought process:
“…ask yourself ‘am I selecting this because it’s a ul inside of .header or because it is my site’s main nav?’”
A good mindset to have!
great post Chris!
@Fulidbyte – true, balance can be key, but I wonder about the whole “semantic” code aspect of the second hand you describe. When it comes to HTML, the semantics seem to be in just the HTML tag you’re using to describe your content. But I don’t think that always relates directly to CSS semantics. CSS semantics should make your styling easy to apply and update if needed. (.redThing, might actually need to be blue a month from now)
If anything, it seems like having more classes actually has the potential to make the HTML even more semantically sound from a developers view, *as long as the CSS classes were set up with scalability in mind*.
Sometimes it is fun to go down the rabbit hole though :d
I don’t necessarily agree that it can be cleaned down to
There may be cases where the designer only wants it to apply to button-classed list items in comments. Perhaps non-list buttons and non-comment list buttons are styled differently. I’m going to ignore the ambiguous “button” name for the class.
Let’s take things step by step.
First of all, in ~99% of sites with articles and comments fields (and only one per page, given that #comments is an id), if if’s EVER inside an article class, it’s probably ALWAYS inside an article class. We can take out the initial class.
Assuming the designer actually knows how html works, li will always be inside ul. The edge cases that would need a direct descendent are so few (read: none, unless your html is a thousand times wonky) that we can just leave that out. This leaves us with this:
Based on the name “button”, I think it’s safe to assume it’s always going to be clickable, and therefore probably always an <a> tag. We can leave that out. Again, let’s leave out the direct descendant, because this whole selector is already so specific that we likely won’t need it unless our HTML is extremely messy. That leaves us with this:
I feel like this is still specific enough to catch all the same uses, without being generally chaotic or accidentally leaving any out. Of course, all this could be avoided by just making a new class just for this use case (heck, that’s what I’d do), but I think this is the cleanest way of doing it while leaving the original intent intact.
Makes perfect sense. For people saying about buttons being specific to comments surely you could just put:
And then apply the two classes to the comment buttons. That way the button class is always clean and only slight modifications need to be made.
Why bother with the
li
ascendant?I can’t imagine a case where you’d want to be so specific to drill down to a
.button
within anli
in#comments
, but you wouldn’t want to also hit a.button
that happens to not fall within anli
.Again, along the lines of what you’ve already mentioned, if we’re catering to incredibly malformed HTML, sure let’s be as specific as possible, but at that point, why not address the root of the problem?
I think you coded your example wrong
#comments li button {
You’re now selecting a button element on a page.
I think you meant
#comments li .button{
I know people say that fancy and complex CSS selectors are technically “slower” than more succinct selectors…but I think for most smaller “mom and pop” sites the speed difference makes little difference…
I personally like to keep my HTML as clean as possible because I believe in portability of content…meaning that I think the content should be able to be extracted from one site and placed in another….the more you use custom classes in the markup the more troublesome this can become…
Also sometimes we may not have access to the raw HTML and so these advanced selectors can come in handy….
I think these advanced selector are fine to use…unless you are building a site with a massive amount of views or more a month…and speed is your ultimate concern…
Agree
It sounds more like you’re not negotiating right or wrong here, you’re negotiating laziness vs best practice. “Practicing best practice” will always help you stronger in the long run.
Just like a painter who cuts corners on a paint job. He probably can get away with it for a few jobs, but there will always be one customer who makes you come back and fix it 3 times till you do it right.
While I agree that the example in this post takes specificity too far, I wouldn’t completely diss including parent selectors.
CSS by nature is messy (compared to other languages like C#, HTML, PHP, what have you) and I find that having entire blocks of styles:
is entirely too unreadable when you’re working on a CSS file that is massive (try doing SharePoint styling…)
I find that when I’m working, since I don’t mind long horizontal lines, I’ll fit each style on one line and use it’s parents as a guide to find what I need quickly:
I’m not sure how much slower it would take, but there are always minimizers as such, and even-so a few milliseconds are worth readable and maintainable code.
But yes, I think whenever the ‘>’ selector becomes involved you may need to re-think the structure of your CSS. Just don’t be so quick to judge very specfic selectors, because they are useful in more ways than one.
I feel your pain, SharePoint is nasty to style, not least because in the older version it doesn’t bother to declare a doctype!
liberal use of !important is normally where I end up (at least with SharePoint) :)
also: even though it’s Crazy Town, ever since I saw the Crazy Town comment in the previous post, I’ve had that disco song stuck in my head “Funky Town”
“Won’t you take me to Funky Town, won’t you take me to…”
THANKS A LOT! ;)
Haha great explanation. I love crazy town and happy town!
I actually find it much cleaner to scan css when there are slightly larger parent selectors. It gives you more of a sense of where you are, rather than just having a single class to point you somewhere in the html.
Think about it, would you rather have your html littered with classes and your css littered with single class selectors, making your css harder to scan. Or would you rather have parent elements with classes that point to regular elements inside it that wouldn’t change a lot, giving your css a much easier way to scan while not overfilling your html with classes.
The argument that you would have to change the CSS if there’s an extra UL element in the header seems rediculous because if someone actually did that your CSS will have to be changed regardless.
I prefer keeping my css scanable and html clean from class-clutter over just giving every single element in my css a seperate class.
This is where meaningful class names comes into play, right?
I wish the explanation had been put to me like this when I was first learning parent selectors, thank you for yet another great article.
Oh, Chris, I don’t know how you have such great self-control. Only you can write a blog post promoting OOCSS without once mentioning “OOCSS”. :)
You just have this awesome way of placing yourself as the web design industry’s unofficial diplomat.
But the truth is: It doesn’t matter what buzzword we use to describe what we do. It’s the solution that matters. Which is why problem solving will always be a thing, and buzzwords just go by the wayside.
You know, I use Sass… I nest code so I could move site elements around and not worry about specificity. My outputted code results in some pretty long selectors.
How does everyone feel about this article with the idea of using pre processors like Sass or LESS?
@David, SASS does a great job at combating this issue, IMHO. Our team uses SASS and scopes everything fairly tightly, because SASS is so good at handling nested elements that properly reflect the associated DOM.
Our SASS would probably end up outputting a selector like the original example in this article, with some exception:
• not use a #comments ID within a class (we try to use IDs to scope page overrides and minimize their use on sub-elements, because they override the cascade)
• not use the > selector unless it was ABSOLUTELY necessary. It’s incredibly useful, but communicates a very specific level of intent. If you start throwing it around without a real need then other developers/designers can’t trust that it’s there for a reason.
Just defining a general class of .button is fine for a small site, but any significantly complex site will soon become a sea of interdependent/elaborate class names (“I can’t use .button for this since it’s defined globally, guess I’ll call it … .cute_button”) and unintended inheritance (“Whoops, `.article a` tells my anchors to be red, and that overrides the blue `.button` definition when i put an anchor with a class of `button` in my `.article`”).
Of course one could also avoid id’s and tag selectors entirely and instead pile on the classes, but that’s more of a difference of philosophy than anything, this comment is already too long, and hopefully it already answered your question.
TL;DR SASS is good
I was thinking the exact same thing. I use SASS to “group” my elements nicely. For example, I could write this super simple code (let’s assume there’s only one type of list style on the page):
Which will obviously result in:
However, in this case that’s already too much nesting. UL LI is not necessary, and can be just LI (just like A.BUTTON can be just .BUTTON). Sure I could write my SASS differently, but again, I like to group my items like this, and place elements nested sometimes because they only appear in that section.
Same with something like
#header h1
when justh1
is good enough. In SASS it just gives a good visual idea of where this item appears in the DOM, in CSS it adds an unnecessary parent element.Obviously this is a super simple example, but it shows how neatly structured SASS code will not always result in Happy Town optimized CSS.
SASS and LESS are good. However, nesting can bite you in the ass if you aren’t cautious in its use. It’s still wise to think modularly, which means thinking through the implications future changes to the DOM might have on the way you’ve written your SASS or LESS code.
Tying styles specifically to a particular DOM structure doesn’t provide the flexibility that may be needed on a larger scale. Chris’s example is very specific, and it very well could be the result of someone coming into an already “specific” code base, struggling to get the right style to work on a specific element. I’ve been in that position before.
The point behind learning to break styles down into modular, less specific pieces is to allow design elements to scale along with the growth of the site.
When using SASS or LESS in a modular fashion, and nesting is needed for some reason, keep the nesting as shallow as makes sense. Something like “.comments { .button { } }” would be preferable to “.comments { ul.comment-list { li { a.button { } } } }”.
I’ve recently been experimenting with an interesting way of gently specifying things with a class as general as “.button”:
This kind of horizontal selector specification simultaneously deals with the problem of very general selectors, the problem of rules needing deeper and deeper conflict resolution, and the issue of how to clarify what the difference is. Additionally, when used right, it also allows you to actually set up a self documenting style guide for the visual language your users need to quickly understand directly within the CSS. Why is that button green? Why, it’s a submit button, that’s why. How about that black button? Oh, it’s a cancel button, of course.
Furthermore, you can unify styles in your visual language, if need be:
Specifically, maybe you need the payment form to be really, super clear:
Now, we’re super deep in site structure and dealing with specificity, and our code isn’t tromping all over itself.
Also, I’ve been noticing that one problem that tends to cause us to start fighting our own CSS is when we start out by using really general selector names, and then just keep doing it until we end up in a sort of Tron lightcycle situation. I think the real problem that causes that is that we started out way too general. Sometimes, we solve that by using parent selectors to get more specific; unfortunately, that often ends in crazy town. The thing is, it’s a language issue, not a code issue. We got in trouble because we started calling all chairs red chairs. Only red chairs should be red chairs, and only submit buttons should look like submit buttons. With horizontal selectors used this way, we never call all chairs bean bag chairs. A bean bag chair is comfy and squishy, a chair is for sitting in. The chair isn’t comfy and squishy because it’s in my bedroom, it’s because it’s a beanbag chair. If I started telling everyone I knew that every chair in my room was squishy, I’d end up in crazy town, fast. Instead, I tell them that all bean bag chairs are squishy, and my friends never get confused by my desk chair.
I think you’re right. Whenever I’ve gone horribly wrong, it’s exactly because I’ve started out too general and add specificity to over-ride that. I’ve been figuring out ways to be more organized and rational with my CSS, and this is definitely part of it.
It’s not a best practise, using tags in selectors, like “article .button”, there could be many types of articles on site, I think it’s better to use specific article class “.article .button”
great post Thanks…
Nice post. I think grouping is better option. Thanks for this useful and helpful post.
BTW just in case if there was ever any doubt ;-) I’ve created a benchmark test to prove the article too – it shows simpler selectors up to 40% faster! http://bit.ly/ObVKpv
“Chances are, the selector should be”
Indeed … chances are. Just make sure your css selectors are correct. Make sure that everything inside is necessary, just don’t take stuff out of them just because they “become too long”.
The danger of this new hype of promoting short selectors is that people only remember that, even though short selectors aren’t necessarily better, could hurt future-proofness and impact performance only marginally.
As for the html, these classes don’t hurt the semantics, but they do hurt reuse of html code. Littering your html with classes like “comment-button” is far from smart and it is limiting your html code to be reused in other projects.
I’ll grant you that it’s quite likely that the “crazy town” selector could probably be improved in most situations. I’m just saying that you shouldn’t judge someone’s CSS on that alone, unless you’re sure you understand how it could be improved, and what led the developer/designer to use such a selector in the first place.
If you see something like that in a project that the dev/designer has created from scratch and has full control over, sure, it could most certainly be improved. But there are a lot of cases where you are modifying an existing site, and you don’t have the option to dump legacy code. That crazy town CSS might be a side-effect of crazy town HTML generated from a Drupal module.
I’m no designer, and I’m sure that my blog has plenty of crazy town selectors. Some of them are from plugins. Some of them are my own (probably to override something from a plugin). On the one hand, I don’t expect somebody to judge my overall skills by the CSS on my blog. But on the other hand, I think that crazy town selectors should probably be pretty low on the list of things by which to judge CSS code quality. If you do see them, maybe you should look to see if there’s some reason for it.
If I have to write nutso selectors to override something generated by a CMS, I do it. I don’t always have the option to change the code that’s generating the original HTML + CSS.
Again, this is from my perspective as a developer (not a designer), and from my experience dealing with projects that have changed hands at least once, on big CMS installs (Drupal mostly, lately, WordPress sometimes). Every time I see !important, my brain screams, because it usually means I will end up writing my own, more specific !important rule, and I die a little inside.
I think the SMACSS approach is certainly a good way of preventing unnecessary specificity, with the added advantage of not being bound to elements in specific.
I’m a really big fan of taking the modular approach, for example:
As long as you make sure you don’t end up with a gazillion classes on your elements (then you clearly abstracted way too much), this is a nice and VERY maintainable approach to CSS.
Furthermore, I think the base principal should always be the following: make the mark-up as semantical and sensible as you can; perfect it so your document and data really is structured and then go about styling only where explicitly needed and abstract as much as you go.
God I love front-end! :-D
What of I use less or sass and I just like to nest selectors?
And it outputs to this:
Would that be valid reason?
Hi Enrique,
In general it’s a bad practice (although a tempting one) to reflect your HTML structure in SASS/LESS, as it creates unnecessary selectors which will become more complex as your project grows.
I think you really need to master CSS in the first place in order to make good use of pre-processors, If you don’t have a good grasp of what’s going on ‘under the hood’, then your SASS/LESS will end up being rather inefficient as well.
I don’t use SASS that often (regrettably) , but when I do, I like to create ‘placeholder’ classes in order to increase maintainability, like so:
That way you’ll end up with nice code like:
Which your linter will love as well ;-)
I would have just used
adding the “a” tag instead of going all the way back up! no?
a.button is too specific, no need for the element here (also less flexible).
.button is good enough ;-)
Specificity is the devil!
LOL!!! I agree!
Very Lol. I am very confused with spesificity
I’ve been a developer for over 30 years and if there’s one thing I’ve come to value it’s maintainability. Unless speed is critical (systems such as air traffic control come to mind), maintainability is the most important requirement for code after efficacy. Then comes commenting. Efficiency comes a very distant third. Addiction to awesome cleverness immediately disqualifies someone from being allowed anywhere near code :-)
It’s not just a matter of being kind to novices: complicated nestings & inheritances are inherently unreadable due to the limited capacity of short-term memory. It takes more time to figure them out than it does to read simple statements. As a result, maintenance costs soar. Then there’s the changing nature of technology as well as coding styles. Something that may be comprehensible in CSS3 may be completely baffling to someone who is used to CSS15… (don’t forget, there are still systems running that were coded in the 1970s – who knows if web systems will have that kind of longevity?)
By all means use clever stuff on vanity sites, but for serious systems, keep it maintainable!
This is what I’m struggling with at this very moment:
.menu2 > li ul:hover > li ul
and
.menu2 > li:nth-child(3):hover ~ li
Heh..