【CSS】深入掌握padding与margin及其各自使用场景

1,223 阅读5分钟

padding

padding用于设置内边距,即content与border之间的间距。有padding-top、padding-right、padding-bottom、padding-left。

设置padding时,可以单独给上右下左边距设置,也可以采用padding的简写形式进行设置。padding的简写形式有4种情况,记忆方式如下。

如上图,以顺时针方向进行对称式记忆,为padding设置值时,为top、right、bottom、left的值,情况如下:

  1. 为padding设置4个值时,分别为top、right、bottom、left的值。
  2. 为padding设置3个值时,省略了left,则left的值等于right。
  3. 为padding设置2个值时,省略了bottom和left,则bottom的值为top的值,left的值为right的值。
  4. 为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,那么该属性会传递至父元素,使得父元素下移,而不是子元素相对父元素下移,如下图。

解决方案如下:

  1. 为父元素设置padding-top以代替margin(推荐,因为padding就是用来设置父子元素间距的,不应使用margin)
  2. 为父元素设置border(不推荐,会改变父元素尺寸)
  3. 触发父元素BFC,即设置父元素overflow:auto(后面详解)
  4. 父元素设置为flex布局

这里仅对margin-top的传递问题进行详解,实际上margin-bottom的传递很少遇到,不作详解。

margin折叠

如果由上下两个元素,为上元素设置margin-bottom,为下元素设置margin-top,此时会产生margin的上下折叠,上下两个元素之间的间距值为二者之间较大的设置值。如图所示。

水平方向上不会有margin折叠问题。

解决方案就是只设置一个元素的垂直方向上的margin。

用margin实现块级元素水平居中

设置margin-left:auto则左边距接收未使用的水平空间中的一部分(这主要由所使用的布局模式确定)。如果 margin-leftmargin-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的原生定义来决定最终用哪个方案。遇到不同情况所使用的方案如下。

  1. 当元素同级时,元素之间需要间距,则使用margin。
  2. 当元素之间属于子父关系时,则使用padding。