Ask HN: Anyone have a really smart way to organize css?

198 points by katieben ↗ HN
I'd love to see an example of super organized, tight CSS. Do you organize by location (header, footer, body), by function (typography, position data), or both, with multiple instances of the same selector? Wondering how my css stacks up and where I could improve. Thanks! (:

121 comments

[ 4.5 ms ] story [ 189 ms ] thread
I'm hoping for some good answers here, because I'd love a better way.

I always put universal elements first (body, img, @font-face, etc.), then I just organize it top to bottom by page location (i.e. header, content, sidebar, footer, etc.). I also tab-indent so that elements within another are indented and "contained" underneath, making it easy for me to move from one section to the next. I also write the CSS horizontally, only making a new line for a new element.

I should also note that I'm a n00b :-), so this could be a horrible way to do it.

I do it more or less the same way, except I try to separate the layout from its content (I'll put #header, #content, #sidebar, #footer together, and later on define stuff that is specific to the content of e.g. #header).

Also, when having quite a few properties for a selector, it's quite difficult to read when all is on one long line, so I use new lines for each property.

With the exception of the horizontal CSS (personal preference - unless its compressed, I prefer things on new lines), I like everything you said.

(I actually find the tab-indented elements really interesting and may have to try it on my next project!)

One thing you didn't mention were comments. I've seen some css files with great commenting. For instance, comments at the top that act as an index/table of content for the css file. Very nice!

I do it by widget and layout.
Slightly related, but mainly a formatting issue, I format my css files as such:

  .foo    { x: y; a: b }
  .bar    { m: n }
  .baz    { background: blah blah url(xyz.png) top left;
            x: y; i: j; }
instead of the more commonly seen:

  .foo {
    x: y;
    a: b;
  }

  .bar {
    m: n
  }

  .baz { 
    background: blah blah url(xyz.png) top left;
    x: y; 
    i: j; 
  }
My format takes up less vertical space in the editor. Sometimes, I can get my entire CSS file into a single page on the screen, reducing the amount of time I spend scrolling and searching. I do split lines when they go off the edge of the space, as seen in the .baz example.
I prefer the latter. It's more readable IMO. If file size is an issue, I just use a CSS compressor. Also, it's not too hard in finding selectors, most IDE's or text editors have a "Find" command to locate a selector. That's my 2 cents.
This isn't about file size at all, it is about being able to see as much CSS as possible at one time.

My screen is wide, my editor is wide, my code is fairly wide, but the standard format for CSS is really narrow. Every time I see the vertical format in my editor, easily 80% of the window space is completely empty, and otherwise useless, and 80% of the CSS is not on the screen and I have to page up and down, or search, to find stuff.

This is a workflow optimization that works for me. It might work for others too.

I do it too and for the same reasons. Just easier to keep your head around if you can see and scan more of the file at once. I tend to list properties with the most crucial to layout first so it's easy to find major problems (e.g., float, etc).
why don't you let your IDE organize your selectors? As mentioned above, CSS Edit does a great job with this. With it, you get the readability of the latter formatting system and the scanability (not a word, I know) of the former system.
If you're working on a project with multiple people, having the CSS properties one-per-line helps a lot with determining who changed what in your version control system.

Most of the command-line diff tools don't highlight changes within a single line, and annotation tools usually work on a per-line basis as well.

To be honest. With firebug's ability to tell me what line and css files the style on an element is coming from I don't find spending a lot of time on organization to have a ton of benefit.
While I love Firebug, I'd have to counter that organization with CSS is actually quite important (and does have its benefits!)

This is especially true when you're working either in a team environment or on a large site. The very nature of CSS (and how things cascade down) can become a nightmare when organization isn't taken into account from the start.

I agree completely, especially on a web app that is constantly growing. 2 on-the-job things that help me the most are:

1. Using the 960 grid system (or your preferred grid flavor) 2. Grouping by the following:

Body Typography Forms (Other global stuff like links and buttons) /* Layout Element 1 / ID1 {} ID2 {} class1 {} class2 {} / Layout Element 2 */ ID3 {} ID4 {} class3 {} class4 {}

I also write my styles on one line, but that's just personal preference. I find it easier to scan down for the selector, then across for the property I want. I definitely don't do it for aesthetics or file size ;)

I haven't used it, as there just hasn't been a project with enough lead time to experiment with something lately, but I'm fond of the idea of code generators for CSS, like CleverCSS for Python and Sass for Ruby.

Other than that, the best advice I can offer that I DO follow is that I group all HTML elements together, all IDs together, and then all classes together. Within each of those groupings, everything is in alphabetical order.

  body { foo: bar; }
  form { foo: bar; }
  h1, h2, h3 { foo: bar; }
  input { foo: bar; }
  p { foo: bar; }

  #container {}
  #footer {}
  #nav {}

  .etc {}
  .even {}
  .odd {}
and so forth.
my css is pretty simplistic like this also.

one thing to do is to place class names based on the url with your id's. the class name can be generated from the request_uri (assuming the html code is in a view/template/include).

example: <div id="container" class="contact_us">

then if you need tweaks to a specific page, just add #container.contact_us { foo: bar... }

I have four core files:

    reset.css    - I use eric meyer's
    elements.css - Global defaults for things like body,
                   h1, h2, h3, p, a, input, strong. All
                   or almost all selectors in here are
                   just tag names.
    layout.css   - Just sets up the global layout with
                   containers: e.g. header, footer, left
                   column, right column.
    blocks.css   - Reusable chunks.
In addition to that, I use a separate file for each "page type". For example, 'article.css', 'index.css', stuff like that. Some larger sites merit additional files like splitting off 'forms.css', 'tabular.css', etc.

All files get concatenated and minified before serving, obviously.

What would you put in chunks.css? Could you maybe provide a brief example?
I can't speak for the OP, but as I use a similar system I can venture a guess that some of the following might be worthy of chunk status...

For a website: callouts, user quote styles, tables styles [zebra stripes, etc.], feature lists, intro paragraph styles, Flash/message styles, common control styles, etc.

That makes a lot of CSS files. Google chrome network optimization would tell you to reduce the amount of includes to speed up your site. That said that is debatable since it would be quickly cached.
As he says at the end, one would obviously not just stick a big stack of `link`s in the page. Some kind of build system/asset packager would be necessary and desired (so you aren't forced to write a huge monolithic css file that no one but your past-self can navigate :)).
Use SASS with partials and mixins and sort them as it's more convenient for you (probably following the natural flow of descending order of your page).
SASS has helped me with organization tremendously. With SASS I keep a "typography" partial that is the basic text elements (h1, p, etc.) and font-family variables.

I also have a "colors" partial where I put variables for all my color definitions, such as $light-blue, $dark-gray, and $background-color.

I leverage SASS and Compass for Ruby heavily.

I utilize mixins heavily so I can modulize all my styling and make sure it's included in areas that are appropriate. I've learned this is the only way to handle CSS without styles getting too complicated and accidentally changing something where you didn't mean to.

Example (create a mixin that has certain styles for forms and then include it in a body.wizard page) this way I keep my CSS very dry.

General coding guidelines are horizontal. I recently switched to this. I used to do vertical and indentation but it's very hard to read with big files. I've found that it's a lot easier to read horizontal CSS.

I alpha all my styles from a-z.

i saw one guy's css once it it looks like:

  .wrapper { ... }
      .sidebar { ... }
      .content { ... }
the indentation was well done.
(comment deleted)
We had a GUI 'designer' who did the exact same thing to our whole site. Spent ages trying to get stuff to work... :)
Here's what I do:

- Almost all CSS goes in 1 big file. One line per selector to keep thinks clean and easy to find. Styles from external sources (like jQuery UI) go in separate files.

- Reset lines go at the top, if you use them, in a / RESET / section.

- Styles for individual HTML tags are next in the / HTML TAGS / section.

- Then a / UTILITY CLASSES / section for clearing floats, etc.

- Next comes site layout. Headers, footers, page width, etc. all go here. Just the layout though - think the grid. No real content styling yet.

- Now sections for each piece in the layout. Content styles go here. First a section for the / HEADER CONTENT /, then a big section for the / PAGE CONTENT / (vast majority of styles go here), then the / FOOTER CONTENT / styles.

The best suggestion I can give is to break up your CSS into multiple files. If you have a "projects" page, make a "projects" CSS file for style definitions specific to that page. I keep the overall layout elements together. I typically also have a "forms" CSS file just for buttons, form layouts, and inputs.

Then @import everything in screen.css.

Natalie Downe, my co-founder, has a very neat technique for organising CSS which she calls a CSS System. She described it in this talk:

http://lanyrd.com/2008/barcamp-london-5/sg/

She splits everything in to general styles (basic HTML elements), helper styles (things like forms, notifications, icons), page structure (header, footer, layout columns etc), page components (reusable composable classes for components that occur on different pages in different combinations, such as a news teaser) and over-rides (special cases for individual pages, rarely used).

She hardly ever uses IDs, preferring classes for almost everything - because CSS written against classes can be used more than once on a page.

She uses CSSEdit's groups feature to make the CSS easier to navigate - it's all in one file. http://macrabbit.com/cssedit/

View the stylesheets on http://lanyrd.com/ and follow the link at the top to the unminified version to see annotated examples.

ID's are useful for unique element styling which will always be a case in a website. There's certain elements that are absolutely unique.

Goes hand-in-hand with javascript to ease selector targeting.

I never scope ID's either, that's the wrong way to do it. An ID is always unique so it is top-level.

The problem with absolutely unique elements is that, in a complex enough website (that evolves over time), they often end up not being unique after all.

I agree about IDs for JavaScript though.

Exactly, as far as CSS is concerned an id is effectively equivalent to a class name except when it breaks things.

Ids should be used only for scripts, and most of the time should be auto generated anyway.

It is not equivalent in any sense. Let's not forget specificity.
If you're relying on weird specificity chains, then your CSS is likely an unmaintainable mess.

Leave IDs for uniquely identifying an element on a page because you need to access it from a script.

Treating them like "Extra Strong" class names is a maintenance nightmare.

"I agree about IDs for JavaScript though."

Would you mind elaborating on the JavaScript point? Is it for convenience with document.getElementById or something?

Using jQuery, I tend to prefer class selectors the same as in my CSS.

There's less of a win in ajax from applying functionality on a class level - there aren't typically multiple selector boxes on the same page that all hit the same ajax callback.
Jquery class selector is the slowest selector, avoid them as much as possible. ID selector is the fastest. So, if your application is jquery intense, better avoid css selectors.
in modern querySelector implementations (any real browser), class look-ups are just as fast as IDs.
Another problem with IDs is that they make the "point system" in selectors much more complicated than if you only use classes and elements.
What about an ID for main page elements and things that never will change like #header or #footer or #sidebar?
Ideally for those you would use the html5 header, footer, and aside tags, respectively. You can use the html5 Javascript shim to enable support for those tags in IE.
sidebar is not equal aside, and you can have several headers footers on one page.
ID is unique on the page. Website can have many pages. If there is a need to style some element of the page differently scoped IDs can be handy.
I checked the lanyrd.com stylesheet. I'm sorry to say but if your stylesheet is this big you are doing it wrong. 100K for a compressed stylesheet! So I'm not so sure her technique is a winner.
Oh really? Because every medium-to-large website I've ever looked at or developed has had a stylesheet that large. Facebook? Twitter? GitHub? 100k+ compressed stylesheets. Hell, even if your site is small-to-medium sized but very design-intensive, I could see you reaching that mark.

Don't worry, I'm sure all those developers are "doing it wrong" too.

Well did you check the stylesheet of Twitter for instance? Only 40K but even then.. why even that big for a simple Twitter homepage!? So I'm sorry you did not convince me. And maybe, I know it's a bold statement, they are doing it wrong.

I think it also has to do with frameworks. Sometimes frameworks spit out a lot of HTML you won't ever need. So the HTML is bloated in the first place. Then it's a hell of a job to style the mess.

When you are fortunate to control the HTML you should first start to optimize your HTML before you even start with CSS.

Lanyrd is a complex site - we have over 50 different page templates, all of which are styled using that one stylesheet. We get a lot of functionality out of that 100K. Not to mention that CSS compresses extremely well - served with gzip, the entire stylesheet is actually just 19745 bytes.

We use a far-future expires header (and serve from Amazon CloudFront), so browsers should only ever fetch the file once no matter how many pages on the site the user visits.

I think most of you who answered this reply missed the point where CSS is not HTML… ID's should be used when they suit better. The same with classes. You end up constructing semantical html which a) easier to maintain and b) won't mix the design with the content on code-time.
+1 for never styling by IDs, which are global variables and should be used when all else fails.
After many years doing CSS my best workflow has come to this:

    reset.css //for resetting browsers
    grid.css //if I'm using a css framework
    global.css //styles that are shared across the site
    section.css //styles that pertain a specific section. The name of the file varies, i.e. "about.css".
You need a good code editor that allows you to open files without tabbing or reaching for the mouse, I use Textmate's Command T to switch fast among my files.

reset.css There's a bunch around, I use the one from htmlboilerplate.com, but there's many good ones available. (Eric Meyer's). You will almost never touch this file.

grid.css I only use this occasionally, when I'm working on sites where the grid is very clear and I take out all the stuff I'm not going to use. I usually go for a three col version of 960.gs and trim it to about 12 lines of css. Never touch this.

global.css Here you put your nav, your footer, you body styles, etc. I think that separating by colors and typography doesn't make sense, because you usually change a widget's appearance.

section.css I count on the body tag having a classname, so I can have body class="about" and then do...

    .about section.photo {...}
This way you never override your styles accidentally.

Miscellaneous I avoid the one declaration per line convention when I have similar styles and I want to be able to read them in a table format, i.e.

    .available {background-color: #0f0;}
    .taken     {background-color: #00f;}
    .deleted   {background-color: #f00;}
I usually start from the most generic to the more specific, but I don't worry too much about code order because in the end I just do a search and reach it in no time.
A good example of some super organized CSS is in the HTML5 Boilerplate by Paul Irish. Found here: https://github.com/paulirish/html5-boilerplate/blob/master/c... I sometimes use multiple instances of the same selector, especially if a project starts getting very big. I like to separate each function of the site into it's own block after the footer declarations. It lets me stay organized during development and ensures that I can keep track of what I'm working on while I'm working on it. Here's the order I'm currently using, which was inspired by the above:

    /* HTML STRUCTURE STYLES */
    body { foo: bar; }
    h1 { foo: bar; }
    a { foo: bar; }
    /* Image Replacement & Hacks */
    .ir { foo: bar; }
    /* Container Styles */
    #header { foo: bar; }
    #main { foo: bar; }
    #footer { foo: bar; }
    .column { foo: bar; }
    .sidebar { foo: bar; }
    .img-cotainer { foo: bar; }
    /* Everything inside of #header */
    .navigation { foo: bar; }
    #header li.nav { foo: bar; }
    /* Everything inside of #main */
    .content { foo: bar; }
    /* Everything inside of #footer */
    .social { foo: bar; }
    #footer li.nav { foo: bar; }
    /* Everything in specific view inside of a container from above */
    .profile { foo: bar; }
    .comments { foo: bar; }
    /* Media Queries */
    @media all and (orientation:portrait {
      * { foo: bar; }
    }
    /* Print Styles using Media Query */
    @media print {
      * { foo: bar; }
    }
For me the biggest goal is fewer lines to organize in the first place rather than any particular scheme for grouping. What I do is:

1) Use as few separate stylesheets site-wide as possible so any contradicting or repetitive rules will be obvious.

2) Use one line per rule so I can scan the selectors quickly, then scroll horizontally if necessary

3) I prefer complex comma-separated selectors which set one or two properties to simple selectors which set many properties. Grouping in this way gets me closer to having constants, e.g. a specific hex color won't be rewritten again and again, it will just follow a complex selector list.

4) Once a selector works, I try to make it more general, e.g. "div.info { font-size: 12px }" can probably just be ".info { font-size: 12px }". More general rules will apply in more cases, so fewer overall rules will be necessary.

2) Use one line per rule so I can scan the selectors quickly, then scroll horizontally if necessary

I'm going to finally start turning off text wrap. You've opened my eyes to this. Thanks for sharing.

On an MVC site, I organize by controller. There's one general file for generic cross-site stuff (header/footer, etc.), supplemented by another CSS file that shares the markup for all controller-specific pages.

This gives a max of two css files per page. For the landing page I compress the generic file along with the controller-specific css file for the default page into a single file. This speeds up the loading process while preventing too much bloat. Since the other pages are usually hit after the landing page they require only a single extra download. Any reset code can be included in there as well, although maintained as a separate file.

I doubt this approach is ideal when it comes to organizing things, but it's fairly fast when it comes to development. I design by including css in style="" and then refactoring the markup into classes once the design is complete. Saves a lot of back and forth while getting things lined up.

I also organize styles by controller/action in my Rails projects. This trick from "The Rails 3 Way" is great for assigning the correct classes to the page:

Using Haml:

  %body(class="#{controller.controller_name} #{controller.action_name}")
Using Erb:

  <body class ='<%= "#{controller.controller_name} #{controller.action_name}"%>'>
I've really enjoyed SASS/SCSS optionally with Compass. It lets you compile the stylesheets while still keeping the source files separate and organized. I've also seen the approach with one big file for the application with commented sections, however, the drawback to that approach is using a version control system with multiple editors on a large file (merge conflicts, etc).
Start by using sass reset.sass 960gs.sass default.sass In default @include reset and 960gs (sass compiles it all into one css file)

Then use a per page sass file that references default.sass

If you want something pre-built that does all this use compass.

At some point, the amount of CSS complexity becomes best handled by a preprocessor.

Stylus is great: http://learnboost.github.com/stylus/

I made a post about it, and personally prefer it to Sass and Less: http://nylira.com/stylus-the-revolutionary-successor-to-css/ The hardcore abbreviation mixins in my post seem to offend some coders. When you work in CSS and HTML hours every day though, every character saved adds up to a huge productivity boost.

My current project has 30 directories with 73 partial Sass files, which compile down to one 320kb file.

As to your question, I organize my partials based on controller and url structure.

My current project has 30 directories with 73 partial Sass files, which compile down to one 320kb file.

Isn't that a lot to download? That's like 2 seconds on average to download that file in the U.S., and probably in the 10 seconds or higher range for a lot of folks. I guess if the download is delayed to after some kind of engagement (sign up, etc) it's not a big deal?

Is 320K of CSS really necessary? (legitimately asking)

320K is a lot, no question. This project hasn't been released to public yet, and there are areas to optimize.

Keep in mind that this only 42k gzipped.

IMHO, it's not.

I'm working on a few relatively complex web apps where the CSS download time don't come to anywhere near that size. In my world (mobile devices, in particular) 320k would be totally unacceptable. 100k is about the point where I start re-evaluating my design.

I just use Blueprint.
Lots of comments really help, especially when you look at it months after.
Suprised no-one has mentioned Nicole Sullivan's (amongst others) Object Oriented CSS (OOCSS) project: https://github.com/stubbornella/oocss/wiki

She used this approach at Facebook (and Yahoo, I think?) to successfully tidy up a huge code base of thousands of CSS files down to a more manageable few.

I attended her workshop at Webstock and since then had a chance to put it into practice on a 'get it up quick' green fields project (http://chchneeds.org.nz). I must say I was really pleasantly surprised at the way this approach just avoids a lot of the pain points, as a web developer/coder (ie not an html/css guru) I so often face when just getting the simplest things to 'work'.

I guess the hardest thing for me to get my head around to was that to make things more modular you had to let go (a tiny bit) of being so religious about 'semantic html' as a requirement for the HTML, but I think its worth it to get your CSS a whole lot more modular and 'pluggable' together.

Still a bit more work to do, IMHO, but I'm definitely going to be monitoring this project closely.

Nicole Sullivan's site: http://www.stubbornella.org/content/

I'm really interested in the OOCSS approach, it's efficient, maintainable and modular, and although it's not perfectly semantic the trade-off is minimal. I first discovered it from the Velocity 2009 conference, and Nicole Sullivan's talk from Web Directions North - http://goo.gl/yLkby
I once tried breaking my css into files according to function (typography.css, color.css, layout.css). It ended up being a royal pain because when I added a new HTML element and I went to style it, I ended up having to duplicate the css selector for that element in three files. I also was constantly switching among the three files to work with one element's styles. So whatever you do, don't organize by function. :)
Ever since using Drupal's Zen theme I have preferred their basic setup for grouping CSS files. Here is a rough example:

html-reset.css layout-fixed.css page-backgrounds.css messages.css pages.css blocks.css navigation.css comments.css forms.css fields.css print.css ie.css ie6.css

Drupal's CSS optimization, once turned on, will roll all of these up for you automatically, so if you aren't using Drupal you will need some sort of build system to combine and minimize everything. But I think this is a good start.

On a side note, I really like the method the Zen theme uses for CSS columns. Worth checking that out as well.