css之padding/margin/border详解

1,758 阅读8分钟

padding

padding的尺寸

  • 如果块状元素设置padding,会影响盒子的大小。如果box-sizing按照border-box来看,那么盒子的宽度=content的宽度+两边的padding
  • 如果块状元素设置了定宽,box-sizing按照border-box来看,如果两边的padding足够大,那么宽度无效,内容则表现为“首选最小宽度”
 .box{
     width:80px;
     padding:20px 60px;
     box-sizing:border-box
 }
 这种情况下width会无效,最终的宽度为60*2=120px
  • 内联元素的padding会在水平方向上影响布局和视觉表现,但在垂直方向上面不影响视觉表现,而是出现会影响布局的层叠效果。(css的层叠效果分为两类,一种是纯视觉层叠不影响外部尺寸-box-shadow/outline;另一类会影响外部尺寸-内联元素的上下padding)

基于padding的尺寸特点的巧用

  • 可以利用垂直方向不影响视觉的特点增大行内元素的点击区域
  • 我们利用浏览器URI的hash值+元素的id设置实现网页锚点,通常这个锚点定位的时候会直接定位在当前匹配的id元素。如果我们想要距离窗口的顶部有适当地距离,我们可以利用行内元素垂直方向影响布局而不影响视觉的特性,设置元素上内边距,即可实现。

PS:对于非替换的内联元素,不仅padding不会加入行盒高度的计算,margin和border也是如此,都不计算高度,但实际上在内联盒子周围发生了渲染

padding的百分比值

  • padding属性是不支持负数的
  • padding的百分比值无论是水平方向还是垂直方向,都是基于元素的宽度计算的(块状元素与内联元素一样)
  • 默认的宽度和高度有差异:内联元素的垂直padding会让“幽灵空白节点”显现,通过设置font-size:0,可以消除幽灵空白节点的影响
  • 内联元素的padding会算作内联行框盒子的一部分,所以padding如果超出父级设置的宽度会自动换行

基于padding百分比值的应用

  • 利用百分比是根据元素宽度计算的特性,我们可以为padding设置百分比从而实现正方形或矩形的描述。
.box{
    padding:10% 50%;
    position:relative
}
.box > img{
   position:absolute;
   width:100%;
   height:100%;
   left:0;
   top:0 
}
这样就可以实现一个长宽比固定为5:1的矩形,矩形中的图片也会一直是5:1的比例,兼容性极好

margin

margin元素与尺寸

尺寸的概念

  • 元素的尺寸:该含义为border-box尺寸,包含border、padding、content。在JQ中对用api为$().width()$().height();在原生js中对应的api为offsetWidth offsetHeight
  • 元素的内部尺寸(可视尺寸):该含义为padding-box,包含padding、content。在JQ中对应的api为$().innerWidth() $().innerHeight();在原生js中对应的api为clientWidth clientHeight
  • 元素的外部尺寸:该含义为margin-box,包含margin、border、padding、content。在JQ中对应的api为$().outerWidth(true) $().outerHeight(true);原生js没有对应的api

充分利用可用空间的概念

  • 某一元素在未设置宽度的情况下,能够完全占据其父级的宽度或窗口的宽度并且具有横向的流特性,或经过write-mode设置后具有纵向的流特性并完全占据空间

margin对于内部元素尺寸的影响

  • 只要元素的尺寸表现符合“充分利用可用空间”,无论是水平方向还是垂直方向都可以利用margin改变该元素的尺寸

margin对于内部元素尺寸影响的应用

  • 左侧定宽,右侧自适应的布局
 .left{
    width:200px;
    float:left;
 }
 .right{
    margin-left:200px
 }

这是我们在写这类布局时常用的方法,就是利用margin在自然流向上,可以改变元素尺寸的特性

  • 右侧定宽,左侧自适应。可以将上一种方法翻转过来,但是出于书写顺序的考虑,也可以这样设置:
.father{
  overflow:hidden;
} 
.left{
   width:100%;
   float:left;
 }
 .right{
   float:left;
   margin-left:-200px; // 会出现在右侧,占据200px
 }
 .left div{  // left的子元素div具有“充分利用可用空间特性”
    margin-right:200px
 }
  • 多个元素两端对齐效果(给定一组li元素,两边在窗口或父级两侧,每个li元素中间保留20px间距,类似于flex中的space-between的效果)
ul {
  margin-right:-20px
}
li {
  float:left;
  width:100px;
  margin-right:20px;
}

利用margin解决此类布局问题,兼容性很好

margin对于外部尺寸的影响

  • 只要元素拥有块状元素的特性,设置了margin就一定会对元素的外部尺寸产生影响
  • margin对于内联元素,纵向上设置无用,不影响任何,横向上会影响排版,但由于内联元素呈现“包裹性”,所以并不会改变内联元素的“内部尺寸”

margin对于外部尺寸影响的应用

  • 我们如果想要纵向留有间距,通常会设置padding:50px 0; 但是这样设置在Chrome中有一个问题:在overflow后滚轮滚至底部padding-bottom的50px会失效,这个时候我们选择去设置margin:50px 0 是一个比较好的选择(当然也可以设置border)
  • 两侧等高布局:无论左侧的文字多还是右侧的文字多,两侧必须是等高的
.father{
  overflow:hidden
}
.left,.right{
  margin-bottom:-9999px;
  padding-bottom:9999px;
}

这样设置的重点是一定要overflow:hidden 因为即使逻辑上正负抵消,但是它的高度是依然存在的。这样设置的一个弊端是也会影响锚点定位,只适用于场景简单的等高布局

margin的百分比值也是相对有宽度计算的,只是因为垂直方向上会发生合并,往往需要双倍的设置才能达到和padding一样的效果

margin合并

margin合并的条件:

  • 块状元素(不包含float和决定定位的元素,即使它们会将元素块状化)
  • 垂直方向(在没有通过write-mode改写流方向时,如果改了就是水平方向)

margin合并的三种场景:

  • 相邻兄弟元素的margin合并(前一个元素的下边距和后一个元素的上边距)
  • 父级和第一个/最后一个子元素(无论是父元素设置了margin还是子元素设置了margin或是父子元素都设置了margin,在没有其它属性影响的情况下,都会发生合并)
  • 空块级元素的合并

阻止margin发生合并的方法

  • 使用border、padding的设置代替margin
  • 利用BFC
  • 增加其余行内元素使其相隔开

margin合并的规则

  • 正正取大值
  • 正负值相加
  • 负负最负值

margin的值为auto

margin的初始值为0,auto的含义是“剩余空间”

  • 如果一侧是定值,一侧是auto,那么auto为剩余空间的大小。
  • 如果两侧的值都是auto,那么就平分剩余空间
  • auto起作用的条件,在设置的方向上具有“自动填充的特性”(div元素在没有设置宽度的情况下自动填充父级宽度)

margin:auto的垂直居中设置

  • 流特性默认在水平方向上,元素如果设置了margin:auto那么会在水平方向上居中,如果一侧设置了margin-left:auto那么元素就会水平居右,这个和内联元素的text-align属性如出一辙。但是如果想要利用auto值来设置垂直方向上面的居中,就需要在垂直方向上具有“自动填充特性”。
.father{
  position:relative;
  width:800px;
  height:800px;
}
.son{
  position:absolute;
  top:0;
  right:0;
  bottom:0;
  left:0;
  width:200px;
  height:200px;
  margin:auto;
}

margin元素无效的情形

  • 内联元素的垂直方向margin设置无效
  • 表格中的<tr> <td> display:table-cell table-row 元素的margin无效
  • margin发生了合并,再去修改margin的值,无效
  • 绝对定位非定位方的margin无效(left:20px margin-right无效)
  • 定高容器的定高子元素的margin-bottom,定宽容器的定宽子元素的margin-right

border

  • border是不支持百分比的值得
  • border-width可以设置任意像素值,但其还支持若干关键字,包括thin=1px、medium(默认值)=3px、thick=4px
  • border-style默认值为none,如果不设置就不会出现边框,其可以设置的关键字有:solid、dashed、dotted、double、inset、outset、groove、ridge
  • border-color默认采取的颜色是color,具有类似特性的css属性还有outline、box-shadow、text-shadow

border-color:transparent的巧用

  • 右下定位技巧:按照排版特性,很多属性都是根据左侧或左上侧设置边距或定位。但如果我们有遇到右侧规定间距的需求,就可以使用border来救场
  • 优雅的增加定位元素的点击区域的大小:如果我们使用padding,那么定位元素就会改变,但如果使用border就可以在不改变定位的情况下改变增大点击区域

不仅padding+margin可以实现等高布局,border同样也可以,原理为border为盒子的一部分,盒子变高,border会随之变高。demo

掌握并利用好padding、margin、border的特性,可以帮助我们巧妙的写出兼容性极好的排版与布局