你有所不知的margin屬性

前言

致謝

 本文總結於 張鑫旭老師CSS深刻理解之margin課程,感謝張老師的辛苦付出!css

難學的 CSS

 做爲前端狗的咱們,天天都要和網頁打交道。當 UI 將設計稿發給你時,CSS 的知識便顯得尤其重要。而 CSS 這一標記性的語言,卻時常讓我很頭疼:毫無邏輯性,並充滿了各類坑爹的潛規則 ,以致於每次作項目時,大部分時間精力都浪費在了調整佈局與樣式上,詳情可點擊知乎上的爲何 CSS 這麼難學?問題,道出了個人心聲 :(html

 但誰叫咱們是吃這碗飯的呢,無論怎樣,有困難必須迎面解決,學好 CSS ,向張老師看齊!前端

正文

margin 算是性格剛烈的屬性了,下面,我將從各個方面講解 margin 的可怕之處。chrome

元素尺寸的影響

一般一個元素的尺寸可分爲:可視尺寸 與 佔據尺寸瀏覽器

  1. 可視尺寸 - clientWidth (border - padding - size)
  2. 佔據尺寸 - outerWidth (border - margin)
    元素尺寸示例圖

margin 又是怎樣影響這兩個尺寸的呢?佈局

首先,兩個尺寸都需知足必定的條件。spa

可視尺寸的影響條件

  1. 適用於 沒有設定 width/height 的塊級元素 (寬高設死了,怎麼會影響呢?) 其中不包括 float absolute fixed 元素 ,inline水平 ,table-cell 元素
  2. 只適用於水平方向尺寸(margin-left/margin-right)

佔據尺寸的影響條件

  1. 適用於 block/inline-block 水平元素
  2. 適用於 任何方向
  3. 與 width/height 值無關
  4. inline 元素隻影響水平方向 (後面會提到)

影響示例

  1. margin 影響元素的可視水平尺寸設計

    See the Pen margin的可視尺寸 by Simon Ma (@Tomotoes) on CodePen.code

  2. margin 影響佔據尺寸 ,這個能夠說是 margin 的本命技能了,就不舉例了。cdn

百分比單位

一般而言,margin 的單位中,百分比單位最容易讓人頭暈。

  1. 普通元素的百分比 margin 都是相對於 容器的寬度 計算的
<style> #parent { margin: 20px 400px; width: 100px; height: 200px; } #child { /* 等價於 margin: 5% * 父元素的寬度 10% * 父元素的寬度; */ margin: 5% 10%; /* 父元素的寬度 * 50% */ width: 50%; /* 父元素的高度 * 50% */ height: 50%; } </style>
<div id="parent">
  <div id="child"></div>
</div>
複製代碼
  1. 絕對定位的百分比 margin 是相對於 第一個具備定位屬性的祖先元素的寬度 計算的(relative/absolute/fixed)
<style> #parent { width: 100px; } #child { /* 注意子元素已增長絕對定位,則百分比按照定位屬性的祖先元素的寬度計算, 本例中是瀏覽器視口 */ position:absolute; /* 等價於 margin: 5% * 父元素的寬度 10% * 父元素的寬度; */ margin: 5% 10%; } </style>
<div id="parent">
  <div id="child"></div>
</div>
複製代碼

重疊詳解

重疊可謂是 margin 中的最重要的潛規則了。

發生情景

  1. 相鄰的兄弟元素
  2. 父級和第一個/最後一個子元素
  3. 空的塊級元素(本身和本身)

重疊條件

  1. 塊級元素 (不包括 float 和 absolute 元素)
  2. 不考慮 writing-mode,只發生在垂直方向 (margin-top/margin-bottom)
  3. 父子 重疊條件
  • margin-top 重疊

    1. 父元素 非格式化上下文元素 沒有設置 overflow:hidden
    2. 父元素沒有 border-top 設置
    3. 父元素沒有 padding-top 設置
    4. 父元素和第一個子元素之間沒有inline元素分割
  • margin-bottom 重疊

    1. 父元素 非格式化上下文元素 沒有設置 overflow:hidden
    2. 父元素沒有 border-bottom 設置
    3. 父元素沒有 padding-bottom 設置
    4. 父元素和第一個子元素之間沒有inline元素分割
    5. 父元素沒有 height ,min-height,max-height 限制
  1. 空的塊級元素 margin 重疊條件
    1. 元素沒有 border 設置
    2. 元素沒有 padding 設置
    3. 裏面沒有 inline 元素
    4. 沒有 height,或者 min-height

計算規則

  1. 正正取大值
<style> #top{ margin-top:30px; } #bottom{ margin-bottom:20px; } </style>
<div id="bottom"></div>
<div id="top"></div>
兩個元素垂直距離爲 : #top元素的 margin-top值
複製代碼
  1. 正負值相加
<style> #top{ margin-top:-30px; } #bottom{ margin-bottom:20px; } </style>
<div id="bottom"></div>
<div id="top"></div>
兩個元素垂直距離爲: #top元素的margin-top值 加上 #bottom元素的margin-bottom值
複製代碼
  1. 負負最負值
<style> #top{ margin-top:-30px; } #bottom{ margin-bottom:-20px; } </style>
<div id="bottom"></div>
<div id="top"></div>
兩個元素垂直距離爲 : #top元素的 margin-top值
複製代碼
  1. 父級和第一個/最後一個子元素 發生重疊 給子元素設置垂直方向的 margin ,等同於 給父元素設置相同的垂直方向的 margin 屬性, 也就是說 父子元素髮生 margin 重疊時, 它們倆共用一個 margin 屬性

重疊意義

  • 連續段落或列表之類,若是沒有margin重疊,排版會不天然。
  • 頁面中任何地方,嵌套或直接放入任何空的 div,都不會影響原來的佈局。
  • 遺落空的任意多個 p 元素,不會影響原來的閱讀排版。

margin auto

當你使用 margin auto 時,就應該聯想到一個詞 :填充

一個沒有設置寬高的塊級元素,會自動填充寬度

若是 一側是定值,一側是 auto,則 auto 爲剩餘空間的大小

若是兩側均是 auto,則平分 剩餘空間

示例以下:

<style> #demo{ width: 500px; margin-right:100px; /* margin-left: 100vw - margin-right - width*/ margin-left:auto; } </style>
<div id="demo"></div>
複製代碼

margin:auto 0 !== 垂直居中

以上,咱們可得當一個塊級元素設置了 margin: 0 auto 能夠實現水平居中,

而爲何 margin:auto 0 不會垂直居中?

答:一個塊級元素會自動填充可用的水平尺寸,但不會填充垂直尺寸,是由於其根本沒有任何可用的垂直空間。也就是說 margin: 0 auto , 老是有尺寸能夠來填充的! 而 margin: auto 0 是沒有任何尺寸的能夠來填充的。

失效狀況

當子元素的寬度大於父元素的寬度 ,是沒法經過 margin: 0 auto 實現居中的 由於,這個時候已經沒有任何空間能夠填充了,當寬度超出父元素時,margin 已經爲負值了。

垂直居中

  1. writing-mode 與垂直居中
<style> .father{ writing-mode: vertical-lr;/* 更改流的方向爲 垂直方向 */ } .son{ margin: auto; } </style>
<div class="father">
  <div class="son"></div>
</div>
複製代碼
  1. 絕對定位元素
<style> .parent{ position: relative; } .child{ position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin:auto; } </style>
<div class="parent">
  <div class="child"></div>
</div>
複製代碼

失效情景

  1. inline 水平元素的垂直margin 無效(margin-top/margin-bottom)
  2. margin 重疊發生
  3. 絕對定位元素非定位方位的 margin值 "無效" 由於 絕對定位元素 脫離了文檔流,與相鄰元素沒有關係,因此它不可能像普通元素同樣,設置margin,推走其餘元素
  4. margin 鞭長莫及 由於 有某些元素破壞了 文檔流,設置了 float absolute,形成了假象,margin不會根據 這些破壞元素做爲標準
  5. display:table-cell/display:table-row 等聲明的margin無效!某些替換元素除外,根據各個瀏覽器的實現方式做爲區分。好比,給 button 元素聲明 display:table-cell,但在 chrome 中,button 的 display 屬性是 inline-block 。
  6. 內聯特性致使 margin 失效 margin-top: 負無窮, 可是,小到 1em 便無效了。 由於它是內聯元素,默認是基線對齊,x字母下邊緣對齊,margin 值再大,也不會起做用。 示例以下:

    See the Pen margin負無窮情景解析 by Simon Ma (@Tomotoes) on CodePen.

其餘屬性

  1. margin-start
  • 正常流向,margin-start 等同於 margin-left,二者重疊不相加
  • 若是水平流向是從右向左,margin-start 等同於 margin-right
  • 在垂直流下 ( writing-mode:vertical-*; ) margin-start 等同於 margin-top
  1. margin-end 與 margin-start 相對

  2. margin-before 默認狀況等同於 margin-top

  3. margin-after 默認狀況等同於 margin-bottom

  4. margin-collapse

  • margin-collapse:collapse;

    (默認值) 發生重疊

  • margin-collapse:discard;

    取消重疊,margin 重疊部分爲 0 ,沒有margin

  • margin-collapse:separate;

    不發生重疊,margin 重疊部分爲 margin-top + margin-bottom


結束語

margin 課程就到此結束了,再次感謝張鑫旭老師的辛苦付出!

深刻Web全棧各項技術,堅持原創,文章更新雖不定,但只爲質量而生,若是您喜歡此篇文章,歡迎支持關注。

相關文章
相關標籤/搜索