css盒模型是前端开发中非常基础和重要的知识,它是元素大小的呈现方式,它包括margin
、border
、padding
和content
,如图:
一、 box-sizing
css盒模型主要分为IE盒模型(border-box
)、W3C标准盒模型(content-box
)和padding-box
。在声明DOCTYPE的情况下,box-sizing默认为W3C标准盒模型;若不声明,IE浏览器默认为IE盒模型(border-box),chrome和Firefox等默认为W3C标准盒模型(content-box)。
1.1 IE盒模型(border-box)
dom.width = content.width + padding-left + padding-right + border-left + border-right;
dom.height = content.height + padding-top + padding-bottom + border-top + border-bottom;
1.2 W3C标准盒模型(content-box)
dom.width = content.width;
dom.height = content.height;
1.3 padding-box
dom.width = content.width + padding-left + padding-right;
dom.height = content.height + padding-top + padding-bottom;
1.4 如何设置和获取盒模型对应的宽和高
- dom.style.width/height --
只能获取到内联style设置的宽和高
- dom.currentStyle.width/height --
只支持IE
- Window.getComputeStyle(dom).width/height --
支持Firefox和chrome
- dom.getBoundingClientRect().width/height
二、内边距padding
padding是一个比较老实
的属性,定义元素的内边距,接受长度值或百分比值,但不允许使用负值。有意思的是,padding的百分比值,是根据父元素的宽度
设定的!在我们潜意识里可能认为,padding水平方向的百分比值应该是根据元素的宽度计算的,padding垂直方向的值应该是元素的高度,这是不对的!我在开发中,通常可以使用padding百分比的特性实现一个响应式的正方形。
padding属性通常包含在元素的实际的布局尺寸中,一般情况下padding的值不会影响元素的布局尺寸。但是padding属性值都特别大的时候呢?对于block
元素,当box-sizing是border-box时候或者width:auto 元素width不会变,但当paddind大于width时,元素宽度会增加,元素内的文字会以內联元素的最小宽度显示;相对于inline
水平元素,水平padding影响尺寸,垂直padding会影响尺寸,但会影响背景色。
许多标签元素都会有默认的padding值。button标签元素的padding兼容性特别差。。。
三、边框border
border是padding和margin中间的边框样式属性,目前支持10种border-style,其中最为常用的是solid(直线),还可以使用border-image来代替边框样式。border-width只接受长度值,不接受百分比值
和负值,但是如果边框没有样式,就没有宽度
。在开发中,我们可以利用border-width和border-color来实现许多的不规则图形。比如一个黄色的三角形:
{
width: 0;
height: 0;
border: 0 solid transparent;
border-left: 50px solid yellow;
}
四、外边距margin
margin就好像是元素的气场,气场有多大,别人就离你有多远了,是一个特别不老实
的属性。margin可以接受任何长度单位,包括负值。
4.1 margin 负值
margin负值在不同方向的产生的效果不同。margin-top为负值不会增加高度,只会产生向上位移,margin-bottom为负值不会产生位移,会减少自身的高度。margin所产生的位移效果,不会脱离文档流。当元素不存在width属性或者width=auto的时候,margin负值会增加元素的宽度,我们可以使用这一特性实现等高布局的效果哦。
4.2 margin auto
auto就是自动意思。当元素为block元素,我们可以使用margin: auto
实现元素水平方向居中。那么问题来了,为什么要是block元素?margin auto是什么意思?垂直方向为什么不居中呢?
我们知道block会自动填充父元素的宽度,但是不能自动填充父元素的高度。当元素能够自动填充父元素时,margin auto才能生效,auto = (father.width - content.width)/ 2
,所以垂直方向不能产生居中的效果。如果设置writing-mode
为垂直方向,block会自动填充父元素的高度,那么就可以实现垂直居中了。设置writing-mode
产生一个方向的自动填充,如果需要水平和垂直方向都居中,就可以使用relative
来产生两个方向的自动填充了!
4.3 margin 百分比值
margin的百分比值,也是根据父元素的宽度
设定的!下面的代码可以实现一个2:1的长方形:
{
width: 0;
height: 0;
margin: 50%;
}
诶?为什么padding:50%
呈现出来的是正方形?margin呈现出来的是长方形呢?让我们来看看边距重叠吧!
4.4 边距重叠
为什么说margin是一个特别不老实的属性呢,很大一部分是因为边距重叠了。产生边距重叠的特性:
- 不脱离文档流的block元素
- 作用于writing-mode方向
发生边距重叠的情景:
- 相邻的两个元素之间的margin
- 父元素与第一个和最后一个子元素
- 元素height = 0时 (4.3例子)
边距重叠的计算方法:
- 正正负负取最大值
- 负正相加
避免产生边距重叠的方法:
- BFC(block formatting context)
- margin-collapse: unset;