Fork me on GitHub

CSS盒模型详解

CSS盒模型作为前端面试中经常出现的问题,因为涉及到浏览器表现,页面布局,兼容,CSS3等前端多个重要领域,还是比较考验前端水平的。

在这篇博客中,对CSS 盒模型进行了一些介绍总结,涉及到的都是跟盒模型关系密切的一些知识点。

盒模型概述

HTML中,所有元素(除了图片和表单元素)都是按照盒模型(box model)的标准来进行排版和布局的。也就是说,除了内部无法再包含其他元素的图片和表单元素(这两者本质上都是作为其他内容占位符的替换元素),其他所有的HTML元素,如 <div><span><a> 元素,均相当于一个个盒子,堆叠嵌套,形成了我们看到的网页。

对应元素的每个盒子的具体表现,主要取决于元素的以下几个属性:

  • 边距margin
  • 边框 border
  • 填充 padding
  • width 和高height

元素在布局时,会根据以上几个属性来确定盒模型的宽高,即元素实际占据的宽高,从而完成布局。

盒模型模式

在根据以上几个属性来确定盒模型宽高时,存在两个计算标准,也可以说是两种模式。

一种是W3C规定的计算标准,又称为标准盒模型模式,另一种是 微软IE 规定的计算标准,又称为 IE怪异盒模型模式

标准盒模型

W3C规定,元素的widthheight 属性,表示的是元素内容 content的宽高,不包括元素的paddingborder。因此,在W3C的标准中,元素盒模型的宽高计算方式为:

盒模型高 = 元素height + 上下padding之和 + 上下border之和 + 上下margin之和

盒模型宽 = 元素width + 左右padding之和 + 左右border之和 + 左右margin之和

同时在标准盒模型下,元素以下各项与宽高有关的属性,控制的都是元素content的大小:

  • height
  • width
  • min-height
  • min-width
  • max-height
  • max-width

在这种模式下,元素的widthheight确定时,我们对paddingborder的修改,会导致盒模型的宽高相应变化,也就是元素在页面中的真实占据宽高变化。

IE怪异盒模型

由于历史遗留问题,在IE浏览器中,元素的widthheight 在计算时,不光包括元素的content,还包括了元素的paddingborder。因此,在IE怪异盒模型模式下,盒模型的宽高计算如下:

盒模型高 = 元素height + 上下margin之和

盒模型宽 = 元素width + 左右margin之和

在这种模式下,元素的widthheight确定时,我们对paddingborder的修改,会导致元素内容区域,也就是content的宽高变化,对元素在页面中的真实占据宽高没有影响。

两种模式的切换

以上两种模式,可以通过 CSS3的属性 box-sizing 来进行切换。

1
2
3
4
5
/* 标准模型 */
box-sizing: content-box;

/* IE模型 */
box-sizing: border-box;

需要注意的是,这种切换盒模型模式的方法,只在IE8+ 浏览器和其他主流浏览器中被支持。

引申出的问题

兼容问题

如上文所说,在IE8+ 浏览器和其他主流浏览器中,我们可以通过css3属性box-sizing 来进行盒模型模式的切换。

但是在更早版本的IE浏览器中,是不支持此css3属性的,如果希望使用标准盒模型,可通过设置文档声明为 <!DOCTYPE html>实现,当然,此方法对所有IE浏览器都有效。

IE怪异盒模型的应用

IE怪异盒模型模式下,元素宽高固定时,paddingborder的改变,并不会影响到元素真实占据宽高的改变。

这在元素宽高为百分比时十分有用,例如我们想让并排的两个元素宽度各为50%,但又想通过设置padding让它们的内容靠的别那么近。如果在标准盒模型下,设置padding之后,元素的真实宽度就会增加,导致两元素撑破容器,无法并排显示。当然我们可以通过设置元素宽度为49%padding1%来实现,但这样非常不优雅。而此时通过设置box-sizingborder-box使用IE盒模型,就可以很轻松的实现我们的目的。

换句话说,IE盒模型的关键作用就在于此,让有borderpadding的元素,能更符合我们直觉的使用百分比宽高。

浏览器样式

同样由于历史遗留问题,各个浏览器之间的默认样式存在一些区别,影响比较大的就是各个浏览器对元素添加的默认marginpadding 的尺寸大小不一,导致在各浏览器下,元素盒模型的表现不一致。

可以通过覆盖或清楚默认样式(css reset)的方法,来达到各浏览器表现一致的目的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 此种方法不论从效率还是bug发生概率上都不推荐使用 */
*{
margin:0;
padding:0;
}

/* 最好通过以下设定特定元素的内外边距来实现reset,安全且效率高 */
/* structural elements 结构元素 */
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote,
/* list elements 列表元素 */
dl, dt, dd, ul, ol, li,
/* text formatting elements 文本格式元素 */
pre,
/* form elements 表单元素 */
form, fieldset, legend, button, input, textarea,
/* table elements 表格元素 */
th, td {
margin: 0;
padding: 0;
}

以上就是我总结的关于 CSS 盒模型的一些知识,希望对大家有所帮助。^-^。

----本文结束感谢阅读----