Margin 的特異之處

船頭尺發表於2021-09-09

Margin 也可以改變元素的佈局尺寸

通常,元素的佈局尺寸是由 Content、Padding 和 Border 三個區域決定,而我們使用 margin,最常見的作用就是在空間上隔離自身與其他元素。但是,如果元素的寬高具有" 流動性(1) ",margin 也可以改變元素的佈局尺寸。

*(1)可以參考:

例子:

<style>
    div {
        width: 200px;
        background: #ccc;
    }
    
    p {
        margin: 10px;
        background: #FFEB3B;
    }
</style>

<div>
    <p>hello</p>
</div>

圖片描述

例子中,我們可以看到,由於 margin 設定了 10px 的值,p 元素的寬度變為 180px。
反過來,如果將 margin 值設定為負數(2),就可以增加 p 元素的可用寬度。

*(2)margin 的值可以是負數,也可以是百分比。如果是百分比值,和 padding 屬性一樣,四個方向都是基於其所在包含塊寬度計算的。

例子:

<style>
    div {
        width: 200px;
        background: #ccc;
    }
    
    p {
        margin: -10px;
        background: #FFEB3B;
    }
</style>

<div>
    <p>hello</p>
</div>

圖片描述

多列布局

利用 margin 改變元素尺寸的這個特性,可以很方便地實現兩列或多列布局:

例子:

<style>
    div {
        overflow: hidden;
    }
    
    span {
        background: darkmagenta;
        float: left;
        width: 50px;
        height: 100px;
    }
    
    p {
        margin: 0;
        margin-left: 60px;
        background: #FFEB3B;
    }
</style>

<div>
    <span></span>
    <p>白居易的詩雖淺顯易懂,詩味卻很濃郁,藝術成就極高,有《白氏長慶集》。</p>
</div>

圖片描述

Margin 合併

標準文件流中,塊級元素垂直方向上會發生 margin 合併的現象,具體可以分為以下三種情況:

1、上下相鄰的兩個塊級元素會發生外邊距合併。

例子:

<style>
    p {
        margin: 15px 0;
    }
</style>

<p>AAA</p>
<p>BBB</p>

圖片描述

例子中,我們可以看到,第一個 p 元素和第二個 p 元素之間的距離是 15px,說明第一個 p 元素的 margin-bottom 與第二個 p 元素的 margin-top 合併在一起了,並非上下相加。

2、父塊級元素與第一個、最後一個子塊級元素會發生外邊距合併。

例子:

<style>
    div {
        background: #eee;
    }
    
    p {
        margin: 15px 0;
    }
</style>

<div>
    <p>AAA</p>
    <p>BBB</p>
</div>

圖片描述

例子中,我們可以看到,雖然父元素 div 沒有設定外邊距,但第一個子元素 p 的 margin-top 與最後一個子元素 p 的 margin-bottom,全部作用在了父元素身上,導致父元素上下外邊距皆為 15px。

3、空塊級元素自身會發生外邊距合併。

例子:

<style>
    div {
        background: #eee;
        overflow: hidden;
    }
    
    p {
        margin: 15px 0;
    }
</style>

<div>
    <p></p>
</div>

圖片描述

例子中,為了方便觀察,我們為 p 元素設定了父元素 div。元素 div 的高度為 15px,說明空元素 p 的 margin-top 和 margin-bottom 合併在一起了。

合併的計算規則

可以簡單總結為" 正正取其大,負負取其小,正負就相加 "。

例子1:正正取其大

<style>
    p {
        height: 20px;
        background: #00BCD4;
        margin: 0;
    }
    
    p:first-child {
        margin-bottom: 15px;
    }
    
    p:last-child {
        margin-top: 30px;
    }
</style>

<p></p>
<p></p>

圖片描述

例子中,由於" 正正取其大 ",因此第一個 p 元素與第二個 p 元素的間距為 30px。

例子2:負負取其小

<style>
    div {
        margin-bottom: -5px;
    }
    
    p {
        background: #00BCD4;
        height: 20px;
        margin: 0;
        margin-bottom: -10px;
    }
    
    hr {
        margin: 0;
        border: 1px solid #F44336;
    }
</style>

<div>
    <p></p>
</div>
<hr>

圖片描述

例子中,由於" 負負取其小 ",因此父元素 div 最終的下外邊距為 -10px。

例子3:正負就相加

<style>
    div {
        margin-top: -15px;
    }
    
    p {
        background: #00BCD4;
        height: 20px;
        margin: 0;
        margin-top: 20px;
    }
</style>

<div>
    <p></p>
</div>

圖片描述

例子中,由於" 正負就相加 ",因此父元素 div 最終的上外邊距為 5px。

最佳化合並

之所以沒有強調" 避免合併 ",是因為 margin 合併有其存在的意義,尤其是上下相鄰元素的合併,保證了元素上下間距的一致性。而父子合併與元素自身合併,則可以透過一些方法避免發生。

避免父子元素合併的方法:

  1. 父元素在垂直方向設定 border 或 padding 值;
  2. 父元素和子元素之間新增內聯元素隔開( 內聯元素需要有內容 );
  3. 父元素設定 overflow: hidden、position: absolute、float: left / right 等屬性;
  4. 針對父元素與最後一個子元素髮生的 margin-bottom 合併,可以透過設定父元素的高度避免。

避免元素自身合併的方法:

  1. 元素自身在垂直方向設定 border 或 padding 值;
  2. 元素自身設定高度;

Margin 取值 auto 的作用

首先,觀察下面的例子:

<style>
    div {
        width: 200px;
        background: #9E9E9E;
    }
    
    nav {
        width: 50%;
        height: 50px;
        margin: 0 auto;
        background: #00BCD4;
    }
</style>

<div>
    <nav></nav>
</div>

圖片描述

這種元素水平居中的佈局,我相信大家都曾使用過。當我們分別為 margin-right 與 margin-left 設定 auto 時,就可以讓元素 nav 的左右外邊距一致,形成居中效果。
如果將 margin-left 設定為具體數值,margin-right 設定為 auto,可能很多人會認為 nav 的右外邊距為 0,但實際並不是這樣的:

例子:

<style>
    div {
        width: 200px;
        background: #9E9E9E;
    }
    
    nav {
        width: 50%;
        height: 50px;
        margin-left: 30px;
        margin-right: auto;
        background: #00BCD4;
    }
</style>

<div>
    <nav></nav>
</div>

圖片描述

透過例子可以看到,nav 的右外邊距為 70px,正好是 nav 的包含塊剩餘的水平空間。因此可以說,margin 取值 auto,並非沒有意義,而是可以自動填充元素所在包含塊的剩餘空間。
如果元素左右外邊距都取值 auto ,自然也就會平分其包含塊的剩餘空間了。

" 流動性 "元素

上面的內容,我們講了 margin 取值 auto 的作用,但其實這個作用是有前提條件的,就是元素的寬高具有" 流動性 “。” 包裹性 "元素,即使取值 auto,也是沒有意義的。

例子:

<style>
    div {
        width: 200px;
        background: #9E9E9E;
    }
    
    span {
        display: inline-block;
        width: 50%;
        height: 50px;
        margin: 0 auto;
        background: #00BCD4;
    }
</style>

<div>
    <span>hello</span>
</div>

圖片描述


如有錯誤,歡迎指正,本人不勝感激。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3016/viewspace-2824274/,如需轉載,請註明出處,否則將追究法律責任。

相關文章