Top CSS Tips

I thought I'd share some of my habits when it comes to doing CSS work and let me warn you, some of what I have to say is probably a little controversial. But what's life without living it on the edge. (Yeah, I live an exciting life when CSS is considered 'the edge'.)

px for font sizes

Sacrilege, I know. There are perfectly good ways to get consistent font sizing and I really should use them but Internet Explorer is the only browser that I can think of that doesn't resize text. If the majority of your audience uses IE, then be nice to them and don't use pixels. Otherwise, I figure with IE7 supporting it, pixels are the new ems.

When using pixel sizes, I also get to be sparing in my usage. I specify it on the body and any headers that need it. Inheritance is less of an issue (how many sites have you seen list items inexplicably smaller than the rest of the content like it was less important).

CSS declarations on one line

I've always put my entire declaration on one line. Here's an example to explain what I mean:

h2 {font-size:18px; border:1px solid blue; color:#000; background-color:#FFF;}

h2 {
border:1px solid blue;

The second one may look prettier but it sure doesn't help me find anything. When looking for something in a style sheet, the most important thing is the ruleset (that's the part before the { and } ). I'm looking for an element, an id or a class. Having everything on one line makes scanning the document much quicker as you simply see more on a page. Once I've found the ruleset I was looking for, find the property I want is usually straightforward enough as there are rarely that many.

Blocking the Styles

I break down my style sheet into three separate blocks. The first is straight element declarations. Change the body, some links styles, some header styles, reset margins and padding on forms, and so on. This is usually a small block as I only like to redefine what I need to. No global margin and padding reset for me. I clear the body and form and maybe adjust paragraph if the design really needs it. Otherwise, let the browser handle it. I find the more you try to override what the browser does, the more styles you have to put in, which simply adds to the time to track down bugs and maintain the code.

After element declarations, I have my class declarations; things like classes for an error message or a callout would go hear. I usually only have a couple of these.

Finally, the meat. I start by declaring my main containers and then any styles for elements within those containers are indented. At a quick glance, I can see how my page is broken down and makes it easier to know where to look for things. I'll also declare containers even if they don't have any rules.

#content {float:left;}
#content p { ... }

#sidebar {float:left;}
#sidebar p { ... }

#footer {clear:both;}
#sidebar p { ... }

Browser Support

Support only the latest browsers. That means dropping support for IE5 and IE5.5. Lots of time and effort to be saved here. No box model hacks needed for IE6. In fact, in supporting just the most recent versions of browsers, I end up using very few hacks. Along with using very few hacks means I can avoid shovelling different style sheets to separate browsers. I have one sheet, and that's it. Any hacks I do use are normally commented as such. Similar to the use of pixel measurements, you have to consider your audience before dropping browser support.

The biggest thing for me is still triggering hasLayout in IE to do float containment and I've been using zoom:1 for that. I like it because it's innocuous and shouldn't mess with anything else.

Containing Floats

I just touched on float containment so let's expand on that. My current approach to containing floats is using overflow:hidden (with possibly zoom:1 for Internet Explorer). No clearing div or use of :after. Only worry about containing your floats if you have a background you are trying to set on your container. The overflow should be set on the container.

Keep in mind that the content within the container should be designed to stay within the container. Anything too big and it'll get clipped. Shifting things using negative margins outside the container will also get clipped.

Understand Overflow

Overflow is usually where people get bit by IE. If you've got two floated elements and the content from the left container overflows then, in IE, the container grows and inevitably pushes the right container below it. This is usually a sign that you've messed up your margins, widths, or padding on one of these containers but Firefox (et al) won't reveal this. Using something like overflow:hidden or overflow:scroll on a container can help prevent IE from allowing the content to push the width of the container but you're better off trying to fix the issue in the design.

Allow Block Elements to Fill Their Space Naturally

My rule of thumb is, if I set a width, I don't set margin or padding. Likewise, if I'm setting a margin or padding, I don't set a width. Dealing with the box model can be such a pain, especially if you're dealing with percentages. Therefore, I set the width on the containers and then set margin and padding on the elements within them. Everything usually turns out swimmingly.

Use CSS Shorthand

This might seem like beating a dead horse but I still see people doing really verbose statements where they're setting margin-top, margin-right, margin-bottom and margin-left. My general rule of thumb is, you can use the long form only if you're setting one side. Once you have to set more than one side, it'll take less bytes to use shorthand.

In shorthand, remember that the properties start at the top and work clockwise. margin: top right bottom left; It's also handy to know the shorter forms if you have equal values for top and bottom or left and right.

margin: 5px 10px 20px; /* top left/right bottom */
margin: 10px 20px; /* top/bottom left/right */
margin: 0; /* all sides */

For border, if you only have to set more than one side differently then use two declarations. The first to set all sides, and then a second to change the values for one of the properties.

/* 1px blue border on the left and bottom */
border:1px solid blue; border-width: 0 0 1px 1px;

Avoid Unnecessary Selectors

Just specify the minimum number of selectors necessary for the style. If you find yourself doing ul li {...} or table tr td {...} then you're being more verbose than you need. LI's will inevitably be in UL's (okay, I suppose they could find themselves in OL's, in which case, be more specific for those styles) and a TD will inevitably be in a TR and a TABLE.

Or putting the element name in front of an ID selector (Example: div#navigation). I used to do this because it'd help me "remember" which element the ID is on. As it turns out, I tend to use similar class names from project to project and they inevitably appear on the same elements. I also tend to just do a search to find where something is. So, these days, I just leave it at #navigation.

Using less selectors will mean less selectors will be needed to override any particular style — that means it's easier to troubleshoot.

Keep it Simple

If it hasn't been evident throughout this post, only add when you need to, and that includes hacks. No need to get any more complicated than you need to.

Now, I'd love to hear some of your tips.