# 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 时效果
image-20220714204010684-16591725687611 image-20220714203954791

# 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 时效果
image-20220714204010684-16591725687611 image-20220714204236838

# 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 时效果
image-20220714204557589 image-20220714204439234

# 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 时效果
image-20220714204557589 image-20220714204709260

# 二、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 时效果
image-20220714204557589 image-20220714211237283

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 时效果
image-20220730175355837 image-20220714212552181 image-20220714212530456
只给.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;
image-20220714214112074 image-20220714214224421 image-20220714214145066
子元素外边距穿透父元素与父元素的外边距合并,两都为负值,取绝对值中的最大值,则为-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
image-20220714214112074 image-20220714214940852 image-20220714215135197
子元素外边距穿透父元素与父元素外边距合并,两者只有一个值是负数数,两者相加,相加后的结果为最终合并的外边距,则为-30px 子元素外边距穿透父元素与父元素外边距合并,两者只有一个值是负数数,两者相加,相加后的结果为最终合并的外边距,则为 30px

# 三、margin 负值应用场景和最佳实践

TIP

margin 负值的经典布局应用场景和最佳实践

# 1、等高布局

TIP

不管左边蓝色盒子中内容多少,其高度都会随着右边的粉色盒子变高的效果。

image-20220722190819065

点击查看完整源代码
<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、一行多列网格布局

image-20220722191437867

点击查看完整源代码
<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、头像叠加效果

image-20220722192635223

点击查看完整源代码
<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;

image-20220730185050534

点击查看完整源代码
<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、圣杯布局 与 双飞翼布局

这两种布局的优点:

  • 中间一栏内容最重要,最先加载和渲染,同时对搜索引擎优化最利。
  • 两边内容固定,中间内容自适应

# 圣杯布局

image-20220503172535873

点击查看完整源代码
<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>

# 双飞翼布局

image-20220503122341280-16515518235302

点击查看完整源代码
<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>
上次更新时间: 6/8/2023, 9:23:17 PM

大厂最新技术学习分享群

大厂最新技术学习分享群

微信扫一扫进群,获取资料

X