首頁  >  文章  >  web前端  >  css之margin屬性詳解

css之margin屬性詳解

小云云
小云云原創
2018-02-28 14:02:022293瀏覽

身為前端狗的我們,每天都要和網頁打交道。當 UI 將設計稿寄給你時,CSS 的知識就顯得格外重要。而CSS 這一標記性的語言,卻時常讓我很頭疼:毫無邏輯性,並充滿了各種坑爹的潛規則,以至於每次做項目時,大部分時間精力都浪費在了調整佈局與樣式上,詳情可點擊知乎上的為什麼CSS 這麼難學?

正文

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

元素尺寸的影響

通常一個元素的尺寸可分為:視覺尺寸與佔據尺寸
  1. 視覺尺寸- clientWidth (border - padding - size)

  2. 佔據尺寸- outerWidth (border - margin)

css之margin屬性詳解

##margin 又是怎麼影響這兩個尺寸的呢?

首先,兩個尺寸都需滿足一定的條件。

    視覺尺寸的影響條件

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

    佔據尺寸的影響條件
  1. 適用於block/inline-block 水平元素
  2. 適用於任何方向
  3. 與width/height 值無關
  4. inline 元素只會影響水平方向(後面會提到)

    影響範例

  1. margin 影響元素的視覺程度尺寸
  2. margin的視覺尺寸範例
  3. margin 影響佔據尺寸,這可以說是margin 的本命技能了,就不舉例了。

百分比單位

    通常而言,margin 的單位中,百分比單位最容易讓人頭暈。
  1. 普通元素的百分比margin 都是相對於

    容器的寬度
  2. 計算的
  3. <style>
      #parent {
      margin: 20px 400px;
      width: 100px;
      height: 200px;
    }
    #child {
      /* 等价于 margin: 5% * 父元素的宽度  10% * 父元素的宽度; */
      margin: 5% 10%;
      /* 父元素的宽度 * 50% */
      width: 50%; 
      /* 父元素的高度 * 50% */
      height: 50%;
    }
    </style>
    <p id="parent">
      <p id="child"></p>
    </p>

    #絕對定位的百分比margin是相對於第一個具有

    定位屬性的祖先元素的寬度
  4. 計算的(relative/absolute/fixed)
<style>
  #parent {
  width: 100px;
}
#child {
  /* 注意子元素已增加绝对定位,则百分比按照定位属性的祖先元素的宽度计算,
    本例中是浏览器视口 */
  position:absolute; 
  /* 等价于 margin: 5% * 父元素的宽度  10% * 父元素的宽度; */
  margin: 5% 10%;
}
</style>
<p id="parent">
  <p id="child"></p>
</p>

重疊詳解

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

    發生情境
  1. 相鄰的兄弟元素
  2. #父級與第一個/最後一個子元素
  3. 空的區塊級元素(自己和自己)

    #重疊條件
  1. 區塊級元素(不包括float 和absolute 元素)
  2. 不考慮writing-mode,只發生在垂直方向(margin-top/margin-bottom)
  3. #父子重疊條件
  • margin-top 重疊
  • #margin-bottom 重疊
  1. 父元素非格式化上下文元素沒有設定overflow:hidden
  2. #父元素沒有border-bottom 設定
  3. 父元素沒有padding-bottom 設定
  • 父元素與第一個子元素之間沒有inline元素分割

  • ##父元素沒有height , min-height,max-height 限制

    1. 父元素非格式化上下文元素沒有設定overflow:hidden

    2. 父元素沒有border-top設定

    3. 父元素沒有padding-top 設定

    4. #父元素與第一個子元素之間沒有inline元素分割



    5. 空的區塊級元素margin 重疊條件
    1. 元素没有 border 设置
    2. 元素没有 padding 设置
    3. 里面没有 inline 元素
    4. 没有 height,或者 min-height

      #計算規則
    • ##正正取大值
    <style>
    #top{
      margin-top:30px;
    }
    #bottom{
      margin-bottom:20px;
    }
    </style>
    <p id="bottom"></p>
    <p id="top"></p>
    两个元素垂直距离为 : #top元素的 margin-top值
  • 正負值相加
  • <style>
     #top{
      margin-top:-30px;
    }
    #bottom{
      margin-bottom:20px;
    }
    </style>
    <p id="bottom"></p>
    <p id="top"></p>
    两个元素垂直距离为: #top元素的margin-top值 加上 #bottom元素的margin-bottom值
  • #負負最負值
  • <style>
    #top{
      margin-top:-30px;
    }
    #bottom{
      margin-bottom:-20px;
    }
    </style>
    <p id="bottom"></p>
    <p id="top"></p>
    两个元素垂直距离为 : #top元素的 margin-top值

    父層級和第一個/最後一個子元素發生重疊

    給子元素設定垂直方向的margin ,等同於為父元素設定相同的垂直方向的margin 屬性, 也就是說父子元素發生margin 重疊時, 它們兩個共用一個margin 屬性

    重疊意義

    #連續段落或列表之類,如果沒有margin重疊,排版會不自然。

    頁面中任何地方,嵌套或直接放入任何空的 p,都不會影響原來的佈局。 ############遺落空的任多個 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>
    <p id="demo"></p>

    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>
      <p class="father">
        <p class="son"></p>
      </p>
    2. 绝对定位元素

      <style>
      .parent{
        position: relative;
      }
      .child{
        position: absolute;
        top: 0; bottom: 0; left: 0; right: 0;
        margin:auto;
      }
      </style>
      <p class="parent">
        <p class="child"></p>
      </p>

    失效情景

    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 值再大,也不会起作用。
      margin负无穷情景解析

    其他属性

    1. margin-start

    • 正常流向,margin-start 等同于 margin-left,两者重叠不相加

    • 如果水平流向是从右向左,margin-start 等同于 margin-right

    • 在垂直流下 ( writing-mode:vertical-*; ) margin-start 等同于 margin-top

  • margin-end 与 margin-start 相对

  • margin-before 默认情况等同于 margin-top

  • margin-after 默认情况等同于 margin-bottom

  • margin-collapse

    • margin-collapse:collapse;

      (默认值) 发生重叠
    • margin-collapse:discard;

      取消重叠,margin 重叠部分为 0 ,没有margin
    • margin-collapse:separate;

      不发生重叠,margin 重叠部分为 margin-top + margin-bottom

    相关推荐:

    浅谈margin负值的作用

    详解CSS中margin和padding的区别

    CSS的margin有什么作用

    以上是css之margin屬性詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述:
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn