我以前不知道的 margin

lxg337 9年前發布 | 15K 次閱讀 HTML 前端技術

margin 與容器之間的關系

margin 可以改變容器尺寸

標準盒模型與元素尺寸

元素尺寸

  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 }</code></pre>

如何利用這一特性?

一側定寬的自適應布局

栗子

<div class="out">
    <img width="100" style="float: left" src="https://simg.open-open.com/show/e3ca279c3745484247217b9cea42a6c2.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://simg.open-open.com/show/e3ca279c3745484247217b9cea42a6c2.png" />
</div>
// 修改 img 的 margin-bottom
img {
    margin-bottom: 50px;
}

.out { background: green; text-align: center; }</code></pre>

如何利用這一特性?

滾動容器內上下留白

栗子

<div class="out">
    <img width="500" src="https://simg.open-open.com/show/e3ca279c3745484247217b9cea42a6c2.png" />
</div>
.out {
    padding: 50px 0;
    height: 200px;
    overflow: auto;
}

img { margin: 50px 0; }</code></pre>

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; }</code></pre>

一些條件限制

  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 的作用機制

你已經知道的事實

  • 元素有時候,就算沒有設置 width / height,也會自動填充;
div {
    background: red;
}
div {
    position: absolute;
    left: 0;
    right: 0;
}
  • 如果設置 width / height,自動填充特性就會被覆蓋
div {
    width: 200px;
}
// 此時 margin 是 0;
  • 原來應該填充的尺寸被 width / height 強制變更,而 margin: auto 就是為了填充這個變更尺寸設計的;
div {
    width: 200px;
    margin-right: 100px;
    margin-left: auto;
}
  • 為什么圖片 margin: 0 auto; 布局?解決~
  • 為什么明明容器定高,元素定高,margin: auto 0; 無法垂直居中?解決~
  • 那我們垂直方向的話,margin 就無解了嗎?
  • writing-mode: vertical-lr
  • 絕對定位元素的 marin: 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; }</code></pre>

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; }</code></pre>

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://simg.open-open.com/show/e3ca279c3745484247217b9cea42a6c2.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 
  4. position: absolute 與 margin (絕對定位元素非定位放線的 margin 值“無效” relative)
  5. 內聯特性導致的 margin 無效
<!--測試例子5-->
<div style="height: 200px; background: yellow">
    <img width="200" src="https://simg.open-open.com/show/e3ca279c3745484247217b9cea42a6c2.png" />
</div>

margin-start / margin-end 的了解

  • 正常的流向,margin-start 等同于 margin-left,兩者重疊不累加;
  • 如果水平流是從右往左,margin-start 等同于 margin-right;
  • 垂直流(writing-mode: vertical-*;),margin-start 等同于 margin-top;

margin-before / after

margin-collapse

當元素發生 margin 重疊的時候,具體該如何表現

  • collapse
  • discard
  • separate

 

 

來自:https://github.com/lishengzxc/bblog/issues/18

 

 本文由用戶 lxg337 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!