Don’t over-specify your CSS code

When I started writing CSS, I wanted every CSS rule to be as specific as possible. This was to get an instant overview as well as making sure that the desired style was applied to exactly the element I wanted.

After many years of web developing, though, working on both small and large projects, my experience is that over-specifying the CSS is usually a bad thing. It leads to the usage of !important remarks all over, since people have a hard time finding why a style is applied, or can’t find a proper way of specifying it better to just override the previous style. Even though Firebug has made it a lot easier to find inheritance and all styles applied to an element, there’s still seldom any need to as specific as most tend to be when writing CSS code.

To exemplify:


/* Instead of this: */
div#container p.pre-amble{
	margin-top: 1em;
}

/* Write it like this: */
.pre-amble{
	margin-top: 1em;
}

/* Or like this: */
#container .pre-amble{
	margin-top: 1em;
}

/* Instead of this: */
div#container div#header ul#navigation li{
	float: left;
}

/* Write it like this: */
#navigation li{
	float: left;
}

/* Or like this: */
#header #navigation li{
	float: left;
}

What’s the gain?’

The idea is to be as minimalistic as possible. Find the least numbers of common denominators needed to apply a style to an element. By doing this, you will get these advantages:

Much easier for specificity

This means that when you have any style you want that is an exception from the common styling, it will be easier to implement it and override the default applied styling.

File size

Generally speaking, a slimmed down-version compared to an over-specified CSS file is about half the file size. Kilobytes that will, o doubt, be to your gain.

Reusability

Meaning that CSS rules used for some parts can also be reused in any parts without any modification.

Readability

While more specific rules can give you a more detailed description of where it’s used, short, compact CSS rules give you a fast and clean overview.

My advice to you is to remove what you believe to be superfluous specificity, and see just how much more simple it gets and how happy you will become by doing it. 🙂

24 Comments

  • Fabrice says:

    I've gotten used to writing style rules on a single line , as this aligns rules and makes the structure more apparent, and more amageable for long CSS files :

    example:

    <code>

    table.main-actions { … }

    table.main-actions td { … }

    table.main-actions td.pri a { …}

    table.main-actions td.pri a span { … }

    table.main-actions td.sec { … }

    table.main-actions td.sec a { … }

    </code>

    However I agree and in those cases it can be simplified :

    <code>

    table.tabular tr.edit-row td { background-color:#ffffdf; }

    table.tabular tr.edit-row input { display:inline; }

    table.tabular tr.edit-row var { display:none; }

    table.tabular tr.edit-row a.edit-row { visibility:hidden; }

    </code>

    tr can be removed to save some space, maybe even "table" is redudant, while keeping everything aligned and readable

    <code>

    div.picker .root .pager { … }

    div.picker .root .pager td { … }

    div.picker .root .pager td.icon { … }

    div.picker .root .pager td.first {… }

    div.picker .root .pager td.last { … }

    div.picker .root .pager td.pnum { … }

    div.picker .root .pager td.pnum a { … }

    div.picker .root .pager td.pnum a:hover { … }

    </code>

    Here we could remove ".root" to make things easier to handle,

    the trick always is to see in advance if this structure may be re-used in other areas, with slight modifications of appearance.

  • Hi Robert … You're right but if I can "spam" CSS size is not a problem if You choose to serve both JS and CSS using my last unobtrusive idea: packed.it

    However, good practices to write CSS are always appreciated!

    P.S. feel free to remove this comment if You don't like them as You said few posts ago 🙂

  • Eric Shepherd says:

    In a lot of my work, I use chunks of HTML which are modular and can be used anywhere. For ease of portability, I often use very specific CSS rules so that I can copy and paste the module to another site along with its CSS and know that I won't have conflicts from other rules affecting the module.

    Our internal CSS style guide pretty much bans the use of !important, encouraging developers to get at the root of the problem instead of hacking around it.

  • Deborah says:

    Thanks for the reminder on CSS specificity. Sometimes it's just hard to remember when you're struggling with a display issue in browsers.

  • Anders M.J. says:

    The CSS on my blog is currently over-specified, but I plan to change it when I get around to it. The reason it is, is because I started out by deleting the style.css file in the default theme and then wrote it from the ground and up. Problem was, that one browser (can't remember which one) had trouble if I left out the element name (div) before the ID name, e.g. this worked:

    <code>

    div#page {

    /* styles here */

    }

    </code>

    This didn't:

    <code>

    #page {

    /* styles here */

    }

    </code>

  • Nik says:

    Robert,

    I can see your point, but I use specification as a way of organizing my CSS. If I will only use a class called .warning in one section, I will still put at least the containing div id before it to remind myself where this style is being used, e.g.

    <code>#mainBox p.warning { … }</code>

    instead of

    <code> p.warning { … } </code>

  • I partially agree but let's not forget about semantics of classifying and identifying elements.

    I agree that something like:

    <code>

    div#container div#header ul#navigation li{

    float: left;

    }

    </code>

    is redundant simply because ID's such as #navigation only appear once in a document (according to spec) so having multiple ID's in the rule isn't really useful since there's only one #navigation anyways. The only exception is if you're using a dynamic CMS that keeps moving #navigation around in the markup (but if that's happening then you've probably got other issues).

    However, the example of

    <code>

    .pre-amble{

    margin-top: 1em;

    }

    </code>

    can often cause problems if it's too vague. If 'pre-amble' is a class then I would assume there are multiple pre-amble classes scattered about the page, on different elements. Now you've said they should all have a specific margin but in reality the pre-amble in the sidebar will probably be different than the one in the main content area. In this situation, if there's only one pre-amble, it might be better as an ID (the pre-amble of the content area) or, like you said, something like:

    <code>

    #content .pre-amble{

    margin-top: 1em;

    }

    </code>

    I've found a lot of the issue can be resolved by defining common classes that should always be associated with an element. For example, .first could be used to indicate the first in a set of elements (if you ignore advanced selectors). Then you can do:

    <code>

    #navigation li.first { }

    #content p.first {}

    etc…

    </code>

    but you'd never use .first all by itself.

    The problem mostly arises when you're working in a team so I guess the trick is to make sure everyone in your team is on the same page regardless of which methods you choose to use. Advantages of smaller file size, reusability and readability are great but reusability can also be a disadvantage if that's not what was intended by the rest of the team. If it's too reusable then you'll be back to !important again.

  • Mark Ferree says:

    I think that !important has an unnecessary bad reputation.

    I have noticed many people using code like:

    <code>

    html body #wrapper #nav {…}

    </code>

    Just to avoid using !important.

    When I'm scanning through a css file !important will jump out at me as a "hack" but the above code will not stand out as easily. Seeing !important lets me know immediately what I'm dealing with.

    In a perfect world we would avoid both, but as we all know the web is not a perfect world.

  • Over the past two years I've become more minimalistic with my CSS. However, I'm with Eric Shepherd on being very specific when I write a module that will be used by other developers. About 40% of what I do at my job is write utilities for use by other developers where I work.

    In the past, I've been burned because my CSS was not specific enough and the developer CSS overwrote my styles. This happened with my dropdown calendar. A developer's styles made the calendar text so small that it was unreadable. Instead of the "Today" link being centered it was right justified. Then they complained that the problem was with my utility, and they were right, I needed to be more specific.

    So while I agree with you for general page styles, when writing a utility that is going to be used by other developers, I have to protect my clients by being very specific with the CSS styles for that utility. If the developer needs to overwrite a style, they can do it by being just as specific. That requires them to intentionally want to make a change to the style of the utility.

  • Steven Clark says:

    Good advice Robert, especially to anyone just learning CSS so they have the mental tools to assess when it is true and when they may need to overly specify as in cases mentioned in the comments so far (working with others).

    I think the rule often quoted is start general and get more specific as you find the exceptional cases.

  • Another benefit is that seeing you are less anal about lCSS development meaning you will generally enjoy life more 😀

  • I usually split up my rules so that all generic things about a "help box" (for instance) is declared within, say the .help rule. Then I use wrapper ID:s, layout classes or what I find is most suitable to specify the layout/placement specific aspects of the help-box, when placed in different contexts.

    About having element names before classes: I find this very useful when I have general class names (like .help) where I might use a.help or img.help elsewhere in the markup. Using div.help leaves the clashes out of question that way.

  • Robert Nyman says:

    Good input! And Eric Shepherd raises an interesting point, where you won't know the context and want to make sure it's not overridden by any other styles.

    But I think/hope that such scenarios aren't that common, although I know they do exist. It seems they exist more in fairly large web sites and in communities.

    Jeffrey Sambells ,

    I think my examples are a bit too short to exemplify my point about reusage. The idea is, with .pre-amble for instance, is that many CSS properties will be the same wherever it is used. The gist is to focus on what is being general no matter where it is being used, and then code extra for exceptions. Kind of like this:

    <code>

    .pre-amble{

    color: #f00;

    font: bold 1.25em V eradna, Arial, Helvetica, sans-serif;

    text-align: center;

    margin-bottom: 1em;

    padding: 0.5em 1em 0;

    /* etc… */

    }

    and then just have any potential exception for the sidebar:

    .side-bar .pre-amble{

    color: #000;

    }

    </code>

  • I'm glad to see there are others who feel this way. Selectors get completely overblown sometimes. I especially see it in WordPress themes.

    I wonder how much of this comes about because of the way Dreamweaver pre-populates the Advanced selector field when a page element is selected in Design View and the + sign to create a new style is clicked. Dreamweaver goes through the entire page hierarchy in naming the selector, an example of far too much.

  • SpookyET says:

    http://www.thepirateship.com/sites/all/themes/the

    I write boxed css code. I don't plan on switching soon. There are great advantages. I can install a forum or a gallery and reference the global CSS and style small parts of the gallery as opposed to fully styling it because there are no conflicts due to specificity. There cases where classes are not enough, especially when you use common terms that can be used by multiple applications for different things.

  • Marco says:

    I think lots of excessive specificity stems from the 'time is money' principle. This is especially true when developer A has to fix something in developer B's code and it has to be done in 10 minutes because people can't accept that certain things sometimes take their time.

    CSS quite often tends to start out nice, compact and organised and then slowly but surely deteriorate into a mess, especially when lots of different people who all have their own way of working edit it. It takes some serious discipline, coding conventions and patience on the side of those who are in a hurry to prevent this from happening.

  • […] Robert Nyman befasst sich mit der Spezifizität von CSS- Anweisungen: Don’t over-specify your CSS code. […]

  • […] • Don’t over-specify your CSS code […]

  • Andreas says:

    I think Jeffrey Sambells said pretty much all I was thinking. I'm always too specific and I know that, but I don't mind it and to me it makes the code easier to read. Also I'm not sure you'd lose 50% of file size simply by being less specific in your selectors, the properties and their values are the majority of code in my CSS.

    If I use a JS-library with support for CSS-selectors (like jQuery) I'm always as un-specific as possible because of performance issues; '#contact form p label input[name="email"]' must be slower to retrieve than just #contact input[name="email"]… or am I wrong? Also, are there performance issues with being too specific in your CSS as well?

  • Robert Nyman says:

    Andreas,

    In theory, the more specific style rules, the slower it should be for CSS code as well. Then again, I think the difference is hardly noticeable from a performance standpoint.

  • Jeremy Dill says:

    Good article!

    I’ve been doing quite a bit of css fixing/updating for a handful of large complex websites lately. Some of what I am finding right along with what I am reading here.

    Here is my view on this (think of me as an outsider looking into your CSS to fix or add something).

    Method 1) Being very specific is OK as long as you are doing it all in 1 file and you maintain a nice single line grouping (like Fabrice mentioned).

    Method 2) Using a generic method (sometimes with “Overrides” such as Roberts .side-bar .pre-amble) is a a great method for being efficient in terms of code size and reusability.

    Working with 1) Use the CSS file like an index based on what page you are working with, find its reference and alter it.

    Working with 2) Search the CSS file for the class name (or parent) that is applying to your element. As long as your class names/IDs aren’t super short or generic (like don’t name a class with less than 3 letters) it is pretty easy to find all the places where that class is referenced..and then to see what subtags are affected. Since there is less overall CSS, it is not too difficult to figure out what is going on.

    Benefit of 1) The benefit of method 1 is that people who are very CSS minded tend to prefer working like this…and it allows for very specific control of everything, and you don’t have to crack open the html file very often.

    Benefit of 2) The benefit is that you can change things on all pages at once without having to be specific. You can minimize your code and simplify the styling markup. (which I think was the point of this article)

    Disadvantage of 1) You have to write a lot of CSS. You might will find yourself writing the same styling over and over again if you lock yourself into this method.
    Example – (Real example from something I had to work on):

    #sidebar-left .links-menu li#work.active a, #sidebar-left .links-menu li#work.active a:hover{background-position: 0px 0px;color: #fff;}
    #sidebar-left .links-menu li#contact.active a, #sidebar-left .links-menu li#contact.active a:hover{background-position: 0px 0px;color: #fff;}

    Disadvantage of 2) Requires that you are very clever in your overall structure and design. You have to carefully construct your HTML and your CSS to work together. You have to pay close attention to inheritance and use it to help rather than trying to defeat it. Doing all of this might take more time, and you might not be able to get something up and running in a hurry.

    Whatever method you choose, please keep the following things in mind. These are the things that take lots of time and headache to sort out. (at least for me)

    Please don’t mix and match these 2 modes of writing CSS. Tracing through the multiple degrees of generic to super specific tags is never a treat.
    Please keep your stuff grouped (especially critical in method 1).
    For both methods avoid multiple files. Put it all in one file and avoid browser specific hacks or include files. It is possible (although challenging) to write css without hacks.
    For both methods, don’t put in style declarations that do nothing at all.
    For method 2, don’t take it to an extreme. Don’t be afraid to use classes for grouping. Rather than putting generic styles on “li” for example, create a class that groups all the elements inside an unordered list. I.E.

    .simple_list ul{...}
    .simple_list li{...}

    Then wrap your list

    < div class=”simple_list”>
    <ul><li>item</li><li>item2</li></ul>
    </div>

    Why didn’t I just use ul.simple_list {..} and then apply the style to the ul tag? Because now I have organized my css and my HTML in such a way that I can keep doing things to the .simple_list class of boxes, and it keeps things in a name space in for readability in CSS. So, if there are hyperlinks in there for example, I just add another .simple_list a{…}. It’s not super specific, but it’s not so generic that somebody might get lost.

    Ok.. so you found me out. You can probably tell that my preference is method 2. Robert, I am in your camp on this. I think it just makes better use of the power of CSS and HTML. Also, badly written generic code is easier to troubleshoot than badly written specific css in my opinion.

    For those of you who want to make something portable, just put a single ID or unique class at the base of the styling elements to be grouped. This will essentially create a name-space bucket for it (#container as Robert demonstrates). You don’t have to traverse all the way down to each element.

    Ya know, I thought that the point of CSS is to make things more manageable (better organized) and to create separation. But, the way I see it, separation isn’t a benefit in itself. Separation is actually just a requirement so that we can do more things with the page content later.

    If the end result of a CSS implementation is that you need Firebug just to figure out what in the world is going on, then we might as well run with the devil an do all inline styles so we can at least find everything in one place. We haven’t achieved manageability or separation in this case anyway.

    happy coding to you!

    – Jeremy

    PS. Marco.. good point.

  • Robert Nyman says:

    Jeremy,

    Great comment! I pretty much agree whole-heartedly in everything you wrote! 🙂

  • […] Don’t Over-specify Your CSS Code […]

  • […] Don’t Over-Specify Your CSS Code – Robert Nyman […]

Leave a Reply

Your email address will not be published. Required fields are marked *