away-with-widths/use and abuse

published on:
August 05, 2009
comments

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!

Comments

Jethro Larson

comment number
date
August 06, 2009 21:46

Good post. This is definitely a problem I've seen in the inexperienced CSSers. It really is a major problem, right up there with classitis and divitis. Learning what properties to avoid and use sparingly makes a huge difference in code maintainability and agility.

Peter Gasston

comment number
date
August 11, 2009 16:46

The switch you're referring to is the CSS box-sizing property.

IE8 and Opera 7+ support box-sizing natively, and Firefox 1+ and Safari 3+ support it with prefixes (-moz- and -webkit-).

David Thomson

comment number
date
August 12, 2009 02:53

There's a better way of dealing with widths. Think of the Java Swing GUI with it's screen/pane relationships. You float the outer screen and define it's width. Within the inner pane you simply apply margins.

So, .pane_exmp{margin:0} is going to behave like you've stretched your canvass(the pane) over the it's frame(the screen).

This way you can defeat the IE box model issues and get right down to using inline elements against your background because your html/css has a foolproof structure.

Here's an example of two columns.

<div class="container">

<div id="scrn_left">
<div id="pane_left">
</div>
</div>

<div id="scrn_rght">
<div id="pane_rght">
</div>
</div>

</div>

The css would be

.container{float:left;margin:0 auto;width:100px;}
#scrn_left{float:left;width:700px;margin:0;}
#scrn_rght{float:left;width:300px;margin:0;}
#pane_left, #pane_rght{margin:0;min-height:600px;}

Now you've got a foolproof canvass to put your design on.

David Thomson

comment number
date
August 12, 2009 02:56

Heh. You might want to fix your form validation routies...

Niels Matthijs

comment number
date
August 12, 2009 16:52

Peter: thanks for the link and extra info :)

David: well, that method is actually what this article is contesting. Since the width of both inner columns equals the width of the container, you create a dependency which kills flexibility if you enlarge the size of the container.

Paul Bartlett

comment number
date
September 02, 2009 22:47

And this whole nightmare needs to go away - and it is. The only "reason" for flexible layouts was to provide a good readable layout if a FEW people want to enlarge it for easier reading, or a larger monitor size.

That concept has always been stupid. Newspapers, books, catalogs, letters, magazines, tvs, movie screens, ALL present a fixed format media and it works. A designer builds to a fixed size, and the viewer enlarges the image as necessary by holding the media closer, or buying a bigger TV, etc. Designers should never have been asked to build a design that "inflates" to make up for a lack of the media player's ability to zoom.

Designers spend a lot of money and lot of years learning how to build functional, attractive layouts in many fixed size situations. Expecting them to add in all of this extra coding junk to adapt to a media has always been silly, and needs to go.

This "zoom" function is what has been needed all along and it's coming to browsers now. Thank goodness. Goodbye "agility", and hello again to skilled, attractive layouts.

Niels Matthijs

comment number
date
September 07, 2009 23:22

ALL present a fixed format media and it works.

Because they are all confined to paper. It's not as if they had a real option. Visual zoom is certainly an interesting development though it doesn't fix everything.

Tom

comment number
date
September 16, 2009 15:58

I agree with your article, Niels. Sounds like using   for more space. :-D

@6 - Interesting point, I think I can agree with that.

My thoughts about this:

I think nobody would want websites to stretch wide across the screen - it's simply not the way people read (irrespective of the media type), is it? Of course I can speak only for myself here but I wouldn't want to view a page full of text in fullscreen on my 1920 x 1280px screen.

Also, sometimes I have the feeling that for big resolutions in some cases, browsers would need to REARRANGE (not only resize) a website's elements.

Btw, is there a popular (used by many people) website (or more) with a flexible layout?

Niels Matthijs

comment number
date
September 17, 2009 14:34

amazon.com, gloabl webshop #1 :)

Paul Bartlett

comment number
date
February 13, 2011 01:55

"because they are all confined to paper"

No, many of them are NOT paper based. Television, movies, billboards, traffic signs, etc., are not fixed in size and format due just to materials, but also due to the end user's viewing needs. It has been pretty well determined what colors, layouts, typography, photography, video standards and such work best.

Computer monitors are NO different from television monitors when it comes to user needs. No one likes to read 6 pt. type from a foot away, and no one enjoys reading red text on a black background. These standards, along with line breaks/justification, and image standards are the important little secrets that make ANY visual communication pleasant and useful to interact with.

At no point is it benefit to rearrange a professional designers' skilled work simply because the technology allows you to - which is what has happened with CSS and web 2.0. Pages look clean and organized, but they also lose an emotional interest and impact that comes with a great graphic design.

There IS a valid (though still inferior) reason for flexible layouts, and that would be the recent proliferation of tablets like the iPad, where vertical and horizontal orientation needs may vary depending on the app or task being performed.

Fun discussion, thanks.

* required fields

Leave your data
Leave a comment