代码改变世界

剖析盒子模型

2016-01-28 22:01  猴子猿  阅读(812)  评论(3编辑  收藏  举报

在CSS这个一切皆为框的世界里,今天我想谈谈我对CSS盒子模型的理解,如有不妥,请狠狠拍砖。

一、什么是CSS盒子模型

通俗一点,CSS盒子模型由外边距(margin)、边框(border)、内边距(padding)、元素内容(content)组成,请见下图:

 

二、盒子模型中margin、border、padding、content的各自作用

(1) margin:

自己的理解

 

控制元素周围空间的间隔,从视觉角度上达到相互隔开的目的。注意:行内元素是木有margin-top、margin-bottom的。

 

CSS权威指南

边界,元素周围生成额外的空白区。“空白区”通常是指其他元素不能出现且父元素背景可见的区域。

下面通过具体的demo初步来瞧瞧margin的作用,比如有两个块级元素,如div,在它们margin都设置为0时,效果是这样的:

 1 <!DOCTYPE html>
 2     <head>
 3         <title>no_margin</title>
 4         <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 5         <style>
 6             * {
 7                 margin:0;
 8                 padding:0;
 9             }
10             div {
11                 width:80px;
12                 height:80px;
13                 line-height:80px;
14                 text-align:center;
15             }
16             .div1 {
17                 background:#9FCD82;
18             }
19             .div2 {
20                 background:#C8ECCC;
21             }
22         </style>
23     </head>
24     <body>
25         <div class="div1">
26             div1
27         </div>
28         <div class="div2">
29             div2
30         </div>
31     </body>
32 </html>
View Code

倘若我想要让div2的上边距远离div1一些距离,如10像素呢?我们可以设置相对应的div2样式margin-top:10px,设置后的结果见下图

 1 <!DOCTYPE html>
 2     <head>
 3         <title>no_margin</title>
 4         <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 5         <style>
 6             * {
 7                 margin:0;
 8                 padding:0;
 9             }
10             div {
11                 width:80px;
12                 height:80px;
13                 line-height:80px;
14                 text-align:center;
15             }
16             .div1 {
17                 background:#9FCD82;
18             }
19             .div2 {
20                 background:#C8ECCC;
21                 margin-top:10px;
22             }
23         </style>
24     </head>
25     <body>
26         <div class="div1">
27             div1
28         </div>
29         <div class="div2">
30             div2
31         </div>
32     </body>
33 </html>
View Code

为达到div2距离div1垂直之间相距10像素的效果,也可以设置div1的margin-bottom:10px;

或者同时设置div1的margin-bottom:10px;和div2的margin-top:10px;

你可能会感觉奇怪,为什么同时设置都可以呢?!!!

同时设置后它们的相对距离不应该是20px了吗?!!!

这就又要涉及到margin的重叠问题啦。

css2.0规范中对于margin的重叠,描述是:水平边距永远不会重合,垂直边距可能会在特定的框之间重合。

我靠,这个垂直边距可能会在特定的框之间重合,是在哪个特定情况呢。请见下表

1、

在普通流中,两个或者更多的块级元素相邻的垂直边,会重合。如果边距都为正数,选其最大的值;如果出现负边距,则用正边距减去负边距。

2、

在一个浮动框和其它框之间的垂直边距是不重合的。

3、

绝对定位的框与相对定位的框,边距不重合

现在大家知道为什么对前面demo中两个div的边距不是20px,而是10px了吧。

针对第2点--在一个浮动框和其它框之间的垂直边距是不重合的。我还想谈谈,使用block元素+float+margin请注意在IE6下会出现一个双边距问题哦,常见的解决方案就是将block元素换成inline-block元素,不过ie6除了在某些机构外,估计也木有人用了吧!!!

(2) border:

它是可见的,你可以设置任何元素的边框。如我将一个div设置为5px的黑色实线边框border:5px solid #000000。见下图:

 1 <!DOCTYPE html>
 2     <head>
 3         <title>border</title>
 4         <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 5         <style>
 6             * {
 7                 margin:0;
 8                 padding:0;
 9             }
10             div {
11                 width:80px;
12                 height:80px;
13                 line-height:80px;
14                 text-align:center;
15             }
16             .div1 {
17                 background:#9FCD82;
18                 border:5px solid #000000;
19             }
20         </style>
21     </head>
22     <body>
23         <div class="div1">
24             div1
25         </div>
26     </body>
27 </html>
View Code

(3)padding:

padding是设置内容区域与border的距离的,没有负值;并且如果你不通过调试器来看,你是看不出padding设置的是多少值的。注意:行内元素没有padding-top和padding-bottom。

(4)content:

内容。是内容占的区域content,而不是内容区域contentarea。

我靠,content != contentarea ?

答案:是的。

谈到contentarea,那么你就应该有必要清楚地了解什么是标准盒子模型,什么又是IE盒子模型啦。其实它们的区别在与对contentarea 的解析不同,说白了,就是对width、height解析不一样啦,盒子都一样,包括margin、border、padding、content。下面我们具体来看一看这两种模型,先从标准盒子模型开始:

标准盒子模型的width、height只包括内容区域 content,详情见下图

IE盒子模型的width、height则包括了内容区域的content、内边距padding以及边框border,详情见下图

这个怎么解决!!!一个盒子在不同的浏览器解析不同!!!

不用担心,申明文档类型,一键快速解决。

<!DOCTYPE html>这个熟悉吧,它的作用就将标准模式和怪异模式统一为标准模式,当然解析盒子嘛,也就解析为标准模式咯。

我靠,那这是不是太霸道了点,强硬的你可能会说,我觉得IE盒子模型不错呢,劳资就要用它,哈哈,不要动怒,css3中已经提供了这一属性box-sizing,它有两个值content-box和border-box。当你申明文档类型<!DOCTYPE html>时,默认是content-box,也就是标准盒子模型,如果你想使用IE盒子模型,reset一下box-sizing为border-box就OK啦。

Bootstrap也是这么做的哦,下图是bootstrap的部分css reset,可供你参考。

下面我们来简单验证一下box-sizing的两个值(content-box和border-box)到底是否与上面讲的标准盒子模型与IE盒子模型一样。

当设置box-sizing:content-box时,通过chrome调试器的结果如下

可以看出我设置的width:80px,内容区域显示的也是80px。

接下来,当我设置box-sizing:border-box时,通过chrome调试器的结果如下

可以看出,我仅仅改变了box-sizing的值,其他的都原封不动,我设置的width:80px,但是内容content只显示出来50px,并且细心的你可以发现

  width(80px)  ===  content(50px) + padding(10px)*2  + border(5px)*2

  height(80px)  ===  content(50px) + padding(10px)*2  + border(5px)*2

通过比较分析上面两张图片,可以知道box-sizing的两个值的确对应标准盒子模型(content-box)和IE盒子模型(border-box)。

好啦,盒子模型也差不多讲到这里了,时间也不早,洗洗睡咯。今天第一次开博,如有不对之处,望狠狠拍砖~