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的比例,兼容性极好
- 绘制图形:icon图形绘制
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的特性,可以帮助我们巧妙的写出兼容性极好的排版与布局