# margin 负值的最佳实践
TIP
margin 负值是面试中必问的一个核心知识点 !因此,大家必需要掌握
# 一、margin 负值特性
TIP
- margin-left 设置负值,元素自身向左移动,后面的元素也向左移
- margin-right 设置负值,自身不受影响,右边元素向左移动
- margin-top 设置负值,元素自身向上移动 ,下面的元素也向上移
- margin-bottom 设置负值,自身不受影响,下方元素向上移动
# 1、margin-left 负值
TIP
margin-left
设置负值,元素自身向左移动,后面的元素也向左移
<style>
.container {
width: 200px;
height: 100px;
border: 2px solid red;
margin: 50px auto;
}
.box {
width: 100px;
height: 100px;
float: left;
}
.box1 {
/* 背景色为粉色 */
background-color: rgb(252, 188, 198);
/* 负值,元素自身向左移动,后面元素也向左移 */
margin-left: -50px;
}
.box2 {
/* 背景色为天蓝色 */
background-color: rgb(136, 208, 237, 0.5);
}
</style>
<body>
<div class="container">
<div class="box box1"></div>
<div class="box box2"></div>
</div>
</body>
.box1 未加负值时效果 | .box1 添加 margin-left:-50px 时效果 |
---|---|
# 2、margin-right 负值
TIP
margin-right
设置负值,自身不受影响,右边元素向左移动
<style>
.container {
width: 200px;
height: 100px;
border: 2px solid red;
margin: 50px auto;
}
.box {
width: 100px;
height: 100px;
float: left;
}
.box1 {
/* 背景色为粉色 */
background-color: rgb(252, 188, 198);
/* 负值,元素自身不受影响,后面元素向左移动 */
margin-right: -50px;
}
.box2 {
/* 背景色为天蓝色 */
background-color: rgb(136, 208, 237, 0.5);
}
</style>
<body>
<div class="container">
<div class="box box1"></div>
<div class="box box2"></div>
</div>
</body>
.box1 未加负值时效果 | .box1 添加 margin-right:-50px 时效果 |
---|---|
# 3、margin-top 负值
TIP
设置负值,元素自身向上移动 ,下面的元素也向上移
<style>
.container {
width: 100px;
height: 200px;
border: 2px solid red;
margin: 150px auto;
}
.box {
width: 100px;
height: 100px;
}
.box1 {
/* 背景色为粉色 */
background-color: rgb(252, 188, 198);
/* 负值,元素自身向上移动50PX,会影响后面元素位置 */
margin-top: -50px;
}
.box2 {
/* 背景色为天蓝色 */
background-color: rgb(136, 208, 237, 0.5);
}
</style>
<body>
<div class="container">
<div class="box box1"></div>
<div class="box box2"></div>
</div>
</body>
.box1 未加 margin 负值时效果 | .box1 添加 margin-top:-50px 时效果 |
---|---|
# 4、margin-bottom 负值
TIP
margin-bottom 设置负值,自身不受影响,下方元素向上移动
<style>
.container {
width: 100px;
height: 200px;
border: 2px solid red;
margin: 150px auto;
}
.box {
width: 100px;
height: 100px;
}
.box1 {
/* 背景色为粉色 */
background-color: rgb(252, 188, 198);
/* 负值,元素自身向左移动,会影响后面元素位置 */
margin-bottom: -50px;
}
.box2 {
/* 背景色为天蓝色 */
background-color: rgb(136, 208, 237, 0.5);
}
</style>
<body>
<div class="container">
<div class="box box1"></div>
<div class="box box2"></div>
</div>
</body>
.box1 未加 margin 负值时效果 | .box1 添加 margin-bottom:-50px 时效果 |
---|---|
# 二、margin 塌陷时合并规则
TIP
- margin 重叠也叫:外间距重叠 、或外边距合并、或外边距穿透、或外边距塌陷。
- margin 重叠只针对垂直方向,不针对水平方向。
发生的情况的情况:
- 1、兄弟元素之间- 上下外边距合并(重叠)
- 2、父子元素之间-上外边距合并(穿透)(父元没有设置内边距和边框时才会发生合并)
外边距重叠计算规则
- 1、全部都为正值,取最大者;
- 2、不全是正值,则两者相加,得到的结果为最终移动距离
- 3、都为负值,则都取绝对值最大的那个
# 1、兄弟元素间合并,都为负值
TIP
margin-bottom 与 margin-top 都为负值时,都取绝对值最大的那个
<style>
.container {
width: 100px;
height: 200px;
border: 2px solid red;
margin: 150px auto;
}
.box {
width: 100px;
height: 100px;
}
.box1 {
background-color: pink;
/* 下面元素向上移动 50px*/
margin-bottom: -50px;
}
.box2 {
background-color: rgb(131, 202, 229, 0.5);
/* 元素自身向上移动80px */
margin-top: -80px;
}
</style>
<body>
<div class="container">
<div class="box box1"></div>
<div class="box box2"></div>
</div>
</body>
.box1 与.box2 都未设置 margin 属性时 | .box1 中 margin-bottom:-50x; .box2 中 margin-top:-80px 时效果 |
---|---|
margin 上外边距与下外边距都是负值时,取两者中绝对值中最大的那一个,则最终以 margin-top:-80px 为主,.box2 蓝色盒子向上移动 80px
# 2、兄弟元素间合并,一正一负
TIP
margin-top 与 margin-bottom 之间有一个负值时,两者相加,得到的结果,为最终移动距离。
<style>
.container {
width: 100px;
height: 200px;
border: 2px solid red;
margin: 150px auto;
}
.box {
width: 100px;
height: 100px;
}
.box1 {
background-color: pink;
/* 下面元素向下移动50px */
margin-bottom: 50px;
}
.box2 {
background-color: rgb(131, 202, 229, 0.5);
/* 元素自身向上移动 30px */
margin-top: -30px;
/* 元素自身向上移动 80px */
margin-top: -80px;
}
</style>
<body>
<div class="container">
<div class="box box1"></div>
<div class="box box2"></div>
</div>
</body>
当.box1 中设置 margin-bottom:50px 时,其中.box2 中的 margin 属性分别设置以下不同值时的效果如下
.box2 中未设置 margin 属性 | .box2 mrgin-top:-30px 时效果 | .box2 margin-top:-80px 时效果 |
---|---|---|
只给.box1 加了 margin-bottom:50px,则下面的元素向下移动 50px 的间距 | 兄弟元素间的上下外边距发生合并,两者中有一个为负值时,两值相加,得到的最终结果为合并后的外边距大小:50+(-30)=20 则两者间距为 20px | 兄弟元素间的上下外边距发生合并,两者中有一个为负值时,两值相加,得到的最终结果为合并后的外边距大小:50+(-80)=-30 则下面元素向上移动 30px |
# 3、父子元素之间合并,都为负值
TIP
margin-top 与 margin-bottom 之间都为负值时,两者合并时,取绝对值最大的那个
<style>
.container {
width: 200px;
height: 200px;
margin: 150px auto;
border: 2px solid red;
}
.box {
/* 背景颜色为黄色 */
background-color: khaki;
height: 130px;
/* 元素自身向上移动50px */
margin-top: -50px;
}
.box1 {
width: 100px;
height: 100px;
background-color: rgb(252, 191, 201, 0.7);
/* 元素自身向上移动40px */
margin-top: -40px;
/* 元素自身向上移动100px */
margin-top: -100px;
}
</style>
<body>
<div class="container">
<div class="box">
<div class="box1"></div>
</div>
</div>
</body>
正常情况,.box 与.box1 都未设置 margin 时 | .box 的 margin-top:-50px 和.box1 的 margin-top:-100px; | .box 的 margin-top:-50px 和.box1 的 margin-top:-40px; |
---|---|---|
子元素外边距穿透父元素与父元素的外边距合并,两都为负值,取绝对值中的最大值,则为-100px | 子元素外边距穿透父元素与父元素的外边距合并,两都为负值,取绝对值中的最大值,则为-50px |
# 4、父子元素之间合并,一正一负
TIP
margin-top 与 margin-bottom 之间有一个为负值时,两者相加,得到的值为最终移动距离
<style>
.container {
width: 200px;
height: 200px;
margin: 150px auto;
border: 2px solid red;
}
.box {
/* 背景颜色为黄色 */
background-color: khaki;
height: 130px;
/* 元素自身向上移动50px */
margin-top: -50px;
}
.box1 {
width: 100px;
height: 100px;
/* 背景颜色为粉色 */
background-color: rgb(252, 191, 201, 0.7);
/* 元素与父元素有20px间距 */
margin-top: 20px;
/* margin-top:80px; */
}
</style>
<body>
<div class="container">
<div class="box">
<div class="box1"></div>
</div>
</div>
</body>
正常情况,.box 与.box1 都未设置 margin 时 | .box 的 margin-top:-50px 与.box1 的 margin-top:20px | .box 的 margin-top:-50px 与.box1 的 margin-top:80px |
---|---|---|
子元素外边距穿透父元素与父元素外边距合并,两者只有一个值是负数数,两者相加,相加后的结果为最终合并的外边距,则为-30px | 子元素外边距穿透父元素与父元素外边距合并,两者只有一个值是负数数,两者相加,相加后的结果为最终合并的外边距,则为 30px |
# 三、margin 负值应用场景和最佳实践
TIP
margin 负值的经典布局应用场景和最佳实践
# 1、等高布局
TIP
不管左边蓝色盒子中内容多少,其高度都会随着右边的粉色盒子变高的效果。
点击查看完整源代码
<style>
.box {
width: 520px;
border: 2px solid red;
overflow: hidden;
}
/* 清除浮动 */
.clearfix::after {
display: block;
content: "";
clear: both;
}
.left {
width: 200px;
float: left;
background-color: skyblue;
/* 内边距2000px使盒子高度变高 */
padding-bottom: 2000px;
/* 底外边距-2000px,抵消内边距2000px产生的占位 */
margin-bottom: -2000px;
}
.right {
width: 300px;
background-color: pink;
float: right;
}
</style>
<body>
<div class="box clearfix">
<!-- 左边 -->
<div class="left">111</div>
<!-- 右边 -->
<div class="right">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>
</div>
</div>
</body>
# 2、一行多列网格布局
点击查看完整源代码
<style>
body,
ul {
margin: 0;
}
ul {
list-style: none;
padding: 0;
/* 多余留1px,用来给第一个li的左边框 */
margin-left: 1px;
}
.box {
width: 801px;
height: 200px;
margin: 50px auto;
}
ul li {
width: 199px;
height: 198px;
border: 1px solid red;
float: left;
/* 使元素自身向左移动1px,用来覆盖掉前面元素的右边框线 */
margin-left: -1px;
}
</style>
<body>
<div class="box">
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</body>
# 3、头像叠加效果
点击查看完整源代码
<style>
.head {
height: 100px;
/* 去掉行内块元素间默认的空白间隙 */
font-size: 0;
/* 内容水平居中显示 */
text-align: center;
line-height: 100px;
}
.head span {
display: inline-block;
border: 4px solid #fff;
width: 50px;
height: 50px;
background-color: skyblue;
border-radius: 52px;
/* 垂直居中对齐 配合父元的line-height:50px */
vertical-align: middle;
/* 元素向左移动20px */
margin-left: -20px;
}
.head span img {
width: 100%;
height: 100%;
border-radius: 50%;
}
</style>
<body>
<div class="head">
<span><img src="./images/tx1.jpg" alt="" /></span>
<span><img src="./images/tx2.jpg" alt="" /></span>
<span><img src="./images/tx3.jpg" alt="" /></span>
<span><img src="./images/tx4.jpg" alt="" /></span>
</div>
</body>
# 4、元素水平垂直居中
TIP
margin 负值与 position 定位,实现元素水平垂直居中效果
/*
先利用绝对定位
让元素的顶部和左侧分别与父元素垂直和水平中间对齐
然后再利用margin负值,让元素向上和向左移动自身宽度的一半
这样就实现了水平和垂直居中
*/
/* 绝对定位 */
position: absolute;
top: 50%;
left: 50%;
/* 向上移动自身宽度一半 */
margin-top: -50px;
/* 向左移动自身宽度一半 */
margin-left: -50px;
点击查看完整源代码
<style>
.box {
width: 300px;
height: 300px;
background-color: skyblue;
/* 相对定位 */
position: relative;
}
.item {
width: 100px;
height: 100px;
background-color: khaki;
/* 绝对定位 */
position: absolute;
top: 50%;
left: 50%;
/* 向上移动自身宽度一半 */
margin-top: -50px;
/* 向左移动自身宽度一半 */
margin-left: -50px;
}
</style>
<body>
<div class="box">
<div class="item"></div>
</div>
</body>
# 5、圣杯布局 与 双飞翼布局
这两种布局的优点:
- 中间一栏内容最重要,最先加载和渲染,同时对搜索引擎优化最利。
- 两边内容固定,中间内容自适应
# 圣杯布局
点击查看完整源代码
<style>
body {
margin: 0;
/*核心代码*/
min-width: 650px;
}
/* 清除浮动 */
.clearfix::after {
display: block;
content: "";
clear: both;
}
.fl {
float: left;
}
.header {
height: 100px;
background-color: tomato;
}
.container {
padding-left: 200px;
padding-right: 250px;
}
.container .center {
width: 100%;
height: 300px;
background-color: skyblue;
}
.container .left {
width: 200px;
height: 300px;
background-color: cadetblue;
/*核心代码*/
margin-left: -100%;
position: relative;
left: -200px;
}
.container .right {
width: 250px;
height: 300px;
background-color: aquamarine;
/*核心代码*/
margin-right: -250px;
}
.footer {
height: 100px;
background-color: #000;
}
</style>
<body>
<div class="header">头部</div>
<div class="container clearfix">
<div class="center fl">中间</div>
<div class="left fl">左边</div>
<div class="right fl">右边</div>
</div>
<div class="footer">底部</div>
</body>
# 双飞翼布局
点击查看完整源代码
<style>
body {
margin: 0;
}
.fl {
float: left;
}
.main {
background-color: #ddd;
width: 100%;
}
.main .main-content {
background-color: skyblue;
height: 300px;
/*核心代码*/
margin: 0 200px 0 200px;
}
.left {
width: 200px;
height: 300px;
background-color: coral;
/*核心代码*/
margin-left: -100%;
}
.right {
width: 200px;
height: 300px;
background-color: tomato;
/*核心代码*/
margin-left: -200px;
}
</style>
<body>
<div class="main fl">
<div class="main-content">中间</div>
</div>
<div class="left fl">左边</div>
<div class="right fl">右边</div>
</body>
大厂最新技术学习分享群
微信扫一扫进群,获取资料
X