design and development for the web

Organizing CSS Files

Every designer has their own way of formatting and organizing style sheets. Let's take a look at a few different methods. Technically, there is no correct solution. But, depending on the project at hand, you may decide to choose one method over another.

A Single Stylesheet For Everything

Loading in a single style sheet is a great way to keep your styles separate from the rest of your markup. This is how I used to organize things. Including a "global.css" file is easy, and simple. No matter what, you know where your styles are. Linking to them is easy enough with a single link tag in the head of the document.

  2. <link rel='stylesheet' type='text/css' href='global.css' media='all' />

This is fine for very simple projects that don't need a lot of flexibility, or maintenance. What if you want to handle multiple forms of media? You could specify media types within your global.css file, but it gets a little difficult to manage all these styles in a single document. Here is how it would look:

  2. @media screen {
  3. body {
  4. font-size: 80%;
  5. font-family: sans-serif;
  6. }
  7. }
  9. @media print {
  10. body {
  11. font-family: serif;
  12. }
  13. }
  15. @media handheld {
  16. body {
  17. font-family: sans-serif;
  18. }
  19. }

(Take a look at the media rule for CSS2)

This approach might be acceptable for smaller sites, but when you're developing large-scale sites and web applications, you need more flexibility. With one file, it's very easy to get in over your head with maintenance issues. To help split things up, you could set up your global.css file like this:

  2. /* =screen css */
  3. @media screen {
  4. @import('screen/color.css');
  5. @import('screen/typography.css');
  6. @import('screen/layout.css');
  7. }
  9. /* =print css */
  10. @media print {
  11. @import('print/color.css');
  12. @import('print/typography.css');
  13. @import('print/layout.css');
  14. }
  16. /* =handheld css */
  17. @media handheld {
  18. @import('handheld/color.css');
  19. @import('handheld/typography.css');
  20. @import('handheld/layout.css');
  21. }

This is a drastic example, but essentially, you could handle all your css files outside of the markup in this manor. There is one crucial problem with this approach: browser compatibility.

Avoiding CSS Hacks

Adhering to Web Standards is vital to the longevity and stability of web interfaces. Browser Compatibility is a day to day struggle for every designer. With a single css file for all styles of all browsers, we are forced to write improper markup to exploit strange browser behaviors that are considered glitches. Supporting CSS hacks does nothing more than support the strange behaviors, which in turn, makes coding for the future more difficult.

Conditional Comments for Explorer

Thankfully, a certain company (who's initials are "Microsoft") gave us a solution. It's not pretty, but at least we can code for the future without worrying too much about the past. Using conditional comments, we can set up separate sets of styles for all versions of Internet Explorer. The only issue is that these conditional comments will only work in the markup. So, in order to sustain our "valid" markup, we must maintain a separate set of styles within comment lines in the markup.

Well... there goes our "one file" approach:

  2. <link rel='stylesheet' type='text/css' href='/css/global.css' media='all' />
  3. <!--[if IE 6]>
  4. <link rel='stylesheet' type='text/css' href='/css/ie6.css' media='all' />
  5. < ![endif]-->
  6. <!--[if IE 7]>
  7. <link rel='stylesheet' type='text/css' href='/css/ie7.css' media='all' />
  8. < ![endif]-->

Another Approach: one file for each type of media

  2. <link rel="stylesheet" type="text/css" href="screen.css" media="screen" />
  3. <link rel="stylesheet" type="text/css" href="print.css" media="print" />
  4. <link rel="stylesheet" type="text/css" href="handheld.css" media="handheld" />
  5. <!--[if IE 6]>
  6. <link rel='stylesheet' type='text/css' href='/css/ie6.css' media='all' />< ![endif]-->
  7. <!--[if IE 7]>
  8. <link rel='stylesheet' type='text/css' href='/css/ie7.css' media='all' />< ![endif]-->

Backward Compatibility

There are a number of advantages to separating your css in this way. The most obvious advantage is that of being more friendly to Netscape Navigator 4. NN4 does not support the @import tag. I, for one, practically never consider Netscape Navigator 4 as worthy of even a second thought, but it just depends on the project. Maybe your primary market is "Men and women in their late 50's, early 60's." How likely is it, that such a market may have bought their home computer in the last 10 years? I don't have any actual figures in front of me, but I do have parents. My personal answer: it's probably not as likely as you'd think. Some folks still browse the web on their old Macintosh LC 575 from 1994 running Mac OS 7.6.1.

More Flexible and Dynamic with Web Applications

If you're like me, you're probably building some amazing web application that handles spitting out the markup for your interfaces. I especially like this approach because, now I can let my web application decide which media formats are compatible. By separating the calls for each form of media, you give the developers more control over the interface. This allows the presentation of your web application to be more dynamic, depending on the user-agent.

But, to many CSS connoisseurs, like myself, even this can be very tedious and difficult to maintain. Let's stop kidding around and find something that _works_. When you're in the web application business, there are many times when you want to keep the basic layout of a site, but you only want to change the colors and the background images.

Layout.css, Color.css, Typography.css, and Normalize.css

This was about the time that I started reading a great book called "Transcending CSS: The Fine Art of Web Design." In it, Andy Clarke describes a method of organizing your CSS files which I've taken to heart because it gives me so much flexibility. Of course, I made my own adjustments to the idea, which I'd like to share with you.

First off... you should only link in one css file for every supported media type. From this one css file, you can import as many other css files as you want, as long as you use the @import(filename.css); command before any of your other css declarations. The idea is to keep your imports at the top of the file so that they take less precedence than the other declarations in the file. Remember, CSS is linear. So, the last line of CSS is the last declaration to be executed (and it will happily overwrite other declarations that are equally or less specific).

So, let's start by making a screen.css file for the media type of "screen". This one will be used for all your computer monitors, flat panels, etc. from screen.css, you might have some import declarations like this:

  2. @import("normalize.css");
  3. @import("typography.css");
  4. @import("color.css");
  5. @import("layout.css");

So... what goes where?

Okay, this is the fun part. I've had many a debate on this. Even if you can get this far with a fellow designer... inevitably, you're going to have to throw down the gloves and have it out. Here are some general rules:

Layout gets anything dealing with the "layout" of the page. So, this means that width, height, floats, positioning, margins, padding, display, and even (maybe you disagree about these) list-styles, borders (I do short hand border statements because it's simpler, so I'll throw border colors into layout.css. I know, I'm terrible, but that's me.)
Normalize is a handy little css file that you can use and re-use between all your sites. Admittedly, it's something else I picked up from Andy's book: Transcending CSS. It's basically an attempt to zero out as much of the default styles that most browsers apply. You can take a look at my normalize.css file here. The book doesn't describe placing these declarations in a separate file. The declarations rarely change, and I'm always happy to reuse code.
Color gets anything using a color. So, color, background, any subset of background like background-image, background-repeat, etc...
Typography gets anything to do with text. This one is also rather controversial. Take text-align. Many people might consider this to be a lot like vertical-align. But, that all depends on the browser. According to web standards, text-align should NOT effect block-level elements. However, if anyone has ever tried to center a block level element on a page in IE6, you know that the parent element MUST have text-align set to center. Otherwise, your { width: 50%; margin: 0 auto; } won't be centered. This goes against the grain. So, despite it's similarities to vertical-align, they are separate. vertical-align goes in layout. text-align goes in typography.

What about images and other files?

A lot of people worry about having multiple image directories. Here's my approach. Keep your images directory, but don't put your css images in there. Use the images directory for media files that pertain to the content. This goes back to the whole idea of separating the content (and structure) from the presentation. So, anything dealing with the presentation of the content should not be part of the content. This includes your background images applied by css.

So, keep a css directory right next to your images directory. House all your css files in that directory right along with all your background images. This way you don't have to have long and convoluted background url paths when dealing with your color.css file. You won't need a directory path declaration at all if the css file is in the same directory as the image file.

And of course your content images are tucked away in a safer, more "permanent" location for that day when you get bored with your current design and decide to make a new one.

A friendly reminder: there's no correct answer.

I'd like to point out that there is no "wrong" way to organize CSS files. The requirements of any particular project will greatly effect your method of organization.


Recommended Materials