away-with-widths

The css width property is probably one of the easiest to learn to css newcomers. Apart from some box model issues, it works as intended, has a simple syntax and most importantly, is needed right away. You don't get far without widths, which makes them the perfect target for abuse. And abused they are. This article explains why using as little widths as possible helps to maintain a flexible layout and might save you (or some fellow csser) a lot of time in the future.

what's a width

A css width states the horizontal length of a box, that's about all there is to it. It works on all but inline elements, no matter how they are positioned or whether they are floated or not. Widths work.

The only real difficulty concerning the basic use of width is that paddings, margins and borders are not included in the stated width. This means that the actual width of a box is bigger if any of these properties are defined. This confuses many people at first, to the point where they are actually introducing a css switch, allowing you to toggle between the two ideologies (css width including or excluding paddings/margins/borders).

The css switch isn't supported anywhere yet, still it is possible to see the all-included method in action. Just set quirks-mode in ie6 and marvel at the different implementation of the css width property.

what's wrong with widths

You might be wondering how such a simple property can be abused, yet the answer is quite simple. From time to time my job consists of widening a site. Usually older sites that were at one point optimized for an 800x600 res and now need to be changed to work on a 1024*768 res. While this could be an extremely simple task, more often than not I find myself cursing over a calculator while adapting widths for an unhealthy number of elements.

/* using widths */ .outer {width:960px;} .inner {width:936px; margin:0 auto;} /* using widths (variation) */ .inner {width:936px; margin-left:12px;} /* using margins (or paddings) */ .inner {margin:0em 12px;}

The problem of the width property is that its function is not really clear to everyone. Widths are for reserving space, not for spacing. The difference might seem small and negligible, but it really isn't. If, for example, you have a site of 960px wide and you want the header to be 12px removed from both sides, there are two ways of going about it. The snippets above will do exactly the same, the difference is that for the first example we used widths to take care of the spacing, the second example used the proper css properties intended to take care of spacing.

Problems arise when the width on the .outer element is changed. Since the .inner width has a separate width declared on it, it will not take up the newly created space when the outer width is enlarged, nor will it shrink when the outer width is made smaller. What you have just created is an inflexible layout that doesn't adapt if you change the base width. In some cases this is actually the desired effect, in most cases it's just bad coding.

You might find this example silly, but you'd be surprised how many people work like this. So let's run through some methods trying to avoid the use of (unnecessary) widths.

away with widths

Below is a small selection of techniques that will help you reduce the use of widths in your css

width:100%

.outer {...} .inner {float:left; width:100%;}

If you explicitly want to give an inner element the same width as the outer element (which is the default behavior, unless you're working with floats and pos:abs), use width:100%. This way, you are still using the width property, but at least it will automatically adapt when the width on the outer container changes.

pos:abs

.outer {...} .inner {position:absolute; left:0; right:0;}

If you want a pos:abs element to have the same width as it pos:rel element, simply set both left and right properties to 0, this will stretch the element to a width of 100%. This doesn't work in IE6, but there you can use the width:100% trick instead.

simple paddings and margins

.outer {...} .inner {padding-right:50px;}

Need to leave room for an rss icon to the right of your title? Use a padding (or margin) to make sure the text doesn't overlap the icon. Don't make the width of the heading 50px smaller, it will only cause you more work.

columns 1

.outer {...} .innerLeft {float:left; width:100px;} .innerRight {margin-left:110px;}

For simple column structures, float the first column and give it a width. For the second column, simply pass the floated column by using a margin-left. You can do the same for right floated elements (only using a margin-right). The upside here is that the second column will take up all remaining space, relieving you of the task to calculate the remaining width. You will have to remember to change the margin on the second column in proportion to the width of the first column, but that should be easy enough.

columns 2

.outer {padding-left:100px;} .innerLeft {float:left; margin-left:-100px; width:100px;} .innerRight {float:right; width:100%;}

The second way to go about columns is using a combination of .outer paddings, floats and negative margins. Again, you can create a structure by only defining one width, with the other column filling in the remaining space. More detailed info can be found on the Social Geek blog.

result

The result of using all these methods is that you can effectively widen your side by adapting one single value in your css, namely the width defined on you main container. You can actually try it on this blog. Changing the width on the #allContainer will make the whole site wider without creating gaps. It's a little more work if you want the grids to grow proportionally, but it's far from any width hell I had to experience a couple of times.

conclusion

Widths are for stating space, and should be used for only that. When an element on your page has a definite width, declare it as such. But when it is simply supposed to fill an existing space, use other methods to position the element. If you want spacing, use margins and paddings, and you will find that the calculator isn't something you should use all that often while working with css. It will save you time, not to mention the next guy who has to adapt the width of the site in the future.

If you can think of more useful methods, links and suggestions are always appreciated!