1. margin 與容器尺寸
兩種容器尺寸:
- 可視尺寸:含 border 及以內(nèi)的尺寸—— clientWidth、clientHeight(標(biāo)準(zhǔn))
- 占據(jù)尺寸:含 margin 及以內(nèi)的尺寸—— outerWidth、outerWidth(非標(biāo)準(zhǔn),YY)
1.1. margin 與可視尺寸
生效條件:
- 適用于沒有設(shè)定 width/height 的普通 block 水平元素(float 就不行)。
- 只適用于水平方向尺寸(這種情況就不考慮設(shè)置 height 的情況了)。
1.2. margin 與占據(jù)尺寸
- block/inline-block 水平元素均適用
- 與有沒有設(shè)置 width/height 值無關(guān)
- 適用于水平方向和垂直方向
例子是:修改子元素的 margin-bottom: -30px,則父元素的高度減少 30px。
實(shí)例:實(shí)現(xiàn)滾動(dòng)容器上下留白的效果。如果通過在滾動(dòng)容器上使用 padding 來實(shí)現(xiàn),會(huì)發(fā)現(xiàn)在非 Chrome 瀏覽器下,底部 padding 不見了。所以通過在子元素上設(shè)置 margin 來實(shí)現(xiàn)。
2. margin 與百分比屬性值
計(jì)算規(guī)則:
- 普通元素:無論水平方向還是垂直方向都是相對于容器的 width 來計(jì)算的
- 絕對定位元素:相對于第一個(gè)具有定位屬性的祖先元素(relative/absolute/fixed)的 width 計(jì)算的
特性實(shí)例:
- 寬高 2:1 自適應(yīng)布局
.container {
/* overflow: hidden 是為了避免發(fā)生 margin 重疊的現(xiàn)象 */
overflow: hidden;
}
.container>div {
margin: 50%;
}
/* 垂直方向通過 margin 重疊,導(dǎo)致高度只有 50%;而寬度始終是 100% */
<div class="container">
<div />
</div>
3. margin 重疊
通常特性
- margin 重疊只發(fā)生在 block 水平元素(不包括 float 和 absolute 元素)
- 不考慮 writing-mode,只發(fā)生在垂直方向上(margin-top/margin-bottom)
margin 重疊的 3 種情形
- 相鄰的兄弟元素
- 父級和第一個(gè)(或最后一個(gè))子元素。這時(shí)子元素不會(huì)把父元素?fù)伍_,其表現(xiàn)為子元素的 margin 賦給了父元素,父元素位置改變。父子 margin 重疊的其他條件:
對于 margin-top 重疊
- 父元素非 BFC 元素
- 父元素沒有 border-top 設(shè)置
- 父元素沒有 padding-top 值
- 父元素和第一個(gè)子元素之間沒有 inline 元素分隔
對于 margin-bottom 重疊
- 父元素非 BFC 元素
- 父元素沒有 border-bottom 設(shè)置
- 父元素沒有 padding-bottom 值
- 父元素和最后一個(gè)子元素之間沒有 inline 元素分隔
- 父元素沒有 height, min-height, max-height 限制
- 空的 block 元素
發(fā)生重疊的條件:
- 元素沒有 border 設(shè)置
- 元素沒有 padding 值
- 里面沒有 inline 元素
- 沒有 height 和 min-height
margin 的計(jì)算規(guī)則
- 正正取大值
- 正負(fù)值相加
- 負(fù)負(fù)取小值
4. margin: auto
元素有時(shí)候,就算沒有設(shè)置 width/height,也會(huì)自動(dòng)填充滿整個(gè)容器。
比如:
- 普通水平塊元素 div
- position: absolute; left: 0; right: 0; (top: 0; bottom: 0; 可填充高度)
如果設(shè)置了 width/height,自動(dòng)填充特性就會(huì)被覆蓋。原本應(yīng)該填充的尺寸被 width/height 強(qiáng)制變更,而 margin: auto 就是為了填充這個(gè)變更的尺寸設(shè)計(jì)的。
4.1 計(jì)算規(guī)則
- 如果一側(cè)是 auto,另一側(cè)非 auto,則設(shè)置 auto 一側(cè)的 margin 為剩余空間大小。
- 如果兩側(cè)都是 auto,則平分剩余空間大小。
4.2 實(shí)例
- 實(shí)現(xiàn)水平居中。但是如果計(jì)算后的 margin 為負(fù)值,則元素不能水平居中。
5. margin 負(fù)值定位
5.1 實(shí)例
如果能自動(dòng)填充的元素沒有設(shè)置 width/height,通過設(shè)置 margin 為負(fù)值,相當(dāng)于增加了容器的 width/height。
-
實(shí)現(xiàn)兩列等高布局
副作用:貌似會(huì)在移動(dòng)端 focus 的時(shí)候重定位 scroll 導(dǎo)致頁面飛掉(由于設(shè)置了 overflow: hidden ),mark 一下....
通過 margin 和 padding 實(shí)現(xiàn)兩列登高布局 使用 margin 負(fù)值實(shí)現(xiàn)兩欄自適應(yīng)布局
同 float 實(shí)例:

6. margin 失效情形
1. inline 元素垂直方向 margin
失效前提條件:
- 非替換元素,如 img
- 正常書寫模式 writing-mode
2. margin 重疊
3. display: table-cell 與 margin
當(dāng) display 設(shè)置為 table-* 值時(shí),margin 無效。
4. 絕對定位元素非定位方位的 margin 值“無效”
這里的“無效”是指:對絕對定位元素非定位方位設(shè)置 margin 值,對元素的定位是沒有影響的,但是實(shí)際上 margin 還是改變了元素的“占據(jù)尺寸”的,即 margin 是有效的。
5. 鞭長莫及
實(shí)際上是因?yàn)椋簃argin-left 不夠大。

6. 內(nèi)聯(lián)特性導(dǎo)致 margin 無效
如圖,無論再怎么減小 margin-top 的值,圖片的位置都不會(huì)改變。
原因是:圖片含內(nèi)聯(lián)特性,由于 vertical-align 默認(rèn)為 baseline 對齊;由于內(nèi)容 x 不會(huì)跑到容器外面去,所以受到 vertical-align 屬性的拖累,圖片位置被限制了。

