margin属性的值为百分比值时,无论是水平方向还是垂直方向,都是相对宽度计算的
margin负值的效果
- margin-top 负值,元素向上移动
- margin-left 负值,元素向左移动
- margin-right 负值,右侧元素左移,自身不受影响
- margin-bottom 负值,下方元素上移,自身不受影响
margin合并的场景
内联替换元素,垂直margin有效,并且没有margin合并的问题,所以图片永远不会发生margin合并。
1. 相邻兄弟元素margin合并
<template> <div> <p>第1行</p> <p>第2行</p> </div> </template> <style scoped> p { margin: 10px 0px; } </style>
第1行的下margin和第2行的上margin发生了合并,最终两行的间的间距只有10px
2. 父级和第一个/最后一个子元素
<template> <div> <!--形式一--> <div class="father"> <div class="son" style="margin-top:80px;">子元素有margin-top</div> </div> <!--形式二--> <div class="father" style="margin-top:80px;"> <div class="son">父元素有margin-top</div> </div> <!--形式三--> <div class="father" style="margin-top:80px;"> <div class="son" style="margin-top:80px;">父子元素都有margin-top</div> </div> </div> </template> <style scoped> .father { background: red; height: 100px; } .son { background: green; height: 20px; } </style>
无论是父/子元素单独设置margin,还是都设置margin,margin都合并到了父元素上
阻止margin-top合并的方法
满足以下任一条件即可
- 父元素设置为块状格式化上下文元素;(如添加样式 overflow: hidden;)
- 父元素设置border-top值;
- 父元素设置padding-top值;
- 父元素和第一个子元素之间添加内联元素进行分隔。
阻止margin-bottom合并的方法
满足以下任一条件即可
- 父元素设置为块状格式化上下文元素;(如添加样式 overflow: hidden;)
- 父元素设置border-bottom值;
- 父元素设置padding-bottom值;
- 父元素和最后一个子元素之间添加内联元素进行分隔;
- 父元素设置height、min-height或max-height。
3. 空块级元素的margin合并
<template> <div class="father"> <div class="son"></div> </div> </template> <style scoped> .father { overflow: hidden; background: red; } .son { margin: 10px 0; } </style>
子元素的margin-top和margin-bottom合并,最终父元素的高度只有10px
阻止空div元素的margin合并
- 设置垂直方向的border;
- 设置垂直方向的padding;
- 里面添加内联元素(直接Space键空格是没用的);
- 设置height或者min-height。
margin合并的计算规则
- 两个正/负margin合并,取绝对值最大的margin, 如 20px和30px合并得到30px, -50px与-20px合并得到-50px
- 一正一负的margin,则相加求和得到最终的margin,如 50px-20px = 30px , -50px+30px = -20px
margin合并的重要意义
大部分html标签都有默认的margin值(防止图文挤到一块),若无margin合并机制,标签间的间距就会很大,不利于图文信息的展示
margin:auto的填充规则
margin的'auto'是具有强烈的计算意味的关键字,用来计算元素对应方向应该获得的剩余间距大小。
如果里面的元素尺寸大,水平方向auto计算后的负值会被当作0来处理,但垂直方向计算后的负值则会保留
(1)如果一侧定值,一侧auto,则auto为剩余空间大小。
.father { width: 300px; } .son { width: 200px; margin-right: 80px; margin-left: auto; }
最终.son的左边距20px、右边距80px
因margin的初始值大小是0,所以若只有margin-left: auto; 没有margin-right,则得到元素右对齐的效果
.son { width: 200px; margin-left: auto; }
div在div中水平垂直居中的方法可以参考链接
https://blog.csdn.net/weixin_41192489/article/details/115144302
margin失效的场景
- display计算值inline的非替换元素的垂直margin是无效的
- 表格中的tr和td元素或者设置display计算值是table-cell或table-row的元素的margin都是无效的。
- 发生margin合并时,改变绝对值较小的margin是无效的,除非改变后,它的绝对值最大,或者符号相反
- 绝对定位元素非定位方位的margin值“无效”
.box { position: absolute; top: 10%; left: 30%; margin-right: 30px; }
此时right和bottom值属于auto状态,也就是右侧和底部没有进行定位,此时,这两个方向设置margin值我们在页面上是看不到定位变化的。
- 定高容器的子元素的margin-bottom或者宽度定死的子元素的margin-right的定位“失效”。
<div class="box"> <div class="child"></div> </div> .box { height: 100px; } .child { height: 80px; margin-bottom: 100px; }
或
.box { width: 100px; } .child { width: 80px; margin-right: 100px; }
原因在于,若想使用margin属性改变自身的位置,必须是和当前元素定位方向一样的margin属性才可以,否则,margin只能影响后面的元素或者父元素。
例如,一个普通元素,在默认流下,其定位方向是左侧以及上方,此时只有margin-left和margin-top可以影响元素的定位。但是,如果通过一些属性改变了定位方向,如float:right或者绝对定位元素的right右侧定位,则反过来margin-right可以影响元素的定位,margin-left只能影响兄弟元素。
- 鞭长莫及导致的margin无效
<div class="box"> <img src="mm1.jpg"> <p>内容</p> </div> .box > img { float: left; width: 256px; } .box > p { overflow: hidden; margin-left: 200px; }
- 内联特性导致的margin无效
<div class="box"> <img src="mm1.jpg"> </div> .box > img { height: 96px; margin-top: -200px; }