Margin的深刻了解

Margin的深刻了解

關於margin對於一個前端開發者是很是常見的一個CSS屬性,而我今天所分享margin屬性是爲了更加深刻的瞭解margin的一些特性,從而在實際應用中,減小代碼量。主要內容以下:css

1.關於margin的百分比特性。前端

2.關於marginauto的做用機制。css3

3.關於margin的重疊。瀏覽器

4.關於margin的負值。佈局

1、margin的百分比特性。spa

咱們使用百分比時常常會忽略這個問題,margin的百分比相對於咱們直接設置margin-top這類有所不一樣,margin的百分比是相對於容器水平寬度來計算的。這裏有兩種狀況:設計

1.做用元素爲普通元素(float\position等均不是普通block元素)3d

在這種狀況下,百分比是相對於父元素的寬度計算。如:blog

 

<div style="width: 300px; height: 100px;">圖片

<div style="width: 100px; height: 40px; margin: 10%;display: inline-block;"></div>

</div>

(注意:爲何這裏我要用inline-block呢。

此時margin值爲父元素寬度的10%,也就是margin-top30px,margin-left30px

2.做用元素爲絕對定位元素

在這種狀況下,百分比是相對於祖先元素或者最近的定位父元素寬度計算的。如:

 

<div style="width: 800px; height: 150px; ">

<div style="width: 300px; height: 100px; margin-left: 100px; ">

<div style="width: 100px; height: 40px; margin: 10%; position: absolute;"></div>

</div></div>

此時由於div使用了position,因此margin值是根據祖先元素的寬度進行計算。

 

2、marginauto的做用機制。

關於marginauto可能你們在熟悉不過了,用的最多的可能就是margin:0 auto;來進行水平居中定位了,可是你真的瞭解它是怎麼實現的嗎?是否你也遇到過img圖片沒法使用這個水平居中和margin:auto 0 沒法進行垂直居中呢?接下來帶着疑問,我將分享我理解的auto機制。

我用比較通俗的方式表達margin:auto的機制,即是爲了填充由於強制變動尺寸而設計的屬性。

    舉一個例子:

第一個例子是在一個div中,加入了一個沒有設定寬度的p標籤,衆所周知p標籤是一個塊級元素,而瀏覽器默認爲水平流佈局,因此p標籤水平獨佔一行,而後咱們對比第二個例子,是設定了強制設定寬度100pxp標籤但依舊獨佔一行,而後對比第三個例子,是強制設定了寬度100px而且margin-right100pxmargin-left:autop標籤。此時margin-left:auto既是左邊剩餘空間大小。這樣咱們就很好理解爲何margin:0 auto能使元素水平居中了。是由於它至關於margin-left:auto;margin-right:auto;即直接把剩餘空間平分給兩側處理。可能你們都常用第三個列子中沒有添加auto時,margin-right始終不能執行,如今能夠知道它的原理了吧。下次就可使用它了。

理解了上面的機制後,咱們看看爲何img使用上面的方法依舊不行呢。如今應該不少朋友都知道了,由於imginline水平,及時你使用margin:0 auto;可是它沒有須要處理的剩餘空間,因此依舊沒法實現居中,這個時候咱們只要讓它變成block元素,效果就天然呈現了。

解決了第一個問題,如今咱們解決第二個問題,咱們是否能用margin:auto 0來實現垂直居中呢?答案是:固然能夠得!

在前面咱們講到瀏覽器是默認爲水平流佈局,及塊級元素是會自動填充滿一整行的。而咱們的auto是處理被更改的剩餘空間的,而咱們的高度方向並非自動充滿一整行,因此即便你強制設定了高度,可是依舊沒有的剩餘空間,沒有剩餘空間auto天然不會作出反應。可能小夥伴們已經知道如何解決這一個問題了,既是把水平流佈局更改成垂直流佈局。改變佈局後,垂直方向便可自動填充一列,writing-mode:vertical-lr;css3中的屬性,即改變此元素的佈局爲垂直流佈局。這樣,一個垂直居中及完成了。

有小夥伴要問了,如今垂直居中了,可是水平又不能居中了。如今即刻分享水平垂直方向都居中的辦法(辦法有不少,此處是根據margin和絕對定位來實現的)。

代碼先行:

<div style="width: 500px; height: 300px; position: relative;">

<div style=" width: 100px; margin: auto; height: 100px; position: absolute; top: 0; right: 0; left: 0; bottom: 0" ></div>

</div>

細化分析,咱們給img元素一個絕對定位,而後給它top/left/bottom/right都設置爲0,此時裏面div元素填充滿整個外層div,而後咱們強制改變了他的寬度很高度,此時它便有了剩餘空間,根據上面的機制,auto處理了剩餘空間,及讓它水平垂直都成功居中。

3、margin的重疊概念

關於margin的重疊咱們在實戰中常常會出現,下面舉例一個簡單的例子:

*{ margin: 0; padding: 0; }

p{line-height: 1em; margin: 1em 0;}

<p style="">1</p>

<p style="">2</p>

這種例子在實際中很常出現,但到底有什麼端倪呢。當你在瀏覽器上顯示出這段代碼的時候,你會發現,在咱們常理判斷下,倆個p標籤都有margin,應該之間的距離有兩個p標籤的高度啊,但咱們能從肉眼發現,徹底沒有。這就是margin的重疊機制。

可是這是有前提條件的:

1.必須爲block水平元素(不包括floatabsolute元素);

2.不考慮writing-mode,只發生在垂直方向;

margin重疊一般出如今三種情形下

第一種:既是上面舉例的相鄰兩個兄弟元素

第二種:父元素和第一個或者最後一個子元素

第三種:空的block元素;

第一種咱們已經舉例說明,如今說第二種,父元素和第一個子元素的重疊。咱們仍是先寫出代碼塊:

<div style="width: 200px; height: 200px; ">

<div style="margin-top: 100px;">1</div>

</div>

這也是咱們常常碰見的問題,咱們想要的結果是子元素與父元素的距離爲100px,可是咱們設置後發現,是父元素和瀏覽器出現了top值,這即是margin重疊的神奇,這就等同於父元素設置了top值,但有時候咱們會以爲這樣達不到想要的效果,其實,咱們只須要在父元素加入overflow: hidden; 即可以清除重疊機制;父子元素重疊依舊有不少條件,下面我把列舉出來,你們能夠試試。

margin-top重疊條件:

1.父元素費塊狀格式化上下文元素

2.父元素沒有border-toppadding-top

3.父元素和第一子元素沒有inline元素分隔

margin-bottom重疊條件:

1.父元素費塊狀格式化上下文元素

2.父元素沒有border-bottompadding-bottom

3.父元素和最後一個元素沒有inline元素分隔

4.父元素沒有height相關的限制;

其實這些條件也是咱們消除父子元素重疊的方式。

第三種空的block元素,下面是例子:

<div style=" overflow: hidden;">

<div style="margin: 1em 0;"></div>

</div>

裏面的div設置了margin-top:1em,margin-bottom:1em,按照常理,外面容器應該被撐大到2em,可是實際上卻依舊是1em;以上即是margin重疊的三種狀況。它是一把雙刃劍,因此咱們須要合理利用它的重疊。

4、margin的負值

利用margin的負值在咱們實戰中是很是有效的一個技能。咱們一般會遇到這麼一個佈局,三個或者多個div在同一行的顯示的時候須要咱們作出這樣的效果(這樣的效果有不少方法作到,這裏只討論margin實現):

 

在我剛入門的時候,我老是統一個div一個共有的margin值,獲得以下效果:

而後再利用JS或者固定class屬性來控制每一行最後一個divmargin值爲0。不知道是否有朋友和我同樣這樣作,這確實不算一個有用的辦法。而margin負值改變了這一切,讓咱們並不須要去單獨處理某一div

.box{width: 320px; height: 200px; overflow: hidden;}

.box>div>div{width: 100px; height: 100px; background-color: royalblue; float: left;margin-right: 10px;}

.box>div{margin-right: -10px;}

<div class="box">

<div>

<div>1</div>

<div>2</div>

<div>3</div>

</div>

</div>

 

根據上面的代碼,咱們輕易的達到了咱們想要的效果,如今咱們再分析,這是如何作到的。在分析以前,咱們要了解margin有一個很實用的技能,即是改變可視尺寸(前提條件:無高寬的普通block元素和只針對水平方向)。這個技能即是咱們實現這個效果的重點。簡單的說,在沒有設置寬高的時候,咱們div元素的寬度是外層容器的寬度,當咱們給div一個margin-left:100px時,div元素相距左邊有100px,而咱們div元素的寬度就變成了外層容器寬度減去100px;同理,當咱們給div設置了margin-right-10px的時候,至關於容器就在原來的基礎上向右邊多出來10個像素,而這10個像素正好是咱們margin須要的空間,天然咱們要排列的div就不會跑到下一行裏去了,而在最外層設置overflow:hidden;是爲了也不影響咱們外面的全部佈局。可能只從文字上仍是比較難以理解,因此代碼還須要本身實際操做才能讓它深刻你心。

關於margin負值可不僅是這麼一點用處,下面咱們將分析一個關於margin-bottom負值所帶來的經典案例:等高佈局。

 

咱們一般但願,無論左邊內容和右邊內容是否一致,可是他們最終外面的容器高度都但願一直。不少小夥伴通常狀況是使用固定高度來解決這麼一個問題,可是有時候咱們並不知道咱們其中的內容究竟是多少畢竟大多數時候都是後臺來生成這個內容的,那固定高度的辦法當然就失敗了。這時候,就該咱們margin-bottom出擊了。

<style>

*{ margin: 0; padding: 0; list-style: none;}

.red,.green{float: left; width: 300px; margin-bottom: -600px; padding-bottom: 600px;}

.red{}

.green{background-color: green;}

.content{ overflow: hidden;}

</style>

<body>

<div class="content">

<div class="red">

<ul>

<li>1</li>

</ul>

</div>

<div class="green">

<ul>

<li>1</li>

<li>2</li>

<li>2</li>

</ul>

</div>

</div>

效果以下:

 

不論你兩邊內容是否一致,已經等高,首先咱們給咱們內容div給出一個足夠大的margin-bottom負值,而後再使用padding撐開這個div,此時這個div大小足以讓咱們放入足夠多的列表。(注:在我理解看來,其實也是設置一個高度,只是這個高度並不像直接設置出來的高度那樣直接顯示出來暫具空間,而是根據內容慢慢顯示出來,overflow:hidden就是拿來隱藏沒有使用的空間高度)。

不知道你讀完後是否以爲咱們經常使用的margin也這麼神奇呢?又或許其實上面的效果你能夠用不少方法來代替它,這或許不是最優解,可是多一種方法會讓咱們多一種思路。如如有錯的地方,但願你們指出。

相關文章
相關標籤/搜索