盒模型详解—你真的了解盒模型吗?

突然想到前几天面试的一个尴尬场景。关于盒模型理论,我以前确实有拿来认真了解,我以为我还是知道的,结果面试官一个问题把我问蒙了:

“请你说一下W3C盒模型和IE盒模型的区别。”

我…..这是啥?

为了避免这样的丢人事件再次发生,我打算重新认真学习一下。

W3C盒模型理论基础

盒模型指的是HTML元素在浏览器引擎当中的一种构建模式,它把网页当中的所有元素都看成一个个大小不一的盒子互相嵌套。盒模型理论出现的比较早,在199年就有W3C提出了这个理论。尽管CSS标准中为其服务的marginpaddingwidthheight等并没有用盒模型这个术语进行描述,但那时候的开发者以及浏览器厂商已经在使用这个术语了。

这里讨论的是W3C盒模型。

盒模型理论将所有HTML元素视为盒子,如divp等元素均视为盒子。对于每个盒子来说,它有五个参数用于支撑模型布局:

  1. 高度,height。用于描述实际内容的高度,简称为高。
  2. 宽度,width。与高度类似,用于描述实际内容的宽度,简称为宽。
  3. 内边距,padding。内边距描述了内容与边框之间的距离,有上下左右四个方向,简称方向+内距,如左内距,右内距。
  4. 外边距,margin。外边距描述了盒子与盒子之间的间隔距离,有上下左右四个方向,简称方向+外距。
  5. 边框,border。边框是内外边距之间的分界层,可以是任意类型和宽度的线,表示盒子内部和盒子外部的分隔,也有上下左右四个方向。尽管实际开发当中盒子的边框一般都很窄或者没有。(尽管可以没有边框,但在理论模型上边框存在,可以理解成实际使用时加入了一个宽度为0的边框),简称方向+边。

下图描述了W3C盒模型的图形表示(图片摘自Wikipedia-CSS box model)

使用盒模型可以描述绝大多数页面的结构。在CSS3中,盒模型被并入标准,被称为border-box

对于一个盒子的总宽度和总高度而言,其计算方法是显然的:

总宽度=宽+左右内距+左右外距+左右边

总高度=高+上下内距+上下外距+上下边

W3C盒模型与IE盒模型的区别

这里面牵扯到一个历史问题。在HTML4版本之前和CSS出现之前,只有很少的元素支持padding,不同元素的宽高计算方法不尽相同。在盒模型理论提出之前,HTML元素的显示还没有一个很统一的标准。当时,浏览器对于盒模型的适应性还不很好,比如当时的IE4和Netscape 4.0都把宽高定义为边框到边框的距离,这种定义方式的盒模型就被称为IE盒模型,计算距离不适用刚才写的计算公式。可以通过下面的一张图看出区别来。

Wikipedia指出,通常认为IE盒模型是一个错误的盒模型,因为它处理元素的方式并不遵循W3C的标准,这将导致各种各样的显示错误。直到IE6之后,IE才支持了W3C标准的盒模型。但是由于当时需要考虑到向下兼容,默认情况下,IE仍然以它自己的盒模型方式运行。这种行为非常怪异,所以一般将其称之为“怪异盒模型”,将W3C盒模型称为“标准盒模型”。不过Mac上的IE浏览器貌似就没有这样奇怪的设定,遵循了W3C标准。

在标准模式下,使用W3C标准渲染,但对特别远古的浏览器不支持。在怪异模式下,采用向后兼容模式,可能会出现怪异盒模型这样的渲染。

尽管曾经有人想过利用CSS的各种bug让低版本浏览器强行支持W3C标准的盒子,但实践证明那样用bug修bug的操作是不可靠的,那如何让浏览器完全区分标准模式和怪异模式呢?

扩充:标准模式与怪异模式(quirks mode)

标准模式与怪异模式下的渲染模式有很大不同,尽管现在都是标准模式渲染了,但也可以了解一下两者之间的区别。

怪异模式是浏览器为了兼容很早以前的旧版本浏览器设计的,并不遵循W3C标准。换句话说,是故意模拟出来一些旧浏览器的bug来让旧标准的网页能够正常显示。(好家伙,负负得正是吧)

标准模式是微软在2000年IE5发布时提出的一个标准,因为IE5在当时已经实现了当时比较先进的HTML4标准,但同时IE5也要兼容以前浏览器下的内容,所以微软想到了一个文档类型声明的方式,就是HTML代码最前面的DOCTYPE。让浏览器在解析HTML文档之前首先判断一下遵循了什么标准。

DOCTYPE的全称叫做Document Type Declaration,或者叫做DTD。之前还一直好奇DTD到底是什么,现在算是明白了。

现代浏览器如何区分标准模式与怪异模式?一般来说,当出现以下情况之一时,浏览器将触发怪异模式。

  1. doctype声明缺失或不完整;
  2. 遇到HTML 3或更早的文档时;
  3. 使用HTML 4文档但系统标识符不存在时;
  4. SGML注释或其他无法识别的内容出现在文档类型声明之前时;
  5. 在IE6下,文档类型声明之前出现了一个XML声明时;

当DTD遇到这些声明时,将判断为不同的标准:

<!DOCTYPE html>:这代表此页面遵循HTML5规范,浏览器选择标准模式,这是目前最合适的一种模式,写页面无脑加就ok,除非极其特殊的情况。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd>:这代表HTML4的一种规范,浏览器仍然会选择标准模式,但和HTML5有一些区别。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">:这时候选择的不是完全的标准模式,而是“Almost Standards Mode”(几乎标准的模式),里面也和标准模式差不多,但有些地方在转化为HTML5标准时可能会出现混乱。

其他情况可以参考怪异模式的触发条件。

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2018-2021 Shawn Zhou
  • Hexo 框架强力驱动 | 主题 - Ayer
  • 访问人数: | 浏览次数:

感谢打赏~

支付宝
微信