
This article—the second of two—covers horizontal sizing and shows
how to determine the width of elements with
CSS. The first article covers vertical sizing. Once youve mastered both height and width, you
should be well on your way to effectively using
CSS.
Width
Here we will consider the width of an element, which is part of whats called horizontal formatting. You may think that paragraphs are always as wide as they can be — as wide as the browser window or the table cell in which they are contained, and generally, youd be right. But how does this happen? CSS describes it all in detail, and knowing those details is very important.
CSS makes it look very simple, of course. For example, lets say you want an image to be 300 pixels wide. Youd probably think to write: IMG {width: 300px;}
Again, youd be right. However, what if you want a heading to be 20 ems wide? The first reaction is to say: H1 {width: 20em;}
It looks good, but you arent really setting the width of the whole element. What youre doing is setting the width of the content area — that is, the actual box which bounds the content. Padding, borders, and margins will be added to that, and thus can potentially make the box wider than 20ems.
In fact, the horizontal space of a regular, non-positioned element is always as wide as its parents width, no matter what it looks like. Heres the formula to determine how much horizontal space an element will actually occupy:
margin-left + border-width-left + padding-left + width +
padding-right + border-width-right + margin-right
So lets say you have a paragraph which has to be exactly 250 pixels wide, in order, for instance, to align it with an image. Youre putting in a light blue background color, so you want to add some padding to keep the text from touching the edges of the background. You decide that 15 pixels of padding would be fine. Again, you want the background to line up with the image and be exactly 250 pixels wide, so you write:
P.sidebar {padding-left: 15px; padding-right: 15px;
margin-left: 0; margin-right: 0;
border-width-left: 0; border-width-right: 0;
width: 220px; background: #99FFFF;
}

Thats right, the value of width is actually 220 pixels, because you have 15 pixels of padding to the right and left. Thus 220 + 15 + 15 = 250 gets you the result you want. If you change the amount of padding, then youll have to adjust your width value:
P.sidebar {padding-left: 10px; padding-right: 10px;
margin-left: 0; margin-right: 0;
border-width-left: 0; border-width-right: 0;
width: 230px;
}
You might think that the whole sum total of the elements width is now 250 pixels. Actually, thats not the case. Remember that the sum of the seven properties must always add up to the same value as the width of the parent element. In order to accomplish this, some values are overridden, although which ones depends on the context.
Given the previous example, lets assume the sidebar paragraph is found in a table cell which is 300 pixels wide, and which is left-justified (text-align: left;). The seven properties must add up to 300px, no matter what the author writes. Because the padding and width have been explicitly set, and the table cell is left-justified, the browser automatically overrides the right margin to make up the difference. Thus, the result is as if you had written:
P.sidebar {padding-left: 10px; padding-right: 10px;
margin-left: 0; margin-right: 50px;
border-width-left: 0; border-width-right: 0;
width: 230px;
}
If the table cell had been right-justified, then the browser would have set the left margin to be 50px; and had the cell been center-aligned, then the left and right margins would be set to equal values (in this case, 25px each).
On the other hand, lets say that we want to have an element in the 300-pixel table cell which is 280 pixels wide, and centered. There are a number of ways to go about this, but the easiest one is:
P.callout {padding-left: 10px; padding-right: 10px;
margin-left: 10px; margin-right: 10px;
border-width: 0;
width: auto; background: #FFCC99;
}

By setting the width to auto, were saying make this value whatever it needs to be. This is actually the default value for width, so we could have just left out the width statement entirely.
Assuming a non-positioned text element like a paragraph or a DIV, browsers will choose to override either the width, or one of the margins. The method of making these choices is outlined in the following table.
| Condition |
Overridden Property |
none of the properties margin-left, margin-right, and width is set to auto |
margin-right in left-to-right languages;
margin-left in right-to-left languages |
exactly one of the properties margin-left, margin-right, or width is set to auto |
the property set to auto |
width is set to auto, and one or both of margin-left and margin-right is also set to auto |
any margins set to auto are set to zero |
width is not set to auto, and both of margin-left and margin-right are set to auto |
the margins are set to equal amounts (thus visually centering the element) |
Padding and borders cannot be set to auto, and so cannot be overridden by the browser.
Extra-Wide Elements
Since the seven properties must add up to the width of the parent element, what happens if they add up to more than that amount? Returning to our 300-pixel table cell, lets assume we have the following paragraph within it:
P.wide {padding-left: 10px; padding-right: 10px;
margin-left: 10px; margin-right: 10px;
border-width: 0;
width: 290px; background: #FF99CC;
}

So now we have an element which is (10 + 10 + 10 + 10 + 290) 330px wide. Since both margins and the width have all been explicitly set, the browser overrides the value of margin-right and sets it to -20px. The seven properties now add up to 300 pixels, and all is well. However, this does mean that visually, the wide element will be wider than its parent. While intuitively this does not make sense, it is permitted under CSS.
The one place where Macintosh browsers usually err is when the element is contained within a table. In this case, the table cell is usually made larger to accommodate the margins, instead of reducing the right (or left) margin as shown in this section. However, when not within tables, then behavior is usually as expected. So if you have a paragraph that is too wide to fit inside a DIV, for example, then the automatic negative-margin behavior should kick in. Another way to get this negative-margin behavior is to explicitly set a negative margin yourself, which tends to work even inside tables.
Inline Elements
The property width is not permitted on inline text elements. If left or right margins are set, then they are applied to the very beginning or end (respectively) of the element, even if it breaks across multiple lines. Thus, a left margin will cause a visual offset just before the beginning of the element, appearing to push it to the left. Similarly, a right margin will create blank space after the end of the element, appearing to push any following text to the left.
Images
Since images have an intrinsic width, the value auto is always replaced with the intrinsic width of the image, and the width can never be overridden by the browser. The author can change the displayed width of an image by assigning an explicit value, thus scaling the image.
More Information
|