padding
padding用于设置内边距,即content与border之间的间距。有padding-top、padding-right、padding-bottom、padding-left。
设置padding时,可以单独给上右下左边距设置,也可以采用padding的简写形式进行设置。padding的简写形式有4种情况,记忆方式如下。
如上图,以顺时针方向进行对称式记忆,为padding设置值时,为top、right、bottom、left的值,情况如下:
- 为padding设置4个值时,分别为top、right、bottom、left的值。
- 为padding设置3个值时,省略了left,则left的值等于right。
- 为padding设置2个值时,省略了bottom和left,则bottom的值为top的值,left的值为right的值。
- 为padding设置1个值时,仅为top设置了值,此时其他方位的值均等于top。
注意,padding用于设置行内非替换元素时会有特殊性,详见文章盒子属性对于行内非替换元素的特殊性内容。
margin
margin用于设置内边距,即元素和其他元素之间的间距。有margin-top、margin-right、margin-bottom、margin-left。
设置margin时,可以单独给上右下左边距设置,也可以采用margin的简写形式进行设置。margin的简写形式有4种情况,记忆方式如padding内容中的第二段所述。
注意,margin用于设置行内非替换元素时会有特殊性,详见文章盒子属性对于行内非替换元素的特殊性内容。为上下margin设置auto时,浏览器会选择一个合适的值来使用(对于标准流元素默认上下无外边距,对于脱标元素,满足position设置为absolute/fixed时元素的特性中所叙述的公式)。
margin外边距传递
margin-top传递:当子元素是一个块级元素,且顶部线和父元素顶部线重叠时,此时为子元素设置margin-top,则该属性会传递至父元素。
margin-bottom传递(仅作了解):当子元素是一个块级元素,且底部线和父元素底部线重叠,且父元素的高度不是一个定值,而是auto(父元素高度由内容撑开),此时为子元素设置margin-bottom,则该属性会传递至父元素。
水平方向上的margin不会传递。
假设有如下场景,子元素box在一个父元素content中,如下图。
此时如果为子元素设置margin-top,那么该属性会传递至父元素,使得父元素下移,而不是子元素相对父元素下移,如下图。
解决方案如下:
- 为父元素设置padding-top以代替margin(推荐,因为padding就是用来设置父子元素间距的,不应使用margin)
- 为父元素设置border(不推荐,会改变父元素尺寸)
- 触发父元素BFC,即设置父元素
overflow:auto(后面详解) - 父元素设置为flex布局
这里仅对margin-top的传递问题进行详解,实际上margin-bottom的传递很少遇到,不作详解。
margin折叠
如果由上下两个元素,为上元素设置margin-bottom,为下元素设置margin-top,此时会产生margin的上下折叠,上下两个元素之间的间距值为二者之间较大的设置值。如图所示。
水平方向上不会有margin折叠问题。
解决方案就是只设置一个元素的垂直方向上的margin。
用margin实现块级元素水平居中
设置margin-left:auto则左边距接收未使用的水平空间中的一部分(这主要由所使用的布局模式确定)。如果 margin-left 和 margin-right 的值都是 auto,则最后计算的空间是均匀分布的。
即可可以使用margin:0 auto让块级元素水平居中。
注意,该方案用于布局本质上还是在利用css的一些特性,设置子父元素之间的margin,并不推荐,实际布局更推荐flex布局。另外,对上下margin设置为auto(如margin:auto 0),
padding与margin的区别
假设有如下需求:子元素box需要设置与父元素content左边和顶部之间各有100px的距离,初始情况如下图:
正确的效果图如下。
可以通过为父元素设置padding来产生间距,代码如下。
.content{
padding:100px 0 0 100px;
}
但是这样会将父元素撑大,效果如下图。
可以通过设置box-sizing属性,如下图。
.content{
padding:100px 0 0 100px;
box-sizing: border-box;
}
效果如下图,满足了需求。
以上是采用为父元素content设置padding作为解决方案,额外需要的操作是使用box-sizing。另外,可以给子元素box设置margin作为另一个解决方案,如下。
.box{
margin:100px 0 0 100px;
}
效果如下图,可以看到左间距是正常的,但是上间距的设置不正常,反而是父元素向下移动了100px。
这是因为子元素的margin传递给父元素了,这里可以为父元素设置overflow溢出属性来处理,如下。
.content{
overflow:auto;
}
效果如下图,满足了需求。
可以看见,使用padding和margin来制造边距都会有相应的问题,那么实际使用时,需要依据padding和margin的原生定义来决定最终用哪个方案。遇到不同情况所使用的方案如下。
- 当元素同级时,元素之间需要间距,则使用margin。
- 当元素之间属于子父关系时,则使用padding。