CSS 盒子模型(Box Model)
所有HTML元素可以看作盒子,在CSS中,盒子模型可以用来对元素进行布局,包括内边距,边框,外边距,和实际内容这几个部分。
盒子模型分为两种 第一种是W3c标准的盒子模型 标准盒模型
,第二种IE标准的盒子模型 怪异盒模型
当前大部分的浏览器支持的是W3c的标准盒模型,也保留了对怪异盒模型的支持,当然IE浏览器沿用的是怪异盒模型。怪异模式是“部分浏览器在支持W3C标准的同时还保留了原来的解析模式”,怪异模式主要表现在IE内核的浏览器。
一、标准盒模型与怪异盒模型的表现效果和区别
1、标准盒模型中 width
和 height
对应的是内容区域 content
的宽度和高度。
盒子大小 = content + border + padding + margin
2、怪异盒模型中的 width
和 height
对应的是内容区域、边框、内边距总的宽度和高度(content + border + padding)。
盒子大小 = width(content + border + padding) + margin
二、如何选择盒模型
如果是定义了完整的doctype的标准文档类型,无论是哪种模型情况,最终都会触发标准模式,否则doctype协议缺失,会由浏览器自己决定,在IE浏览器中IE9以下(IE6.IE7.IE8)的版本触发怪异模式,其他浏览器中会默认为W3c标准模式。
除此之外,我们还可以通过属性box-sizing来设置盒子模型的解析模式:
content-box: 默认值,border和padding不计算在width内,可看成W3c的标准模型,将采用标准模式解析计算
border-box:border和padding计算在width内,可看成IE的怪异盒模型,将采用怪异模式解析计算
inherit:规定应从父元素继承 box-sizing 属性的值
三、js如何盒模型的宽和高
1、dom.style.width/height
此方法有个局限性,就是只能获取使用内联样式的元素的宽和高。
2、dom.currentStyle.width/height
此方法获取的是浏览器渲染以后的元素的宽和高,无论是用何种方式引入的css样式都可以,但只有IE浏览器支持这种写法。
3、window.getComputedStyle(dom).width/height
此方法获取的也是浏览器渲染以后的元素的宽和高,与方法2原理基本相似,但它兼容 Chrome 和 Firefox,通用性更好一些。
4、dom.getBoundingClientRect().width/height
此方法经常使用的场景,是用于计算一个元素的绝对位置(相对于视窗左上角),它能拿到元素的left、top、width、height 4个属性。
四、盒模型边距重叠问题
父子元素、兄弟元素,当有外边距时,会取其中一个边距的最大值,作为实际的边距。
空元素的有上下边距时,也会取其中更大的一个边距值,作为实际的边距,这就是边距重叠。
注意,对于行内元素 margin-top/margin-bottom 对于上下元素无效,而对于 margin-left/margin-right 有效。对于相邻的块级元素 margin-top 和 margin-bottom 两者叠加按照一定的规则:
- 都是整数 margin 值取两者的最大值;
- 都是负数 margin 值取最小值;
- 两者正负相反,margin 值取两者之和。
那如何解决盒子模型的边距重叠问题呢,这就引出了下一个知识点 BFC
。
五、BFC(边距重叠解决方案)
基本概念
- BFC 全称为 块级格式化上下文 (Block Formatting Context) 。
原理(渲染规则)
- 在BFC这个元素垂直方向的边距会发生重叠
- BFC的区域不会与浮动元素的box重叠
- BFC在页面上是一个独立的容器,其里外的元素不会互相影响
- 计算BFC高度时,浮动元素也会参与计算
创建BFC的方法
- float 值不为 none
- position 值不为 static 和 relative
- display 属性为 inline-block、flex、inline-flex、table/table-cell 等与 table 相关的值
- overflow 值不为 visible
BFC的使用场景
1、BFC解决兄弟元素垂直方向边距重叠:
<section class="layout">
<style>
.layout {
font-size: 2rem;
}
.layout .box1 {
margin: 10px 0;
height: 100px;
background: yellow;
}
.layout .box2 {
margin: 20px 0;
height: 100px;
background: red;
}
</style>
<div class="box1">Box 1</div>
<div style="overflow: hidden;"> //给其中某个兄弟元素增加了父元素div增加样式 overflow: hidden; 即创建了BFC。
<div class="box2">Box 2</div>
</div>
</section>
没创建BFC之前会出现兄弟元素垂直方向边距发生重叠问题:
再给其中某个兄弟元素增加了父元素div增加样式 overflow: hidden; 即创建了BFC后,解决了垂直方向边距重叠问题:
2、BFC解决父元素和子元素的边距重叠
可以在父元素中开启BFC,尽量使用overflow:hidden;,跟上一个例子类似,这里就不做演示。
3、BFC不与float重叠(给没有浮动的盒子创建BFC,设置 overflow: hidden;)
<section class="layout">
<style>
.layout {
background: red;
}
.layout .left {
float: left;
width: 200px;
height: 200px;
background: yellow;
}
.layout .right {
height: 220px;
background: blue;
overflow:auto; /*为元素创建BFC*/
}
</style>
<div class="left"></div>
<div class="right"></div>
</section>
没创建BFC之前,右边元素与左边浮动元素会发生重叠(这种方式也可以用来去做文字环绕图片效果):
开启了BFC之后,右边元素不再与左边浮动元素发生重叠,父级元素的背景颜色也显示出来了,相当于清除浮动:
4、子元素为float布局,给父元素创建BFC让子元素参与高度计算
<section class="layout">
<style>
.layout {
font-size: 2rem;
background: red;
overflow:auto; /*为父元素创建BFC*/
}
.layout .box {
float: left;
height: 100px;
background: yellow;
}
</style>
<div class="box">child box</div>
当没有给父元素创建BFC时,由于子元素左浮动脱离文档流,撑不起父元素的高度,所以父元素高度为0,背景色未显示出来:
给父元素创建BFC后,浮动子元素参与高度计算,这也是清除浮动背后的原理: