lishengzxc / bblog

My Blog
https://github.com/lishengzxc/bblog/issues
178 stars 8 forks source link

我以前不知道的 margin #18

Open lishengzxc opened 7 years ago

lishengzxc commented 7 years ago

margin 与容器之间的关系

margin 可以改变容器尺寸

标准盒模型与元素尺寸

https://gw.alicdn.com/tps/TB1vbsxOXXXXXcUXFXXXXXXXXXX-499-463.png

元素尺寸

  1. 可视尺寸 - clientWidth (实线)
  2. 占据尺寸 - outerWidth (虚线)

margin 与可视尺寸

  1. 适用于没有设定 width / height 的普通 block 元素 float absolute fixed inline table-cell
  2. 只适用于水平方向尺寸
  3. 正负值亦可

栗子

<div class="out">
    <div class="in">
    i am a block element
    </div>
</div>
.out {
    padding: 50px;
    background: red;
}

// 调整 .in 的 margin
.in {
    margin: 50px 20px;
    background: green
}

如何利用这一特性?

一侧定宽的自适应布局

栗子

<div class="out">
    <img width="100" style="float: left" src="https://gw.alicdn.com/tps/TB1vbsxOXXXXXcUXFXXXXXXXXXX-499-463.png" />
    <p>我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字</p>
</div>
p {
    margin-left: 120px;
}

margin 与占据尺寸

  1. block / inline-block 水平元素都适用
  2. 与有没有设定 width / height 无关
  3. 适用于水平和垂直方向

栗子

<div class="out">
    <img width="150" src="https://gw.alicdn.com/tps/TB1vbsxOXXXXXcUXFXXXXXXXXXX-499-463.png" />
</div>
// 修改 img 的 margin-bottom
img {
    margin-bottom: 50px;
}

.out {
    background: green;
    text-align: center;
}

如何利用这一特性?

滚动容器内上下留白

栗子

<div class="out">
    <img width="500" src="https://gw.alicdn.com/tps/TB1vbsxOXXXXXcUXFXXXXXXXXXX-499-463.png" />
</div>
.out {
    padding: 50px 0;
    height: 200px;
    overflow: auto;
}

img {
    margin: 50px 0;
}

margin 的百分比单位

  • 普通元素的百分比 margin 都是相对于容器的宽度
  • 绝对定位元素的百分比 margin 是相对于第一个定位祖先元素的宽度

如何利用这一特性?

宽高比例保持的自适应容器

栗子

<div class="out">
    <div class="box">
    </div>
</div>
.out {
    background: green;
    overflow: hidden;
}
// margin 重叠
.box {
    margin: 50%;
}

margin 重叠

产生 margin 重叠的条件

  1. 必须 block 元素
  2. 不考虑 writing-mode 的话,只发生在垂直方向

margin 重叠的情形

  1. 相邻兄弟元素
  2. 父级和第一个 / 最后一个子元素
  3. 空的 block 元素

相邻兄弟元素

栗子

<p>第一行</p>
<p>第二行</p>
p {
    line-height: 2em;
    margin: 1em 0;
    background: green;
}

父级和第一个 / 最后一个子元素

栗子

<div class="p" style="margin-top: 80px">
    <div class="c" style="margin-top: 80px">我是子</div>
</div>
.p {
    background: yellow;
}

父子 margin 重叠的其他条件

margin-top 重叠

  1. 父元素不是 BFC
  2. 父元素没有 border-top
  3. 父元素没有 padding-top
  4. 父元素和第一个子元素之间没有 inline 元素分割

margin-bottom 重叠

  1. 父元素不是 BFC
  2. 父元素没有 border-top
  3. 父元素没有 padding-top
  4. 父元素和第一个子元素之间没有 inline 元素分割
  5. 父元素没有设置 height min-height max-height

空的 block 元素

栗子

<div class="p">
    <div class="c"></div>
</div>
.p {
    background: green;
    overflow: hidden;
}

.c {
    margin: 10px;
}

一些条件限制

  1. 没 border
  2. 没 padding
  3. 内没 inline 元素
  4. 没 height / min-height

margin 重叠的计算规则

  1. 正正取大值
  2. 正负值相加
  3. 负负最小值

margin 重叠的意义

最初

<h2>h2</h2>
<p>p1</p>
<p>p2</p>
<ul>
  <li>l1</li>
  <li>l2</li>
  <li>l3</li>
</ul>

margin 的 auto

maring: auto 的作用机制

你已经知道的事实

div {
    background: red;
}
div {
    position: absolute;
    left: 0;
    right: 0;
}
div {
    width: 200px;
}
// 此时 margin 是 0;
div {
    width: 200px;
    margin-right: 100px;
    margin-left: auto;
}

例子

.p {
    position: relative;
    height: 500px;
}
.c {
    positon: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
}
.p {
  display: flex;
  height: 500px;
  background: green;
}

.c {
  margin: auto;
  height: 100px;
  width: 100px;
  background: yellow;
}

margin 负值定位

1. 两端对齐

<div class="box">
  <div class="p">
    <div class="c"></div>
    <div class="c"></div>
    <div class="c"></div>
  </div>
</div>
.box {
  width: 1200px;
  background: red;
}

.p {
  margin-right: -20px;
  overflow: hidden;
}

.c {
  width: 386.66px;
  height: 300px;
  background: yellow;
  float: left;
  margin-right: 20px;
}

2. margin 负值下的等高布局

.box {
    overflow: hidden;
}
.cl, .cr {
    float: left;
}
.cl {
    background: red;
}
.cr {
    background: yellow;
}

3. margin 负值下的两栏自适应布局

元素占据空间跟随 margin 移动

<div class="out">
    <img width="100" style="float: right;" src="https://gw.alicdn.com/tps/TB1vbsxOXXXXXcUXFXXXXXXXXXX-499-463.png" />
    <p>我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字</p>
</div>
p {
    margin-right: 120px;
}

DOM 顺序和视觉不符,那么这样~

<div style="float: left; width: 100%;">
    <p style="margin-right: 120px"></p>
</div>
<img width="100" style="float: left; margin-left: -150px" />

margin 无效情形解析

  1. inline 元素垂直 margin 天然无效
  2. 可能 margin 重叠了
  3. display: table-cell 与 margin https://developer.mozilla.org/en-US/docs/web/css/margin
  4. position: absolute 与 margin (绝对定位元素非定位放线的 margin 值“无效” relative)
  5. 内联特性导致的 margin 无效
<!--测试例子5-->
<div style="height: 200px; background: yellow">
    <img width="200" src="https://gw.alicdn.com/tps/TB1vbsxOXXXXXcUXFXXXXXXXXXX-499-463.png" />
</div>

margin-start / margin-end 的了解

margin-before / after

margin-collapse

当元素发生 margin 重叠的时候,具体该如何表现