你真的理解浏览器盒模型吗?

面试官经常会问一个问题:说一下你了解的盒模型
小白:有2种盒模型,IE怪异盒模型和W3C标准盒模型,前者width包括padding和border,后者不包括。

上面的答案几近标准,但其实还有很多点没有答出来,也就是说,一个问题可以拆分成好几个问题回答。
下面我就将”说一下你了解的盒模型”这个问题拆分成多小问题,去详尽的解释这个问题背后隐藏的故事。

①两种盒模型之间有何异同?
分为W3C标准盒模型和IE怪异盒模型,准确叫法应该是内容盒模型和边框盒模型,因为经过近日的一次实验,发现IE5+浏览器目前的默认盒模型也改为了content-box,无论是content-box和border-box,都是符合W3C标准的。

二者都由四部分组成:content,padding,border,margin…
那么IE怪异盒模型与W3C标准盒模型到底哪里有差?)
W3C标准盒模型 vs IE怪异盒模型

  • W3C标准盒模型下元素 css 宽度只应用于 content
  • IE怪异盒模型元素 css 宽度包含 content + padding + border,主要体现在 IE 内核浏览器。
    IE6 以上版本的浏览器只要正确声明 DOCTYPE 即渲染为标准盒模型,亲测,ie5确实是怪异模式(加上<!DOCTYPE html>依然怪异模式),参考:
    Internet Explorer box model bug

②如何切换盒模型模式?
使用 box-sizing: border-box 可切换为IE怪异盒模型,使用box-sizing:content-box可切换为W3C标准盒模型。

W3C标准盒模型细节知识点:

①box-sizing有2种:content-box(默认),border-box
②任何element都可以有min-widh,max-width等等
③有padding时,background会扩充到padding
④margin,top和bottom会存在margin collapsing现象,最后会选择较大的一个margin,原因是box之间margin区域定义不明确

demo地址:https://github.com/FrankKai/Personal-Practice-2/tree/master/cssBoxModel

③如何在W3C标准盒模型和IE怪异盒模型间取舍?
建议使用border-box,因为border-box的width会将padding和border包含在内,布局时更好控制,尤其是在响应式布局中。
image

有一篇墙推IE怪异盒模型的文章:《把所有元素的box-sizing都设置成border-box吧!》
https://css-tricks.com/international-box-sizing-awareness-day/

有一种推荐而且很常见的做法:

1
2
3
* {
box-sizing:border-box;
}

这样做使得witdh包含padding和border,使用百分比布局时更好控制。

④文档的DOCTYPE类型对盒模型类型有影响吗?
答案是:几乎没有,只有ie5及以下才会触发怪异模式。
IE的默认盒模型是怪异盒模型吗:不是!
windows10,windows7下亲测,在未声明<!DOCTYPE html>的情况下,IE的默认盒模型也是W3C标准盒模型。
那么在声明了<!DOCTYPE html>的情况下,IE的默认盒模型是哪一个呢?
依旧是W3C标准盒模型,box-sizing值为content-box,但是不会在chrome devtools的computed中显示出来。

DOCTYPE只是一种用来约定浏览器解析HTML文档时遵循哪种标准的方式,呈现模式分为以下三种:

Standards(标准)模式:遵循最新标准。
Quirks(怪癖/兼容)模式:帮助处理所有奇怪的渲染和非浏览器兼容及不符合标准的网页。
Almost Standards(近似标准)模式:针对标准的某个老版本设计的网页。

HTML规范的标准模式为<!DOCTYPE html>,这也是HTML5推荐的模式,在这个模式下,盒模型的默认值为content-box。

如何查看当前文档的doctype?
无论是IE,Chrome还是FireFox,都可以直接到elements中看去html的头信息,就和C语言的.h头信息一样。
或者在IE和Chrome中,使用document.doctype查看文档模式,ff很怪异,document.doctype打印出一个对象,而且没说明到底是什么doctype。

标准模式和怪异模式是否影响标准盒模型和怪异盒模型的实验:

1
2
3
4
5
6
7
 .box{
width:100px;
padding:10px;
border:10px solid black;
height: 100px;
background: red
}

chrome:未声明doctype,width不包含padding和border,默认是W3C标准盒模型。
image

firefox:未声明doctype,width不包含padding和border,默认是W3C标准盒模型。
image

ie: 未声明doctype,width不包含padding和border,默认是W3C标准盒模型。(11,10,9,8,7, 唯独ie5,是100px(开发工具不可完全信!), 而且发现ie8及以下的rgba()是不支持的)

ie5下的border会挤占content的空间,而不是从content外扩展出去。
image
demo地址:https://github.com/FrankKai/Personal-Practice-2/blob/master/cssBoxModel/cssBoxModelQuirks.html

参考:
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing