Grow your CSS skills. Land your dream job.

Crazy Town Selectors

Published by Chris Coyier

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.

  1. It's an element with a class of button.
  2. But it has to be an anchor link, otherwise it won't match.
  3. 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.
  4. 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.
  5. 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 of article 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.

Comments

  1. Harry Roberts (@csswizardry) posted a great article on this yesterday: http://csswizardry.com/2012/07/shoot-to-kill-css-selector-intent/

  2. Nico
    Permalink to comment#

    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

    • ben
      Permalink to comment#

      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.

  3. Dave^
    Permalink to comment#

    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!

  4. 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*.

  5. Sometimes it is fun to go down the rabbit hole though :d

  6. Covarr
    Permalink to comment#

    I don’t necessarily agree that it can be cleaned down to

    .button {

    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.

    .article #comments ul > li > a.button {

    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.

    #comments ul > li > a.button {

    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:

    #comments li > a.button {

    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:

    #comments li button {

    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.

    • Permalink to comment#

      Makes perfect sense. For people saying about buttons being specific to comments surely you could just put:

      
      .button{
      /*Overarching button styles */
      }
      .comment-button{
      /*Slight button modifications*/
      }
      
      

      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 an li in #comments, but you wouldn’t want to also hit a .button that happens to not fall within an li.

      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{

  7. 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…

    • Steve
      Permalink to comment#

      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.

  8. Eric
    Permalink to comment#

    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:

    
    .style{
        background-color: #FFF;
        color: #000;
        ...
        font-weight: bold;
    }
    

    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:

    
    #library{padding: 5px; color: #626262;}
    #library    #library-top{border-bottom: 1px dashed #CCC;}
    #library    #library-top   img{display:inline-block;}
    #library    #library-top   div{padding-right: 20px; }
    #library    #library-bottom{color: #fff;}
    

    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.

    • Trev
      Permalink to comment#

      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) :)

  9. 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! ;)

  10. Permalink to comment#

    Haha great explanation. I love crazy town and happy town!

  11. Kevin te Raa
    Permalink to comment#

    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.

  12. 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.

  13. 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.

  14. 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):

      ul {
          border:solid 1px black;
          li {
              border:solid 1px red;
          }
      }

      Which will obviously result in:

      ul {
          border:solid 1px black;
      }
      ul li {
          border:solid 1px red;
      }
      

      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 just h1 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 { } } } }”.

  15. I’ve recently been experimenting with an interesting way of gently specifying things with a class as general as “.button”:

    
    .button {
      /* All buttons look like this. */
    }
    
    .submit.button {
      /* specifically, submit buttons look like this. */
    }
    
    .important.button {
      /* Users might need to notice this first. */
    }
    
    .important.submit.button {
      /* Important submit buttons need something special. */
    }
    
    .button-group .button {
      /*  Buttons in a group of buttons look like this. */
    }
    
    .button-group .last.button {
      /* 
        * The last button in a button group might need something specific,  
        * and also needs to do that in IE7.
        */
    }
    
    .button-group.of-two .button {
      /* Something specific needs to happen when two buttons are grouped. */
    }
    

    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:

    
    .button {
    /* Buttons all share these qualities. */
    } 
    
    .submit.button,
    .next.button {
      /* Users who see buttons that look like this know they can continue by pressing them. */
    }
    
    .cancel.button,
    .previous.button {
      /* Users who see this style of button know they can go back by pressing them */
    }
    

    Specifically, maybe you need the payment form to be really, super clear:

    
    #payment-information .submit.button {
      /* Users know this will spend their monies. */
    }
    

    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.

  16. 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”

  17. great post Thanks…

  18. Permalink to comment#

    Nice post. I think grouping is better option. Thanks for this useful and helpful post.

  19. 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

  20. “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.

  21. 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.

  22. Reinier Kaper
    Permalink to comment#

    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:

    
    <a href="/somepage" class="btn btn-callout">Let's go!</a>
    
    .btn {
      /* base styles that go for all buttons */
    }
    
    .btn-callout {
      color: red;
    }
    

    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

  23. What of I use less or sass and I just like to nest selectors?

    .wrap {
        margin: 0 auto;
        .something {
            background: black;
            .something-else {
                color: white;
            }
        }
    }

    And it outputs to this:

    .wrap {
        margin: 0 auto;
    }
    .wrap .something {
        background: black;
    }
    .wrap .something .something-else {
        color: white;
    }

    Would that be valid reason?

    • Reinier Kaper
      Permalink to comment#

      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:

      
      .sprite {
        background: transparent url('/img/sprites.png') top left no-repeat;
      }
      
      .sprite-youtube {
        @extend .sprite;
        background-position: -10px -100px;
      }
      

      That way you’ll end up with nice code like:

      
      .sprite, .sprite-youtube {
        background: transparent url('/img/sprites.png') top left no-repeat;
      }
      .sprite-youtube {
        background-position: -10px -100px;
      }
      

      Which your linter will love as well ;-)

  24. I would have just used

    a.button{
    /*  stuff here */
    }
    
    

    adding the “a” tag instead of going all the way back up! no?

    • Reinier Kaper
      Permalink to comment#

      a.button is too specific, no need for the element here (also less flexible).

      .button is good enough ;-)

  25. Permalink to comment#

    Specificity is the devil!

  26. 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!

  27. 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..

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".