CSS学习【margin为负值】

目录

margin塌陷时合并规则

margin重叠概念

可能会发生的情况

外边距重叠计算规则

兄弟元素之间合并,都为负值

当".box1"和".box2"都未设置外间距时:

给".box1"和".box2"设置外间距后:

兄弟元素间合并,一正一负

当.box2中未设置margin属性

[.box2 margin-top:-30px时](#.box2 margin-top:-30px时)

[.box2 margin-top:-80px时](#.box2 margin-top:-80px时)

父子元素之间合并,都为负值

box与box1都未设置margin时

box的margin-top:-50px和box2的magin-top:-100px时

box的margin-top:-50px和box1的margin-top:-40px

父子元素之间合并,一正一负

box和box1都未设置margin时

box的margin-top:-50px与box1的margin-top:20px

box的margin-top:-50px和box1的margin-top:80px

margin负值的实践场景

1.等高布局

2.一行多列网格布局

3.头像叠加效果

4.元素水平垂直居中

5.双飞翼布局

6.圣杯布局

margin塌陷时合并规则

margin重叠概念

  • margin重叠 也叫:外间距重叠 、或外边距合并 、或外边距穿透 、或外边距塌陷
  • margin重叠 "只针对垂直方向,不针对水平方向"

可能会发生的情况

  1. **兄弟元素之间-上下边距合并(**重叠)
  2. 父子元素之间-上外边距合并(穿透)(父元素没有设置内边距和边框时才会发生合并)

外边距重叠计算规则

  1. 全部为正值,取最大值
  2. 不全是正值,则两者相加,得到的结果为最终移动距离
  3. 都为负值,则取绝对值最大的那个

兄弟元素之间合并,都为负值

margin-bottom与margin-top都为负值时,都取绝对值最大的那个

html 复制代码
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <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>
</html>

当".box1 "和".box2 "都未设置外间距时:

给".box1 "和".box2 "设置外间距后:

margin上外边距与下外边距都是负值,取两者中绝对值最大的哪一个,最终以margin-top:-80px为主,.box2蓝色盒子向上移动80px

兄弟元素间合并,一正一负

margin-top与margin-bottom之间有一个负值时,两者相加,得到的结果,为最终移动距离

html 复制代码
<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>

当**.box2** 中未设置margin属性

只给**.box1** 加了一个margin-bottom:50px ,故两个盒子间隔50px

.box2 margin-top:-30px时

因为box1中margin-bottom:50px是个正值,一正一负,两者相加,故两个盒子间隔为(50px - 30px = 20px)

.box2 margin-top:-80px时

因为box1中margin-bottom:50px是个正值,一正一负,两者相加,故两个盒子间隔为(50px - 80px = -30px),故下面元素向上移动30px

父子元素之间合并,都为负值

html 复制代码
<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和box2的magin-top:-100px时

因为父元素box没有设置内边距和边框,故box1与父元素box外边距发生合并,又因为两者的外边距都为负值,取绝对值中最大值,则为-100px

box的margin-top:-50px和box1的margin-top:-40px

子元素外边距穿透父元素与父元素的外边距合并,两都为负值,取绝对值中的最大值,则为-50px

父子元素之间合并,一正一负

html 复制代码
<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

子元素外边距穿透父元素外边距合并,两者当中有一个值是负数,相加后的结果为最终外边距,即(-50 + 20 = -30px)

box的margin-top:-50px和box1的margin-top:80px

一正一负,最终外边距为两者相加,即(-50 + 80 = 30px)

margin负值的实践场景

1.等高布局

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

html 复制代码
        <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">12345678978989</div>
              <!-- 右边 -->
              <div class="right">
                <p>1</p>
                <p>2</p>
                <p>3</p>
                <p>4</p>
                <p>5</p>
                <p>6</p>
                <p>7</p>
                <p>8</p>
                <p>9</p>
                <p>10</p>
              </div>
            </div>
          </body>

效果图:

2.一行多列网格布局

html 复制代码
        <style>
            body,
            ul {
              margin: 0;
            }
            ul {
              list-style: none;
              padding: 0;
              /* 多余留1px,用来给第一个li的左边框  */
              /* ul是li的父元素,li的margin-left=-1px 两者发生外边距合并 */
              /* 一正一负时 外间距为两者相加 故第一个li不需要移动*/
              margin-left: 1px;
            }
            .box {
                /* 四个li+五个边框的总宽度 */
                width: 801px;
                height: 200px;
                margin: 50px auto;
            }
            ul li {
                /* 四个li的高度为796加上五个竖直边框各1px共801px */
                width: 199px;
                /* 高度加两个上下边框的高度 共198 + 2 = 200px */
                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.头像叠加效果

html 复制代码
        <style>
            .head {
              height: 100px;
              /* 去掉行内块元素间默认的空白间隙 */
              font-size: 0;
              /* 内容水平居中显示 */
              text-align: center;
              line-height: 100px;
              background-color: aquamarine;
            }
            .head > span {
              display: inline-block;
              border: 4px solid #fff;
              width: 50px;
              height: 50px;
              /* background-color: skyblue; */
              /* 弧度比img大2px 用来显示头像的外边框 */
              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="https://tse4-mm.cn.bing.net/th/id/OIP-C.PobTVuzuQy7tAZtvVEc3VQAAAA?rs=1&pid=ImgDetMain" alt="" /></span>
              <span><img src="https://tse4-mm.cn.bing.net/th/id/OIP-C.TIElyUlFJsyKMKJXgSlixAAAAA?rs=1&pid=ImgDetMain" alt="" /></span>
              <span><img src="https://tse4-mm.cn.bing.net/th/id/OIP-C.HVdWPbF8w9RDzR_VFdskegAAAA?rs=1&pid=ImgDetMain" alt="" /></span>
              <span><img src="https://ts1.cn.mm.bing.net/th/id/R-C.3c5f60c6c0ecdf2830c6512752e8846e?rik=9Ndhdvf8by89og&riu=http%3a%2f%2fimg.keaiming.com%2fuploads%2fallimg%2f2020081714%2fpp2ql1hdf0y.jpg&ehk=VkqIRMgwnATNbM0hzt%2bzsoGVL%2f17ZnbmRhylWl3r5z4%3d&risl=&pid=ImgRaw&r=0" alt="" /></span>
            </div>
          </body>

效果图:

4.元素水平垂直居中

方法很简单,先利用绝对定位让元素的左侧和顶部分别与父元素垂直和水平中间对齐,然后再利用margin负值,让元素向上和向左各移动自身宽度/高度的一半

html 复制代码
        <style>
            .father {
                position: relative;
                width: 300px;
                height: 300px;
                background-color: aqua;
            }
            .son {
                position: absolute;
                left: 50%;
                top: 50%;
                width: 100px;
                height: 100px;
                background-color: blueviolet;
                margin-left: -50px;
                margin-top: -50px;
            }
          </style>
          <body>
            <div class="father">
                <div class="son"></div>
            </div>
          </body>
</html>

效果图:

5.双飞翼布局

两边内容固定,中间内容自适应

html 复制代码
<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>

效果图:

给左边的div一个"margin-left:-100%",使其移动的距离等于中间div的宽度,因此左div被拉到中间div的左侧,再给右边的div一个"margin-right:-200px",使其移动的距离等于自身的宽度,因此右div也被拉到第一行

6.圣杯布局

相较于双飞翼布局,添加了顶部导航栏和页脚

html 复制代码
<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>

效果图:

body中的min-width计算如下:

(left和right的自身宽度 + left的额外偏移距离即200px)

相关推荐
Re.不晚14 分钟前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
GIS程序媛—椰子1 小时前
【Vue 全家桶】7、Vue UI组件库(更新中)
前端·vue.js
DogEgg_0011 小时前
前端八股文(一)HTML 持续更新中。。。
前端·html
ZL不懂前端1 小时前
Content Security Policy (CSP)
前端·javascript·面试
木舟10091 小时前
ffmpeg重复回听音频流,时长叠加问题
前端
幼儿园老大*1 小时前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
王大锤43911 小时前
golang通用后台管理系统07(后台与若依前端对接)
开发语言·前端·golang
1 小时前
开源竞争-数据驱动成长-11/05-大专生的思考
人工智能·笔记·学习·算法·机器学习
ctrey_1 小时前
2024-11-4 学习人工智能的Day21 openCV(3)
人工智能·opencv·学习
我血条子呢2 小时前
[Vue]防止路由重复跳转
前端·javascript·vue.js