CSS tips and tricks, Part 2

This is the followup to last week's post, CSS tips and tricks, Part 1, where you can find tips on shorthand, default values, colours, inheritance, cascading, and more.

In this part I'll be giving you some tips on grouping selectors, clearing floats, horizontal centring, importing CSS, and a couple of troubleshooting tips. If you think something is missing, check part one in case it's been covered there.

Group selectors

When several element types, classes, or id:s share some properties, you can group the selectors to avoid specifying the same properties several times. This will save space -- potentially lots of it. Whether you put each selector on the same line or separate them with a line break is mostly a matter of personal taste.

So, to specify the font family, colour, and margins for all heading elements, you can do the following:

  1. h1,h2,h3,h4,h5,h6 {
  2. font-family:"Lucida Grande",Lucida,Arial,Helvetica,sans-serif;
  3. color:#333;
  4. margin:1em 0;
  5. }

Compared to setting the properties individually for each element type this saves a great deal of space. The savings are obviously greater the more properties that are the same.

You can then separately specify any properties that are different for some of those elements, for example font-size:

  1. h1 { font-size:2em; }
  2. h2 { font-size:1.6em; }

Specify link styles in the right order

When applying CSS to the different states of a link you need to think about the order of the rules. In most cases you'll want to specify them in the order :link :visited :hover :active. Take the initial letter for each state and you get "LVHA", which can be expanded to "LoVe HAte" or something else that is easy to remember. The order is affected by specificity, and is explained well by Eric Meyer in Link Specificity.

You may also want to think about specifying the :focus state to make it easier for those who navigate with the keyboard to see which link is currently selected. Where you place the :focus rule depends on what you want to happen. If you want elements that have focus to display the :hover effect you have specified, place it before :hover. If you want the :focus effect to override the :hover effect, place it after : hover.

Clearing floats

A very common CSS problem is how to handle the situation that occurs when you have a floated object in a container and do not want that object to stick out of the bottom of the container. A typical example is floating a tall image within the main body text. If there is not enough text to cover the entire height of the image, the image will extend out of the box it is in. Sometimes that is what you actually want, sometimes it isn't.

The traditional way of controlling this has been to add an extra element, either a div or a br element, inside the element that you want to contain any floated descendants and style it to clear:both. Adding extra markup is a bit ugly, but luckily there is a method that eliminates the need for that: How To Clear Floats Without Structural Markup.

Both of these methods work very well unless you have a layout that involves floats that appear earlier in the markup than the object you actually want to clear. That's where a trick that hasn't been widely known until recently looks like it will come in very handy for controlling floats within page content: using the overflow property, originally described in Simple Clearing of Floats. The method is also analysed and discussed in Clearance and Super simple clearing floats, among other places.

Which of these clearing methods to use depends on the circumstances. Read up on them, experiment, then decide.

I'm not going into the details of floating here. A few excellent articles that explain how floats work are Floatutorial, Containing Floats, and Float Layouts.

Centring (centering)

A simple trick, but worth repeating since this is something I see many CSS beginners having problems with. To horizontally centre an element with CSS, you need to specify the element's width and horizontal margins. If your entire layout is wrapped in a container like this:

  1. <div id="wrap">
  2. <!-- Your layout goes here -->
  3. </div>

you can centre it horizontally by using the following CSS:

  1. #wrap {
  2. width:760px; /* Change this to the width of your layout */
  3. margin:0 auto;
  4. }

The width of #wrap is subtracted from the available window width and the difference is equally split between the left and right margins. The width doesn't have to be fixed -- you can use any unit you like for the width.

IE5/Win does not understand this, but it has a useful bug that makes it apply the text-align property to block level elements. If you need the layout to be centred in that browser, use this CSS instead of the above:

  1. body {
  2. text-align:center;
  3. }
  4. #wrap {
  5. width:760px; /* Change this to the width of your layout */
  6. margin:0 auto;
  7. text-align:left;
  8. }

The first rule makes IE5/Win centre everything in the body element. Other browsers will centre just the text, and since the text-align property is inherited, all text in the document will be centred. You rarely want that, so the next rule overrides that by left aligning all text withing the #wrap element.

Obviously this technique can be used to horizontally centre any block level element within another.

Oh, if IE5/Win support is not required, you don't need the #wrap element for centring the layout. You can style the body element instead. Just be aware that it doesn't work in IE5/Win.

Importing and hiding CSS

A common way of hiding CSS files from old browsers is to use the @import trick. However, the way I see it used most often does not hide the CSS from Internet Explorer 4:

  1. @import url("main.css");

This had me scratching my head for a while. I'd read somewhere that using @import would hide the CSS from the old browsers, but when I checked the result in IE4 it imported the CSS file, with horrible results. Instead, I use the following syntax for @import:

  1. @import "main.css";

That stops Internet Explorer 4 from importing the file. As an extra bonus, it saves a couple of bytes. For an overview of how the syntax used in the @import rule will affect which browsers will import the stylesheet, see centricle's css filter chart.

Giving Internet Explorer what it needs

Sometimes (read: most of the time) you need to send different rules to Internet Explorer to work around bugs in its, shall we say, less-than-perfect CSS implementation.

There are many CSS hacks that do this, but I tend to use just a couple of them, and only when I can't find a better, hack-free way to accomplish what I want. With Microsoft's recent announcement of an upcoming beta release of IE7 for Windows, which may or may not include better support for CSS, and may or may not change the way CSS hacks work, I think the safest way of taking care of IE/Win is to use conditional comments -- more on that below.

To hide a rule from IE, you can use a child selector:

  1. html>body p {
  2. /* declarations */
  3. }

The star html hack will hide a rule from all browsers but IE:

  1. * html p {
  2. /* declarations */
  3. }

Sometimes you want to feed some CSS to IE/Win but not IE/Mac. To do this you can use the commented backslash hack:

  1. /* \*/
  2. * html p {
  3. declarations
  4. }
  5. /* */

Another option -- and I tend to use this more and more since it feels more future-proof than CSS hacks -- is to use Microsoft's proprietary conditional comments. You can use this to give IE/Win a separate stylesheet that contains all the rules that are needed to make it behave properly. I think it's a good way of keeping the hacks and noise out of the main CSS file. You also avoid invalidating the "real" CSS file with proprietary IE extensions to CSS, like expressions, that are sometimes needed.

  1. <!--[if IE]>
  2. <link rel="stylesheet" type="text/css" href="ie.css" />
  3. <![endif]-->

This has the additional benefit of preventing the Flash of Unstyled Content which can occur in IE/Win if there are no link or script elements in the document's head element.

How big is that box?

When something goes wrong, start by validating your CSS. Anybody can make a typo.

If there are no errors in the CSS you need to start analysing what's going on. I like applying background colours to the elements I'm having trouble with to clearly see the space they occupy. Some people suggest using borders, which is fine in many cases. The problem with that approach is that borders will increase an element's dimensions, and top and bottom borders will prevent vertical margins from collapsing. Background colours are generally safer.

Another potential troubleshooting property is outline. Outlines look like borders, but don't affect the dimensions or positioning of the element they are applied to or that of any other elements. The downside is that very few browsers currently support the outline property -- as far as I know it's only supported by Safari, OmniWeb, and Opera.

CSS coding style

There are many different approaches to the use of indenting, line breaks and whitespace when writing CSS. I've been going a bit back-and-forth on that, but I I've settled for the following coding style (for now, anyway):

  1. selector1,
  2. selector2 {
  3. property:value;
  4. }

When I combine selectors, I normally put them on separate lines. I find it easier to find things in the CSS file that way. Next, I leave a space between the end of the last selector and the opening brace. Each declaration goes on a separate line, with no indentation and no spaces around the colons separating properties from values.

I always end each declaration with a semicolon. Doing so isn't necessary for the last declaration in a rule, but it's really easy to forget adding a semicolon before adding a declaration, and that will introduce hard-to-find problems in your CSS.

Finally, the closing brace goes on a line of its own.

Yes, whitespace can be good for readability, but I like to keep it as minimal as possible without negatively affecting readability too much.

Of course, there are exceptions to these rules, and I'm not always fully consistent with my CSS formatting. We all have room for improvement, and I'm working on it, OK.

There's more where that came from

In these two articles I've covered some of the tricks I use when writing and troubleshooting CSS. There are more, so who knows, maybe there will be a part 3 some day. Did I leave out something important, like your favourite tip or trick? Let me know.


This article has been translated into the following languages:

Posted on March 21, 2005 in CSS