CSS 盒模型

所有文档元素都生成一个矩形框,这称为元素框(element box),它描述了一个元素在文档布局中所占的空间大小。而且,每个框影响着其他元素框的位置和大小。

网页布局中,我们是如何把里面的文字、图片等内容,按照美工给我们的效果图排列的整齐有序呢?

简单来说,网页布局的本质就是盒模型摆放的过程。


盒模型的组成

所谓盒模型就是把 HTML 页面中的元素看作是一个矩形的盒子,也就是一个盛放内容的容器。每个矩形都是由元素的内容、内边距(padding)、边框(border)和外边距(margin)组成。

[ 盒子的计算尺寸 ]

大多数浏览器,如 Firefox、IE6+ 都采用了 W3C 规范,符合 CSS 规范的盒模型的总宽度和总高度的计算规则为:

[ 盒模型布局的稳定性 ] 刚接触盒模型时,可能最大的困惑是:分不清内外边距的使用。即,什么情况下使用内边距,什么情况下使用外边距?— 其实,它们在大部分情况下是可以混用的,也就是说觉得哪个方便用哪个。

当然,从稳定性的角度考虑,建议:优先使用 width(宽度)> padding(内边距)> margin(外边距)。因为:

  • margin 可能发生外边距合并的现象,且在 IE6 下存在 margin 加倍的 bug(讨厌),所以,最后使用;
  • padding 会影响盒子大小,需要进行加减运算(麻烦),所以,其次使用;
  • width 没有问题,可以使用宽度剩余法或高度剩余法来实现布局,所以,优先推荐使用。

[1] content(内容区)                                                        // { CSS3自适应宽高?↓}

[ 宽高 ]内容区由width(宽度)、height(高度)两个属性设置,content = width * height 。           

width被定义为从左内边界到右内边界的距离,height被定义为从上内边界到下内边界的距离。

[ 怪异盒模型 ] IE6-浏览器的宽高定义的是可见元素框的尺寸,而不是元素框的内容区尺寸。

[ 最大最小宽高 ] 

设置最大最小宽高的好处是可相对安全地混合使用不同的单位;使用百分数的同时,也可设置基于长度的限制。


[2] 内边距 padding                                                   // 兼容性问题?!

padding属性用于设置内边距,即设置边框与内容之间的距离。对于行内元素,左内边距应用到元素的开始处,右内边距应用到元素的结尾处,垂直内边距不影响行高,但会影响自身尺寸,加背景颜色可以看出。


[3] 外边距 margin                                                         { margin负值、重叠、auto和无效情形?↓ }

margin 用于设置外边距。设置外边距会在元素之间创建“空白”,这段空白通常不能放置其他内容。


[ 妙用 - 水平居中 ] margin:0 auto;

[ CSSRset - 清除元素的默认边距 ] 为了更方便的控制网页中的元素,制作网页时,须清除元素默认的内外边距:

[ 现象 - margin合并 ] 使用 margin 定义块级元素的垂直外边距时,可能会出现外边距的合并。

  • 相邻块元素垂直外边距的合并 — 毗邻元素垂直重叠会取最大值              // 解决方案:避免就好了

当上下相邻的两个块元素相遇时,如果上面的元素有下边距margin-bottom,下面的元素有上外边距margin-top,则它们之间的垂直间距不是margin-bottom与margin-top之和,而是两者中的较大值,这种现象被称为相邻块元素垂直外边距的合并(也称为外边距塌陷)。

  • 嵌套块元素垂直外边距的合并 — 父元素与第一个 / 最后 一个子元素会合并

对于两个嵌套关系的块元素,如果父元素没有上内边距及边框,则父元素的上外边距会与子元素的上外边距发生合并;合并后的外边距为两者中的较大者,即是父元素的上外边距为0,也会发生合并。

解决方案:可以为父元素定义 1px 的上边框或上内边距 或 可以为父元素添加 overflow:hidden 。


[4] 边框 border                                               { 深入了解border?↓ }

元素外边距内就是元素的边框 border,元素的边框是围绕元素内容的内边距的一条或多条线。

[ 行内元素 ] 对于行内元素,边框实际上画在各行之外的下一个像素上,由于各行紧挨着,所以其边框会重叠。无论为行内元素的边框设置怎样的宽度,不会对行高有任何影响;但左右边框会分别显示在元素的开始处和结尾处。

[ 表格的细线边框 ]            // border-collapse:collapse; 表示边框合在一起。


[ 圆角边框 ] border-radius 可以为边框设置圆角(IE8-不支持),四值顺序是:左上、右上、右下、左下。


溢出及相关

[1] overflow(溢出)                                                               引申:overflow-x | overflow-y?↓ }

设置盒子里的内容超出时如何设置。当一个元素固定为某个特定大小,但内容在元素中放不下,此时就可以利用overflow属性来控制这种情况。


 [2] 裁剪 clip

CSS裁剪clip这个属性平时用的不多,但其实它并不是CSS3的新属性,很早就开始出现了。

一个绝对定位或固定定位元素通过使用属性clip可以改变剪裁区域的形状,但并不改变元素本身的宽高属性。

clip:rect(top,right,bottom,left)中的值不是边偏移,而是距元素左上角的距离。
具体来说,就是top和bottom是表示距离元素上边界的距离;left和right是距离元素元素左边界的距离。这里元素的边界指元素边框外侧。

rect(...)的语法与CSS的其他语法相比不太一样。原因是它基于早期的定位草案,而该草案使用了左上偏移机制。

在CSS2之前,实现这个语法的IE已经成为完备推荐,于是标准从边偏移修改成适用这个实现。

但是,这意味着如果高度和宽度没有明确定义,将无法设置一致的剪裁区域。

clip:rect(...)只允许长度值和auto,不允许有百分数。

如果设置为auto,则相当于将剪裁边界设置为适当的内容边界。

对于top或left设置auto,相当于值为0;对于right或bottom设置auto,相当于值为水平方向的宽度和或垂直方向的高度和

[注意] 该元素水平方向或垂直方向的clip区域的边界是外框外侧,不包括outline

[ clip的应用 ]

1. 隐藏效果

当clip:rect(top,right,bottom,left)中的top>=bottom,或者left>=right时,可实现元素的隐藏效果,效果类似于visibility:hidden;


2. 雪碧图定位

css sprite是一种网页图片应用处理方式,它允许将一个页面涉及到的所有零星图片都包含到一张大图中,然后利用background-position来显示应该显示的区域。而如果使用clip也可以实现同样的效果。


3. 歌词演示效果

利用clip和background-clip实现歌词演示效果,实际上通过改变宽度也可以实现,主要用于拓展思路。


[3] 拉伸 resize

CSS3新增了resize属性,该属性允许用户通过拖动的方式来修改元素的尺寸。本来resize应该翻译为缩放,但在实际测试中通过resize属性只可以在宽高基础上实现拉伸效果,而无法实现缩放到小于宽高的效果。

[注意] 在win7下resize拖拽区域的大小是17px*17px,实际上它就是滚动条尺寸。


[4] 滚动条

滚动条在网页中经常见到,却并没有受到足够的重视;只有当因为滚动条的问题需要处理兼容性时,才进行调试操作。


[5] 可见性 visibility                                                    { visibility:hidden & display:none?↓ }

visibility属性常见于与display属性的比较中。但实际上,该属性有自己的一些有趣的用途。


高级特性

[1] box-sizing:设置width、height的指定区域

CSS3可通过box-sizing指定盒模型,即指定 content-box / border-box,这样计算盒子大小的方式也就发生了变化。

  • box-sizing:content-box; 盒子大小为width + padding + border,默认值,符合W3C的标准盒模型;
  • box-sizing:border-borx; 盒子大小为width,也就是说,padding和border是包含在width里面的。

[ CSS盒模型 ]在CSS中,盒模型被分为两种,一种是W3C的标准模型,第二种是IE怪异盒模型。不同之处在于后者的宽高定义的是可见元素框的尺寸,而不是元素框的内容区尺寸。

目前对于浏览器大多数元素都是基于W3C标准的盒模型,但对于表单form中的部分元素还是基于IE的怪异盒模型,如input里的radio、checkbox、button等元素,如果给其设置border和padding它们也只会往元素盒内延伸。

W3C的标准模型下,宽度和高度仅仅包含了内容宽度,除去了边框和内边距两个区域,这样为web设计师处理效果带来了不少麻烦。为解决这个问题,CSS3新增了一个盒模型属性box-sizing,能够事先定义盒模型的尺寸解析方式。


[2] box-shadow 盒阴影                                                // IE8-不支持

box-shadow 可以为元素设置阴影,但需要注意的是:

  • 可以使用多重阴影,但使用过多会造成性能差。
  • 边框在内阴影之上,内阴影在背景图片之上,背景图片在背景色之上,背景色在外阴影之上。
  • 内阴影对 img 元素没有任何效果。
  • 最先写的阴影在最顶层。
  • 该属性与border-radius一脉相承,若通过border-radius设置为圆角,则box-shadow的最终呈现也将是圆角。


  • 模拟边框

  • 单侧投影

  • 邻边投影

  • 双侧投影


[3] outline  轮廓                                                  { 深入了解outline?↓ }

轮廓是绘制于元素周围的一条线,位于边框边缘的外围,可起到突出元素的作用。

轮廓outline处在边框边界的外面,它不像边框那样参与到文档流中,因此轮廓出现或消失时不会影响文档流。

即,不会导致文档的重新显示。利用轮廓,浏览器可以合并部分轮廓,创建一个连续但非矩形的形状。

[ 取消轮廓 ] 默认地,轮廓是一个动态样式,只有元素获取到焦点或被激活时呈现。