前言
盒模型都知道:
content-box
:width = 内容宽度
border-box
:width = 内容宽度 + padding + border
但如果有滚动条(bar)时又如何呢?
Chrome
content-box
:
Cwidth
||
Twidth padding bar border margin
| |
--- width ---
width = Twidth(图上蓝框width) + bar的width
同时Twidth = Cwidth(计算后的样式width)
也就是说,计算Cwidth时,chrome会减去bar的width
clientWidth
= padding外边缘之间的距离(... Twidth + padding)scrollHeight
= padding外边缘之间的距离(Twidth由内容完全撑开时,b的width<Twidth)offsetWidth
= border外边缘之间的距离(... Twidth + padding + bar + border)getBoundingClientRect().width
= border外边缘之间的距离
border-box
:
Twidth padding bar border margin
| | | |
----- width -----
||
Cwidth
width = Twidth + padding + bar + border
这时width = Cwidth
注意Twidth并不是图中右下方盒子所标注的80,会被bar侵蚀一部分
clientWidth
= padding外边缘之间的距离(... Twidth + padding)scrollHeight
= padding外边缘之间的距离(Twidth由内容完全撑开时,b的width为80>Twidth)offsetWidth
= border外边缘之间的距离(... Twidth + padding + bar + border)getBoundingClientRect().width
= border外边缘之间的距离
Firefox
而在Firefox中,bar不参与到盒模型中
content-box
:
Cwidth
||
Twidth padding border margin
||
width
width = Twidth(图上浅蓝框width)
同时Twidth = Cwidth(计算后的样式width)
clientWidth
= padding外边缘之间的距离(... Twidth + padding)scrollHeight
= padding外边缘之间的距离(Twidth由内容完全撑开时)offsetWidth
= border外边缘之间的距离(... Twidth + padding + border)getBoundingClientRect().width
= border外边缘之间的距离
border-box
:
Twidth padding border margin
| | |
--- width ----
||
Cwidth
width = Twidth + padding + border
这时width = Cwidth
注意Twidth就为图中右下方盒子所标注,不会被bar侵蚀
clientWidth
= padding外边缘之间的距离(... Twidth + padding)scrollHeight
= padding外边缘之间的距离(Twidth由内容完全撑开时)offsetWidth
= border外边缘之间的距离(... Twidth + padding + border)getBoundingClientRect().width
= border外边缘之间的距离
offsetParent
标准流
:找有定位的祖先元素,直到bodyfloat
:找有定位的祖先元素,直到bodyabsoute
:找有定位的祖先元素,直到bodyfixed
:firefox为body,其他为nullbody
:null
offsetTop
:
fixed
为top值。body
为0。
其他offsetParent为body时:firefox上元素的border外边缘到offsetParent的border内边缘,其他浏览器为元素的border外边缘到body的border外边缘,所以body不要设border margin
其他offsetParent非body时:都为元素的border外边缘到offsetParent的border内边缘
盒模型与position
relative
absolute
:找有定位的祖先元素,直到document的视口,定位基于padding外边缘(... Twidth + padding)fixed
:相对于document的当前视口,定位基于padding外边缘(... Twidth + padding)
盒模型与百分比height
标准流
:找父元素,且父元素要设height,为父元素Theight的%float
:找父元素,且父元素要设height,为父元素Theight的%absoute
:找有定位的祖先元素,祖先元素要是设height,为祖先元素padding外边缘的%,直到document视口的padding外边缘的%(... Twidth + padding)fixed
:document当前视口的padding外边缘的%(... Twidth + padding)标准流html height:100%
:document初始视口(ICB)的padding外边缘的%(... Twidth + padding),注意document的滚动条标准流body height:100%
:找html,且html要设height,为htmlTheight的%,注意body的滚动条
特殊点
- 内联元素的
clientWidth clientHeight scrollWidth scrollHeight
为0 window.innerHeight
包括document的滚动条document.documentElement.clientHeight
是ICB的高度,也就是初始视口的高度,所以html不要设padding border margin
以上都是基于Twidth所说,Twidth是渲染引擎最终所得的盒子内容,会受其中子元素脱离文档流的影响,包括:
- 子元素float
- 子元素absolute、fixed
也就是说,子元素一旦脱标,会对父元素的Twidth造成影响,进而影响父元素的各种大小,更进一步可能影响子元素的百分比大小和position定位。