The CSS Box Model

At the risk of over-repeating myself: every element in web design is a rectangular box. This was my ah-ha moment that helped me really start to understand CSS-based web design and accomplish the layouts I wanted to accomplish. We've talked about the positioning of these boxes a bit, and about their behavior.

What we haven't talked about much is the box itself. How is the size of the box calculated exactly? Here is a diagram:

 

If you are a Firebug user, you might be used to the diagram like this, which does a nice job of showing you the numbers affecting any box on the page:

Notice in both examples the margin is in the white. Margin is unique in that it doesn't affect the size of the box itself per-say, but it affects other content interacting with the box, and thus an important part of the CSS box model.

The size of the box itself is calculated like this:

Width width + padding-left + padding-right + border-left + border-right
Height height + padding-top + padding-bottom + border-top + border-bottom

What if these values are undeclared?

If padding or borders are undeclared, they are either zero (likely if you are using a css reset) or the browser default value (probably not zero especially on form elements that are commonly not reset).

If the width of a box is undeclared (and the box is a block level element), things get a little weirder. Let's start with that, and then move on to some other good-to-know stuff about the box model.

The Default Width of Block Level Boxes

If you don't declare a width, and the box has static or relative positioning, the width will remain 100% in width and the padding and border will push inwards instead of outward. But if you explicitly set the width of the box to be 100%, the padding will push the box outward as normal.

The lesson here being that the default width of a box isn't really 100% but a less tangible "whatever is left". This is particularly valuable to know, since there are lots of circumstances where it is immensely useful to either set or not set a width.

The biggest ass-biter I always find with this is textarea elements, which very much need their widths set to fight the required "cols" attribute, and are unable to have children elements. So you often need the textarea to be explicitly set to 100%, yet have padding as well, pushing it too large to fit. In a static width environment, we often resort to pixel widths that fit, but no such luck in fluid width environments.

Absolute Boxes with No Width

Absolutely positioned boxes that have no width set on them behave a bit strangely. Their width is only as wide as it needs to be to hold the content. So if the box contains a single word, the box is only as wide as that word renders. If it grows to two words, it'll grow that wide.

This should continue until the box is 100% of the parent's width (the nearest parent with relative positioning, or browser window) and then begin to wrap. It feels natural and normal for boxes to expand vertically to accommodate content, but it just feels strange when it happens horizontally. That strange feeling is warranted, as there are plenty of quirks in how different browsers handle this, not to mention just the fact that text renders differently across platforms.

Floated Boxes With No Width

The same exact behavior is seen with floated elements with no widths. The box is only as wide as it needs to be to accommodate the content, up to as wide as it's parent element (doesn't need to be relatively positioned though). Because of the fragile nature of these width-less boxes, the lesson to take away here is to not rely on them in mission-critical scenarios, like in overall page layout. If you float a column to use as a sidebar and count on some element inside (like an image) to be responsible for holding it's width, you are asking for trouble.

Inline Elements are Boxes Too

We've been kind of focusing on boxes as block-level elements here. It's easy to think of block-level elements as boxes, but inline elements are boxes too. Think of them as really really long and skinny rectangles, that just so happen to wrap at every line. They are able to have margin, padding, borders just like any other box.

The wrapping is what makes it confusing. A left margin as shown above pushes the box to the right as you would suspect, but only the first line, as that is the beginning of the box. Padding is applied above and below the text like it should be, and when it wraps it ignores the line above its padding and begins where the line-height dictates it should begin. The background was applied with transparency to see how it works more clearly.

See it with your own eyes

Wanna see every single "box" that makes up a page? Try putting this in the stylesheet temporarily:

* {
   border: 1px solid red !important;
}

 

注:虽然文章的内容取自原文章,但基本上每句话都加上了本人的想法,再加上本人英语欠佳,可以说是改的面目全非。如果您发现什么根本性的错误或什么关键地方没有提及请告知我,我将快速更改,谢谢阅读。

我们必须深刻的认识到:每一个在WEB设计中的元素都是一个矩形的盒子(将设计具体化)。在真正了解了这个概念后,我们就能够真正开始明白CSS的基础WEB设计和实现自己想要实现的布局和设计。接下来我们将讨论一下这些盒子的布置和他们的行为。

我们往往忽视的就是盒子本身,所以让我们想想怎么才能恰到好处的计算这些盒子的位置和大小呢?让我们来看两个例子:

如果你是一个Firebug(注:Firebug是firefox下的一个插件,能够调试所有网站语言)的使用者,你也许会习惯于这样的图表,他能够很好的展示这些盒子在页面上的效果。

也许大家能够注意到,在这两个例子中,他们的边缘都是处在白色之中。虽然边缘不能够影响这个盒子的大小,但是边缘能够对其他的盒子造成影响,改变其他盒子的位置。所以我们可以知道,边缘是CSS盒式模型的一个重要的组成部分。

我们通常使用下列的方式来计算盒子的大小:
------------------------------------------------------------------------------------------------------------
Box of Width = width + padding-left + padding-right + border-left + border-right

Box of Height = height + padding-top + padding-bottom + border-top + border-bottom
------------------------------------------------------------------------------------------------------------

通过下面的示例图,大家可以对这个模型有更加好的把握。

如果我们没有设定这些值的话会发生什么?


如果你没有设定padding或者是border,系统就会默认为0,但有的浏览器有自己的默认值(这些默认值不一定是0,所以我建议无论是否要使用这些值,请将他们他们重置为默认值)

默认Width的块级盒子

如果你没有声明一个宽度( Box of Width ),而且这个盒子的位置是静态(static),或者是相对的(relative),那么这个盒子(Box of Width)的宽度将会100%的填充在padding、border、width中,其是向内部延伸,而不是向外部。但是如果你明确的设置了一个盒子的 宽度,那么这个盒子的填充通常将会是向外部。


如果你对此还是概念模糊的话(我也感觉上面的解释含糊不清),可以将下面的代码复制进你喜欢的编辑器内,并运行它。

01 <hr align="left" width="240px"/>
02  <div style=" height:250px; width:50%; border:#03F solid 20px; padding:20px #093; margin:0px; left: 0px; top: 21px;">
03              
04         <div style="position:absolute; background-color:#9C3; border:#43F solid 10px; padding:5px; margin:10px; left: 38px; top: 273px; width: 82px;">
05                  1
06         </div>
07         <div style=" background-color:#9C3;width:300px;border:#03F solid 10px; padding:5px; margin:10px">
08                  2
09         </div>       
10         <div style=" background-color:#9C3; position:relative; border:#03F solid 10px; padding:5px; margin:10px">
11                  3
12         </div>
13         <div style=" background-color:#9C3; position:static; border:#03F solid 10px; padding:5px ; margin:15px">
14                  4
15         </div>
16           
17     </div>

 


没有宽度的盒子(设定position属性为absolute的盒子)

往往 position属性为absolute且没有设定宽度的盒子会表现的有些奇怪。这样的盒子的宽度往往取决于其自身内容的大小。也就是说当这个盒子里只有 一个单词的时候,这个盒子的宽度就是一个单词的宽度。如果是两个单词的话,那他就会变成两个单词的宽度。如果不断的增加,最终就会溢出,很有可能会冲出你 的浏览器窗口(笑)。



在此之上我们还要关注一下兼容性的问题,毕竟这些代码是要运行在各式各样的浏览器上的(话说国内的IE6着实让人头痛啊╮(╯_╰)╭)。


 

对于浮动属性的盒子

同样精准的行为也在没有设定宽度的浮动元素上被发现。这个盒子仅仅和他容纳的内容一样宽,直到和他的父亲元素一样(并不需要去进行相对位置摆放)。由于这 些缺少Width属性的盒子有易碎的性质,所以我们不能轻易的拿走他们依赖的关键脚本,像是在整体的页面布局中。如果你悬浮一些列去当工具条,依靠一些元 素(像是图片)去对保持宽度负责,那我想你是在找麻烦。

联机元素也是盒子

我们很容易就将块级元素抽象化为一个盒子,但是我们往往没有想到联机元素也是一个盒子,事实上确实如此。请将他们想象成一个非常非常长且非常非常细小的矩 形,这些小矩形缠绕在每一行中。他们和其他的盒子一样,同样拥有margin, padding, border属性。



这种包装使得他变得模糊起来。也许你认为一个左边缘将一个盒子推到了右边是不可信的,但是这个第一行是作为这个盒子的开始。将背景属性设置为透明将能使你更加清晰的使用它。

用我们的眼睛好好看看!

如果你能使用一些网页调试器(我认为谷歌浏览器是不错的选择)来将盒子的边缘调成红色,你将看到不一样的世界,你会看见一堆盒子正堆积在页面上!

posted @ 2012-10-15 15:43  Mose  阅读(424)  评论(0编辑  收藏  举报