在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>
倘若我想要让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>
为达到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>
(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调试器的结果如下
可以看出我设置的80px,内容区域显示的也是80px。
接下来,当我设置box-sizing:border-box时,通过chrome调试器的结果如下
可以看出,我仅仅改变了box-sizing的值,其他的都原封不动,我设置的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)。
好啦,盒子模型也差不多讲到这里了,时间也不早,洗洗睡咯。今天第一次开博,如有不对之处,望狠狠拍砖~