1、display为inline(不包括inline-block和替换元素)的元素的padding和margin垂直方向都不会影响布局,即不会改变和上下盒子的间隔,但会改变其盒子的内外尺寸(改变外尺寸不会有效果,无任何表现),内尺寸表现在背景会叠加,如下图:
2、margin合并只出现在上下相邻或父子相邻的块级元素之间,其它的即便天然使元素块状化的浮动和绝对定位都不能使margin合并。需要注意的是,浮动和绝对定位会使元素的display的值为block(可通过js获取查看),但其表现却和display为inline-block大致,呈现包裹性。或者说display的值只有在流内才能发挥作用,当脱离流,display的值已无意义。
const span = document.querySelector('.float-span');
console.log('值:', window.getComputedStyle(span).display);//值为block
3、元素的margin和padding的百分比值(无论上下左右)都是相对元素的宽度计算,但由于margin合并的存在,不会存在很大的意义。在元素充分利用可用空间的时候,margin的负值是可以改变元素的内部尺寸即padding box,默认的只有在水平方向上可能充分利用可利用空间。在不是充分利用可利用空间的情形下则是改变元素的外部尺寸即margin box,也就是改变元素和其它元素的位置关系,需要注意的是这些改变仅对块级元素存在作用,行内元素请参考1。
4、margin合并的条件和场景
条件: (1)块级元素之间 (2)发生在与流方向相垂直的方向(默认流方向的是水平方向)
场景:
(1)相邻兄弟块级元素合并,如
p{margin:10px;}
<p>1</p>
<p>2</p>
(2) 父子元素的合并, 第一个子元素和父元素或最后一个子元素和父元素,如
<div>
<p>first son</p>
<span>second son</span>
<p>last son </p>
</div>
上面两个p元素在没有阻断margin合并的条件下如果有margin都会发生合并,对于这种情况的合并可以通过以下方法阻断
1)父元素设置为块级上下文元素,最方便的就是设置overflow为非visible值
2)父元素设置border或padding
3)父子元素之间添加内联元素就是隔断
对于最后一个子元素和父元素的合并,除以上方法还可以设置height、min-height或max-height
(3)空块级元素之间自己margin的合并,如
<div></div>
如这个空div元素自己同时设置了margin-top和margin-bottom,那么这两者会发生合并
合并计算规则: ’正正取大值’,‘正负值相加’ ,‘负负最负值’,即当合并的两个margin值都是正值的时候,合并的结果值就是两个值中大的那个,当合并的两个值一正一负的时候,合并的结果值就是两者的和,而两个值都是负值的时候,其结果就是较小的那个负值。
5、margin的默认值是0,为auto时则为其分配剩余可用空间,这也是为什么两侧都设置了auto元素表现为居中,当只设置为margin-left:auto的时候,左外边距会获得所有的剩余空间,其结果为右对齐,另外触发margin:auto的条件是当元素的width或height为auto的时候,其会在对应方向填充,很明显去掉height,垂直方向并不会居中,所以margin:auto不会垂直居中,但可以通过改变流的方向,writing-mode:vertical-lr;使其变成垂直流,需要知道这样子后文字也是从上到下排,而且这样子之后无法水平居中。
6、利用margin:auto实现垂直水平居中,当元素表现为格式化高度的时候,其垂直方向的auto也是可以生效的。
.father {
width: 500px;
height: 400px;
margin: 0 auto;
background-color: blue;
position: relative;
}
.son {
width: 200px;
height: 100px;
background-color:red;
margin: auto;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
上面代码,son元素将会在father元素中水平垂直居中,另外对于替换元素,当display设置为block,margin计算规则同样适用。
另外格式化宽度或高度只有在width或height不设置的情况下才会生效,当width或height设置之后只会表现为对应值的宽高。
7、margin无效的情况
除了1中所说明的display为inline的非替换元素在垂直方向之外,还有以下情况,
(1)display的计算值为table-cell或table-row,table的tr、td就属于这种情况,故它们的margin无效
(2)发生margin合并之后,修改margin可能无效,你有可能修改的margin是比较小的那个。
(3)绝对定位元素未定位方位的margin无效,即只设置了left或top,那么right或bottom方向上的margin无效,这是由于绝对定位元素的渲染是独立的,所以无法和其它兄弟元素产生联系,这样margin就无法发挥作用。
(4)左侧有一个float:left的块,其宽度为100px,那么右侧的元素设置margin-left在负无穷到100px的范围内是无效的,大于100px才会影响内容的位置。
(5)在一个容器内有一张图片,随着margin的负值图片上移,但当到达某一个负值的时候,继续减小margin的值,图片不再上移,margin似乎无效了。