1. 程式人生 > >CSS基礎學習——理解盒子模型

CSS基礎學習——理解盒子模型

初瞭解

  • CSS盒子模型,一個神祕的方形組織。

  • MDN中的定義:W3C盒模型是 CSS 規範的一個模組,它定義了一個長方形的盒子,每個盒子擁有各自的內邊距和外邊距,並根據視覺格式化模型來對元素進行佈局。

  • 自己的話來解釋一番:盒子模型是相對於塊狀元素和行內可替換元素而言的,當我們編輯好html與css,命令瀏覽器開始渲染時,瀏覽器的渲染引擎會根據盒子模型而將所有符合要求的元素表示為一個矩形的盒子,而我們編寫好的CSS樣式,便決定著這個盒子的各組成元素的大小、盒子的位置、顏色、背景、邊框等等屬性。

兩種模型

  • 標準盒模型
    • 圖示:

 

    • 以及相關的CSS屬性: 
高度/寬度 外邊距 最大最小高寬度 溢位 內邊距 其他
height margin max-height overflow padding visibility
width margin-left max-width overflow-x padding-left box-shadow
  margin-right min-height overflow-y padding-right box-decoration-break
  margin-bottom min-width   padding-bottom box-sizing
  margin-top     padding-top  
    • 其中最主要的五個屬性:

width:內容區(content)的寬度,注意不是整個盒子的寬度。

height:內容區(content)的高度,也不是整個盒子的高度。

padding:內邊距。

border:邊框。

margin:外邊距。

 

  • IE盒模型:但是,還有另一種盒模型,那就是IE盒模型,IE5.5及更早的版本使用的是IE盒模型,而IE6之後,也遵從了標準盒模型。它的計算方法與標準盒模型不同,接下來會闡述不同在哪。

盒子的大小

設定內容大小

在標準盒模型中,整個div可以看做一個盒子,而此時整個盒子的寬度並不等於width,而是width+2*border+2*padding,最中間的content寬度等於width為100px;

此時設定的寬度只能應用到內容區。

值得一提的是,雖然margin也屬於存在於盒子模型中,但並不參與盒子模型的寬度和高度計算,可以看做是用於控制與其他元素之間的距離關係。

<div class="box">這是一個小盒子</div>
.box {
        width: 100px;
        height: 100px;
        border: 5px solid #000;
        padding: 10px;
        margin: 20px;
        box-sizing: border-box;
}

 

盒子模型展示

盒子的真實寬度(margin沒有計算在內)

 

設定高度後,效果和寬度一樣:

<div class="box">這是一個小盒子</div>
.box {
         width: 100px; 
         height: 100px; 
         border: 5px solid #000; 
         padding: 10px; 
         margin: 20px;
}            

 

盒子模型展示

盒子的真實寬度(margin沒有計算在內)

 

因此若改動任意一個width、padding或border都會導致盒子的大小發生改變,這對佈局來說十分不友好。

設定盒子大小

如何設定盒子的大小,使得改動padding和border時,不會改動整個盒子的大小,而是“內部解決”。

使用box-sizing屬性改變盒子模型的計算方式。

MDN中寫道:如果box-sizing為預設值content-box,width、min-width、max-width、height、min-height 與 max-height 控制內容大小。

可見box-sizing屬性值與盒子模型的大小計算密切相關。

 

box-sizing

  • 語法:content-box | border-box | inherit
  • IE盒模型的不同之處就在此。
content-box 預設值,標準盒模型。如果你設定一個元素的寬為100px,那麼這個元素的內容區會有100px寬,並且任何邊框和內邊距的寬度都會被增加到最後繪製出來的元素(盒子)寬度中。
border-box IE盒模型。告訴瀏覽器你設定的邊框和內邊距的值是包含在width內的。也就是說,如果你將一個元素的width設為100px,那麼這100px會包含其它的border和padding,內容區的實際寬度會是width減去border + padding的計算值。大多數情況下這使得我們更容易的去設定一個元素(盒子)的寬高。

 

設定box-sizing為border-box

實踐一下吧

<div class="box">這是一個小盒子</div>
.box {
        width: 100px;
        height: 100px;
        border: 5px solid #000;
        padding: 10px;
        margin: 20px;
        box-sizing: border-box;
}

盒子模型展示(盒子寬度=content+2*padding+2*border=70+2*10+2*5=width=100px;)

盒子的真實寬度(margin沒有計算在內)

 可以清楚地看見:盒子寬度=content+2*padding+2*border=70+2*10+2*5=width=100px;

 改變padding大小

<div class="box">這是一個小盒子</div>
.box {
        width: 100px;
        height: 100px;
        border: 5px solid #000;
        padding: 20px;      /*調整padding*/
        margin: 20px;
        box-sizing: border-box;
}

並且將padding增大到20px時,盒子總寬度還是不變,只是調整了內容區的寬度為paddingteng騰出10px的位置。

盒子模型展示(盒子寬度=content+2*padding+2*border=50+2*20+2*5=width=100px;)

盒子的真實寬度(margin沒有計算在內)

瀏覽器相容

/* 
 * 支援 Firefox, Chrome, Safari, Opera, IE8+ 和老的Android瀏覽器
 * 對於box-sizing屬性,瀏覽器廠商已移除 -webkit 字首
 */

.example {
  -moz-box-sizing: border-box;
   box-sizing: border-box;
}

 

垂直外邊距的合併

既然說到盒子模型了,就再記錄一下外邊距margin!

margin呢,不參與盒子模型的寬高度計算,用來調整與其他元素之間的位子等關係,但是有一點需要注意的是,垂直方向上的外邊距有“合併”的效果。

 即:垂直方向相鄰的兩個元素如果都有設定外邊距,瀏覽器渲染時只保留較大的外邊距。

這只是一個定義,那麼具體什麼條件下會發生這個事件呢~(來自MDN)

  • 直接相鄰的兩個元素

    • 毗鄰的兩個元素之間的外邊距會摺疊(除非是兩個浮動元素)

  • 父元素與其第一個或最後一個子元素之間

    • 如果在父元素與其第一個子元素之間不存在邊框、內邊距、行內內容,也沒有建立塊格式化上下文、或者清除浮動將兩者的 margin-top 分開;或者在父元素與其最後一個子元素之間不存在邊框、內邊距、行內內容、heightmin-heightmax-height將兩者的 margin-bottom 分開,那麼這兩對外邊距之間會產生摺疊。此時子元素的外邊距會“溢位”到父元素的外面。

  • 空的塊級元素

    • 如果一個塊級元素中不包含任何內容,並且在其 margin-top 與 margin-bottom 之間沒有邊框、內邊距、行內內容、heightmin-height 將兩者分開,則該元素的上下外邊距會摺疊。

  

  一些需要注意的地方:

  • 上述情況的組合會產生更復雜的外邊距摺疊。

  • 即使某一外邊距為0,這些規則仍然適用。因此就算父元素的外邊距是0,第一個或最後一個子元素的外邊距仍然會“溢位”到父元素的外面。

  • 如果參與摺疊的外邊距中包含負值摺疊後的外邊距的值為最大的正邊距與最小的負邊距(即絕對值最大的負邊距)的和

  • 如果所有參與摺疊的外邊距都為負,摺疊後的外邊距的值為最小的負邊距的值。這一規則適用於相鄰元素和巢狀元素。

實踐

簡單相鄰元素

<ul style="margin: 10px;">
    <li>路飛</li>
    <li>索隆</li>
    <li>娜美</li>
</ul>

“小盒子”設定了margin:20px;(下同)

                                 

可見列表的上外邊距被“小盒子”吞啦

 

父子元素

<ul style="margin: 10px;">
    <li>路飛</li>
    <li>索隆</li>
    <li style="margin-bottom: 30px;;">娜美</li>
</ul>

li元素設定了下外邊距30px,li元素的外邊距“溢位到”父元素外面,並且與下一個相鄰元素“小盒子”產生外邊距合併,得到的視覺效果便是兩者列表與“小盒子”之間的間距為30px,而不是30+20=50px;

父子元素外邊距合併

若父元素設定了邊框

<ul style="margin: 10px; border: solid;">
    <li>路飛</li>
    <li>索隆</li>
    <li style="margin-bottom: 30px;;">娜美</li>
</ul>

li元素的外邊距就無法“溢位”了

設定邊框後便無法合併父子元素外邊距

 

 空元素

<div class="box">這是一個小盒子</div>
<div style="margin: 50px;"></div>

 

                      

上下外邊距合併,並和上方相鄰的“小盒子”的下邊距合併

 

總結

1、CSS盒子模型規定了一個塊狀元素或行內可替換元素的展示方式,從而使瀏覽器根據這個規定和樣式表,渲染元素。

2、標準盒模型與IE盒模型,在計算元素寬高度時的不同,可以用box-sizing來轉換。

3、相鄰元素的垂直外邊距會合並。