前言
盒模型都知道:
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
relativeabsolute:找有定位的祖先元素,直到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定位。