CSS盒子模型以及外邊框合併的問題

盒子模型

咱們把佈局裏面的全部東西均可以想象成一個盒子,盒子裏面又裝着小盒子,小盒子裏面又裝着小小盒子......
因此佈局的萬物基於盒子。即便一個小小的元素p,也能夠把它抽象成爲一個盒子。
你如今內心有不少疑問,不要緊,接着看。git

如下是標準的盒子模型。(圖片來源github

clipboard.png

咱們日常給元素加上的width,height實際上就是給內容區域加寬和高。咱們增長內外邊距的時候不改變內容區域的大小,卻會改變總體的大小。若是咱們爲元素加一個1像素的框的話,那麼咱們能看見的只是框裏面的東西(內邊距+內容區域),若是在元素上添加背景,背景也會應用於這一區域,而外邊距是不可見的,它是用來分隔各個元素。web

雖然外邊距是不可見的,可是咱們算元素的總寬度或者總高度的時候,要加上外邊距。
即:佈局

height總=margin-top+border+padding-top+height+padding-bottom+border+margin-bottom
width總=margin-left+border+padding-left+width+padding-right+border+margin-rightgoogle

若是隻在視覺上固定框的大小不用加入margin進行計算。這裏和《精通CSS 高級web標準解決方案(第二版)》有不一樣的意見。(P39-P40,我認爲書中出錯)url

外邊距的合併問題

什麼是合併

就是外邊距中會有疊加的狀況,取二者中最大的一個做爲間隔spa

合併問題的前提是

處於普通流兩個或多個塊元素垂直方向上相遇加粗文字,會形成的margin摺疊code

除去普通流、兩個或多個、塊元素、垂直很好理解以外圖片

這個相遇要好好解釋一下了,什麼算相遇呢?ip

簡單的來講,無非就是就是說兩個元素碰到了一塊兒。這個相遇就是真真正正的遇到了,若是有邊框等阻擋,是不會發生摺疊的!

具體的,分爲:

Ⅰ:父元素的上外邊距和第一個子元素的上外邊距

大概就是圖片中的效果:

clipboard.png

也就是父元素的margin-top 和 第一個子元素的margin-top相遇,

看代碼:

HTML:
<div class="father">
    <div class="son"></div>
</div>

CSS:
/*爲了效果更加明顯,爲body添加背景顏色*/
body{
    background-color:#ccc;
}
.father{
    background-color:blue;
    height:100px;
    width:100px;
    margin-top:20px;
}
.son{
    background-color:red;
    height:20px;
    width:20px;
    margin-top:20px;
}

效果圖:

clipboard.png

能夠看出來紅色方塊本來應該在藍色方塊的下方20px處,然而卻合併了!

這種合併有時候是一種便利,而在有些狀況卻成爲了避免知何處的bug。因此在後面會講怎麼消除這種浮動。

Ⅱ:父元素的下外邊距和最後一個子元素的下外邊距

也就是父元素的margin-bottom與最後一個子元素的margin-bottom相遇發生的重疊。

與上一個相似,因此再也不闡述。

Ⅲ:相鄰兄弟姐妹元素

相鄰兄弟就是,相鄰的兩個元素margin-topmargin-bottom發生的合併。

clipboard.png

外邊距爲40px的狀況:

clipboard.png

<div class="block1"></div>
<div class="block2"></div>

.block1 {
    background-color:red;
    height:50px;
    width:50px;
    margin-bottom:20px;
}
.block2 {
    background-color:blue;
    height:50px;
    width:50px;
    margin-top:20px;
}
實際效果圖:

clipboard.png

因而可知,相鄰同胞元素確實發生了合併。

Ⅳ:空元素 ,本身的上外邊距會和本身的下外邊距合

clipboard.png

<p style="margin-bottom: 0px;">這個段落的和下面段落的距離將爲20px</p>
        
<div style="margin-top: 20px; margin-bottom: 20px;"></div>
        
<p style="margin-top: 0px;">這個段落的和上面段落的距離將爲20px</p>

這樣第一個p元素和第三個p元素之間距離爲20px

阻止自動合併

從定義出發會很好的理解這個問題,咱們能夠從合併的前提的角度出發探討幾種阻止合併的方法:

第一種方法: 擺脫普通流

position:absolute;
float:left/right;

clipboard.png

第二中方法:變成非塊元素

第一篇文章已經提過能夠用display:inline;將塊元素變成行內元素。

注意:用這種雖然是理論上是能夠實現的,然而它行內元素除了圖片是不能設置寬高的,同時margin-top margin-bottom也將失效,因此我認爲實際實現不了。

其實除了行內元素和塊級元素,還有一種元素 inline-block,它集合二者的優勢。(以後會有專門一篇文章總結。)

因此用display:inline-block也能夠實現。

clipboard.png

避免相遇

最重要的前提就是兩個元素相遇,纔有可能合併,咱們只須要把它們隔斷!

那麼在相遇的兩個margin中間能夠有什麼呢?
我針對兩種狀況給出了圖解。
圖片描述

由此能夠很清楚的看出來,只有父子的狀況才能用這種方法。

並且方法也很顯而易見:在父級元素設置padding或者border

對於父子元素來講,還有一種方式:
清除浮動,overflow:hidden overflow:auto 便可,關於爲何能清除浮動尚未搞清楚。

針對父子元素的方法
設置了清除浮動屬性

注意

  1. 若是有負外邊距,合併後外邊距爲最大正邊距加上最小負邊距(絕對值最大的一個),如上面元素下邊距爲20px,下面元素上邊距爲-20px,則最後爲0px.
  2. 在實際的狀況, 能夠只寫margin-bottom或者margin-top避免出現這種狀況。

非塊元素如何顯示?

爲此我專門寫了一篇文章:細究內聯元素(你必定不知道的東西)(一樣的之後再上連接。)

更新狀況

2017.12.03 初版2017.12.03 第二版,修改排版,修改一些重要理解,增長新的探究。2017.12.15 第三版,修改排版,增長一些新的思索

相關文章
相關標籤/搜索