[譯]HTML&CSS Lesson4: 盒子模型

amhuang發表於2017-09-26

現在我們已經熟悉了HTML和CSS。瞭解了它的基礎。現在我們來更深入的瞭解元素在頁面中的呈現和大小。

在這節課中,我們將會討論什麼是盒子模型,它的工作模式是怎樣的。我們也會在課程中學習一些新的CSS屬性,並且將介紹三種長度單位。

元素是如何顯示的

在瞭解盒子模型之前,我們先來了解一下元素是如何顯示的。在第二節課中,我們學習了塊狀元素和內聯元素的差異。快速回顧一下,塊狀元素會另起一行,並佔據所有可用的寬度,不管內容有沒有。而內聯元素會並排顯示,寬度緊隨內容變化而變化。塊狀元素通常用在大塊的內容上,例如標題,結構元素。內聯元素用在小塊的內容上,比如將幾句話加粗或斜體顯示。

display屬性

元素如何顯示——例如塊狀元素,內聯元素和其他元素——都由顯示屬性display決定。每個元素都有一個預設的display屬性值。和其他屬性值一樣,這個屬性值是可以被覆蓋的。display值有很多,其中最常用的是blockinlineline-blocknone

我們可以通過CSS選中元素並改變和重新宣告元素的display屬性值。 若值為block可以使元素成為塊狀元素顯示。

p {
  display: block;
}複製程式碼

將值設定為inline,可以將元素轉化為內聯元素。

p {
  display: inline;
}複製程式碼

inline-block比較有意思,它可以使元素的所有塊狀元素的屬性生效。但元素又按照內聯元素顯示,不會另起一行。

p {
  display: inline-block;
}複製程式碼

兩個內嵌塊元素間的空隙

inline-block內嵌塊元素有個重要的點,就是它們並非是首尾相接的。兩個內嵌塊元素之間存在小空隙。這個空隙雖然很惱人,但這是正常現象。我們會討論為什麼這個空隙存在,以及怎麼消除。


最後是none屬性值,會完全隱藏元素,頁面渲染的時候會當它不存在。任何被包裹在這個屬性值元素內的元素都會被隱藏。

div {
  display: none;
}複製程式碼

瞭解元素如何顯示,以及怎麼修改display屬性非常重要,因為它會影響盒子模型的呈現效果。討論盒子模型的時候,我們會知道他們之間的差別,意義和影響。

什麼是盒子模型?

根據盒子模型的概念,每個在頁面上的元素都是一個擁有寬,高,內邊距,邊框和外邊距的長方形盒子。

頁面上每個元素都符合盒子模型的定義,所以它非常重要。我們使用一些新的CSS屬性來來熟悉它。

使用盒子模型

每個元素都是一個長方形盒子,有幾個屬效能確定這個盒子的大小。盒子的核心屬性是元素的寬高,這兩個值可能是由元素的display屬性、元素的內容或具體的widthheight屬性值生成的。內邊距padding和邊框border擴充了元素的高寬。最後是我們定義的在邊框外的外邊距margin

盒子模型對應的CSS屬性為:widthheightpaddingbordermargin

我們來看例子:

div {
  border: 6px solid #949599;
  height: 100px;
  margin: 20px;
  padding: 20px;
  width: 400px;
}複製程式碼

根據盒子模型,元素的總寬度計算如下:

margin-right + border-right + padding-right + width + padding-left + border-left + margin-left複製程式碼

使用上述公式,就能算出示例中的高寬值

  • Width:492px = 20px + 6px + 20px + 400px + 20px + 6px + 20px
  • Height:192px = 20px + 6px + 20px + 100px + 20px + 6px + 20px

毫無疑問盒子模型是HTML和CSS很容易混淆的部分之一。
我們將width的值設定為400畫素,但元素的實際寬度為492畫素。預設情況下,盒子模型是加法。因此想要確定盒子的實際大小,我們需要考慮將四面的內邊距,邊框,外邊距都考慮進去。寬度不僅僅是width屬性的值,也要加上左右兩側的內邊距,邊框和外邊距。

到目前為止,上述屬性看著沒什麼實際意義。因為這只是為了澄清所有形成盒子模型的屬性:widthheightpaddingbordermargin

寬度和高度

每個元素都有預設的高度和寬度。雖然寬度和高度都有可能是0畫素,但預設情況下,瀏覽器會渲染每個元素的大小。元素的預設寬度和高度依賴於元素是怎麼顯示的。如果元素是頁面佈局的關鍵元素。那麼它就需要設定具體的widthheight屬性值。這種情況下,只能指定非內聯元素的屬性值。

寬度

元素的預設寬度依賴於它display屬性的值。塊狀元素的預設寬度為100%,佔據整行空間。內聯元素和內嵌塊元素的寬度都隨著元素的內容變化而變化。內聯元素不具備固定的大小,所以widthheight屬性只有在非內聯元素上才能生效。如下是為非內聯元素設定寬度的例子:

div {
  width: 400px;
}複製程式碼

高度

元素的預設高度取決於它的內容。元素根據內容需要進行垂直擴充套件或收縮。我們可以使用height屬性為非內聯元素設定高度:

div {
  height: 100px;
}複製程式碼

調整內聯元素
請記住內聯元素不支援widthheight屬性和與其相關的值。塊狀元素和內嵌塊元素支援widthheight屬性和與其對應的值。


外邊距和內邊距

瀏覽器會根據元素設定其預設的外邊距和內邊距,使其更清晰易讀。我們使用基於文字的元素來看一下這個現象。不同瀏覽器和不同元素之間的預設外邊距和內邊距可能存在差異。我們在第一課中有討論過CSS重置,將這些差別調低,或使其為零。這樣我們就可以從頭開始定義我們需要的樣式。

外邊距

margin屬性設定一個元素的周圍空間大小。外邊距在元素邊框外並且是完全透明的。外邊距可以幫助我們將元素定位在頁面的特定位置,並且可以與其他元素保持距離。 示例如下:

div {
  margin: 20px;
}複製程式碼

margin有一個特殊的現象,就是在內聯元素中垂直外邊距margin-topmargin-bottom不生效,在塊狀元素和內嵌塊元素中有效。

內邊距

padding屬性和margin屬性相似,只不過它在邊框內部,padding是為元素提供內部空間。示例如下:

div {
  padding: 20px;
}複製程式碼

padding屬性和margin屬性不一致的地方是垂直內邊距在內聯元素中同樣有效;雖然垂直內邊距顯示在元素基準線之上或之下,但是它確實是存在的。


內聯元素的外邊距和內邊距
內聯元素對內邊距和外邊距的實現和塊狀元素與內嵌塊元素不同。外邊距只有橫向margin-leftmargin-right有效。內邊距在內聯元素中完全生效,但是垂直內邊距padding-toppadding-bottom在元素基準線上面或下面顯示(譯者注:內聯元素加上垂直內邊距之後,元素內部的內容部分在視覺上沒有產生偏移)。

塊狀元素和內嵌塊元素的外邊距和內邊距的顯示是正常的。


外邊距和內邊距的宣告方式

在CSS中,很多屬性都有多種宣告方法。普通的寫法,就是一個屬性一個值,一個個地列出來。但我們也可以使用簡寫,一個屬性包含多個值。不是所有的屬性都有簡寫,所以我們必須確保寫出的屬性和值的結構是正確的。

marginpadding有普通和簡寫兩種書寫方式。當元素四面設定相同的外邊距時,可以使用margin屬性,並只指定一個值:

div {
  margin: 20px;
}複製程式碼

如果上下外邊距的值一致,左右外邊距的值一致,我們可以輸入兩個值。 設定上下外邊距的值在前面。以下例子將上下外邊距設定為10畫素,將左右外邊距設定為20畫素:

div {
  margin: 10px 20px;
}複製程式碼

如果四個值都不一致,那麼我們按照 上右下左 的順序輸入值。例如,我們為div設定10畫素的頂部外邊距,20畫素的右側外邊距,0畫素的底部外邊距,以及15畫素的左側外邊距:

div {
  margin: 10px 20px 0 15px;
}複製程式碼

若我們要設定多個值,優先考慮用marginpadding。但我們也可以用普通寫法,輸入一一對應的屬性和值。每個屬性名(該例子中是外邊距和內邊距)後跟隨一個破折號-以及要設定值的盒子的方向:topbottomrightleft
例如,padding-left屬性只接受一個值,設定元素的左側內邊距;margin-top只接受一個值,設定元素的頂部外邊距。

div {
  margin-top: 10px;
  padding-left: 6px;
}複製程式碼

當我們只想設定單邊的marginpadding值時,這種普通寫法是最好的選擇。保持程式碼的精確性可以防止出現混淆。例如,我們是否只想將元素的上右左三側的外邊距設為0,是否只想將底部外邊距設為10畫素?
普通寫法輸入屬性和值可以讓目標更明確。當處理三個或以上的值時,縮寫更有幫助。


外邊距和內邊距的顏色
marginpadding屬性是完全透明的,不可以設定顏色。但因為是透明的,所以透出了相關元素的背景色。元素外邊距部分看到的顏色為它父級元素的背景色。元素內邊距部分看到的顏色為該元素的背景色。


邊框

邊框在內邊距和外邊距之間,畫出了元素輪廓。border屬性要求三個值:寬度,樣式,顏色。邊框屬性簡寫時值的順序為:寬度,樣式,顏色。普通書寫方式下,邊框的三個屬性名為:border-widthborder-styleborder-color。普通書寫方式因為是單個值,更容易修改和複寫。

邊框的寬度和顏色能分別使用第三節課中討論過的長度單位和色值。

邊框有很多不同樣式。最常用的樣式值為soliddasheddottednone,但你可以在列表中看到很多其他的樣式。

以下是邊框設定示例:

div {
  border: 6px solid #949599;
}複製程式碼

單側邊框

marginpadding屬性一樣,也可以一次只設定元素一個方向的邊框。使用屬性名:border-topborder-rightborder-bottomborder-left。它們的屬性值和border的屬性值一樣有三個:寬度,樣式和顏色。如下所示:

div {
  border-bottom: 6px solid #949599;
}複製程式碼

另外,單側邊框的樣式也可以被細分,如下所示:

div {
  border-bottom-width: 12px;
}複製程式碼

這些高度細分的邊框屬性名都由連字元分隔,由border單詞開頭,隨後是邊框的方向:toprightbottomleft,最後是要設定的樣式:widthstylecolor

border-radius

border-radius可以使元素的邊角變圓。

border-radius接受多種長度單位,如百分比,畫素,確定元素邊角變圓的半徑。單個值表示四個角的弧度一直,兩個值按分別表示top-left/bottom-righttop-right/bottom-left,輸入四個值按順序分別表示:top-lefttop-rightbottom-rightbottom-left

思考border-radius多個值的順序時(包括marginpadding),記住它們是從左上角開始(marginpadding從上側開始)按順時針方向排序的。

div {
  border-radius: 5px;
}複製程式碼


border-radius屬性也允許我們使用普通方法書寫單個屬性值。這些普通的屬性以border單詞開通,跟著是邊角的垂直位置(topbottom),再是邊角的橫向位置(leftright),最後是半徑radius。例如,要設定<div>右上角的邊角半徑,可以使用border-top-right-radius屬性:

div {
  border-top-right-radius: 5px;
}複製程式碼

box-sizing

現在,在盒子模型中有一個附加屬性。如果你設定了元素的width400畫素,並將padding設定為20畫素,將border設定為10畫素,那麼實際的盒子寬度為460畫素。記住,盒子的寬度是width,paddingborder相加獲得的。

但是在CSS3中,盒子模型有了一個不一樣的計算方式。CSS3推出了box-sizing屬性,完全改變了盒子模型的運作模式和元素大小的計算方式。這個屬性有三個主要值——content-boxpadding-boxborder-box——每個值對盒子模型大小的計算稍微有些不一樣。

content-box

content-box這個屬性值是預設值。這個預設值和元素不加box-sizing屬性時的效果是一致的。元素從widthheight屬性的值開始計算,加上paddingbordermargin屬性值獲得盒子的實際尺寸。

div {
  -webkit-box-sizing: content-box;
     -moz-box-sizing: content-box;
          box-sizing: content-box;
}複製程式碼

特定瀏覽器的屬性和值

上例中box-sizing屬性前的連字元和字母是什麼?

CSS3的推出後,瀏覽器逐步開始以加字首的方式支援新屬性和值,包括box-sizing屬性。隨著部分CSS規範被瀏覽器廣泛支援以及瀏覽器版本的更新,字首的作用也越來越小,隨著時間的發展將不再是一個問題。但在老版本瀏覽器中還是不可或缺的。

屬性名和屬性值都可以新增字首。例如,上例中的box-sizing屬性名加了字首。瀏覽器可以選擇什麼時候加字首什麼時候不加字首,因此有些屬性需要帶有某瀏覽器的字首,有些屬性不需要。

接下來的課程中,若某個屬性或值需要字首,只會在介紹那個屬性時新增使用(這有利於保持程式碼的簡潔)。不過你們在實際寫程式碼的時候不要忘記新增字首。

最常見的幾個瀏覽器字首概括如下:

  • Mozilla的火狐瀏覽器: -moz-
  • 微軟的IE瀏覽器:-ms-
  • Webkit(谷歌的Chrome瀏覽器和蘋果的Safari瀏覽器):-webkit-

padding-box

屬性值padding-box時,元素將padding屬性值計算入widthheight屬性值內,改變了盒子模型計算模式。例如,元素的width設定為400畫素,padding值設為20畫素,最終元素實際的寬度還是400畫素。隨著內邊距的擴大,元素的內容區域會隨著縮小,但是盒子實際大小並未發生改變。

如果我們增加bordermargin,那麼盒子的大小就是這些屬性值加上widthheight的值。例如,我們將元素的的width設定為400畫素,每個方向的border都設定為10畫素,padding設定為20畫素,那麼元素的實際寬度就為420畫素。

div {
  box-sizing: padding-box;
}複製程式碼

值 padding-box 已被棄用

隨著CSS規範的更新,box-sizing的值padding-box已被棄用,我們不應再使用它。


Border Box

最後一個屬性值是border-box,它將borderpadding都算在元素的widthheight屬性值內。例如,一個元素的width400畫素,每邊的padding20畫素,border10畫素,最終元素的實際寬度仍然為400畫素。
若我們還增加了margin屬性,在獲取盒子總大小時它的值需要做加法計算。不管box-sizing的屬性值是什麼, 計算盒子總大小時任何margin的值都需要做加法計入。

div {
  box-sizing: border-box;
}複製程式碼

使用box-sizing屬性

通常來說,box-sizing最佳屬性值為border-box,這個屬性值更易計算。如果我們將一個元素的width400畫素,那麼不管你增加了邊框還是內邊距,它的大小都還是400畫素。

另外,我們也可以輕鬆的相對值。如果我們設定一個元素的寬度為40%,元素每邊的padding值為20畫素,border值為10畫素。那麼儘管有地方設定了畫素值,元素盒子的實際大小仍然為40%

唯一遺憾的是box-sizing是CSS3的屬性,並不是所有瀏覽器都支援,尤其是老版本瀏覽器。所幸隨著瀏覽器版本更新,影響會越來越小。我們使用box-sizing的時候,需要留意哪些瀏覽器會出現相容問題。

開發者工具

大多數瀏覽器都有開發者工具。我們可以使用這些工具檢視頁面上的元素、這些元素的HTML結構
和CSS屬性及它們值。它們大部分都有盒子模型圖解。

在Chrome瀏覽器中開啟選單欄,找到“更多工具”選項中的“開發者工具”選項並點選它,瀏覽器視窗的底部會顯示出一個視窗,其中提供了一些程式碼檢查工具。

懸停或點選視窗中的元素節點,可以檢視這個元素的資訊。

選中一個元素後,在視窗右側選中“Computed”選項,我們就可以看到我們選中的元素的盒子模型。

Chrome, Firefox,Safari以及其他瀏覽器中都有開發者工具。檢視原始碼可以學到很多東西。我在編寫HTML和CSS的時候通常都會開啟開發者工具,也常常用它檢視分析其他網站的原始碼。

練習

現在我們回到之前做的“樣式討論會”網站,並未它新增更多的內容。

  • 首先,在main.css檔案中新增一個box-sizing屬性,值設定為border-box,這樣可以使我們的元素更容易控制。在檔案的頁面重置樣式下,新增一條註釋,有助於網站佈局。把它放在樣式重置程式碼之下,是使其放在正確的層疊關係上。
    在這裡,我們可以使用萬用字元選擇器*,後面跟隨帶偽元素的選擇器*:before*:after,這樣就可以選中頁面中所有的元素,將其box-sizing值設定為border-box。請記住,box-sizing是有字首的,因為它是一個較新的屬性。
/*
  ========================================
  Grid
  ========================================
*/

*,
*:before,
*:after {
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
}複製程式碼
  • 接下來我們要建立一個可以作為我們元素容器的class屬性。用它在不同的元素上設定共同的widthpadding屬性,並將元素居中。 在我們萬用字元選擇器下,建立一個新的class選擇器名為container。在選擇器中將width設定為960畫素,padding-leftpadding-right設定為30畫素,上下外邊距設定為0,左右外邊距設為auto
    container告訴瀏覽器所有使用了這選擇器的元素的寬度。左右外邊距值設為auto,再加之設好的寬度值,可以讓瀏覽器自動計算出左右相等的外邊距,元素就相對於頁面居中了。最後設定左右內邊距,使內容不緊貼元於素的邊緣,為內容提供一點喘息的空間。
.container {
  margin: 0 auto;
  padding-left: 30px;
  padding-right: 30px;
  width: 960px;
}複製程式碼
  • 現在container已經可以使用,我們把它新增到所有頁面的<header><footer>元素上,所有頁面包括index.htmlspeakers.htmlschedule.htmlvenue.html以及register.html頁面。
<header class="container">...</header>

<footer class="container">...</footer>複製程式碼
  • 接下來,我們將container新增到介紹會議的<session>元素和包含<section>作為子元素的`
    元素上。
<section class="container">...</section>複製程式碼
  • 另外,也將container新增到其他頁面中包含有<h1>元素的<section>元素上。
<section class="container">
  <h1>...</h1>
</section>複製程式碼
  • 稍後我們還會再回來調整這些元素和class屬性。現在我們先做另一件事。
  • 現在我們的內容已經居中顯示,接下來為元素建立縱向的間隔。我們先把標題和段落的底部外邊距設定為22畫素。我們將這個排版樣式以及它的註釋放在之前的容器樣式之下。
/*
  ========================================
  Typography
  ========================================
*/

h1, h3, h4, h5, p {
  margin-bottom: 22px;
}複製程式碼
  • 我們在此跳過了<h2><h6>元素,因為設計中<h2>不需要外邊距,<h6>這次我們不會用到。
  • 現在我們在頁面第一個<section>的底部放置一個按鈕,併為其設定邊框和圓角。
    我們先新增一個<a>元素,並將其的class屬性值設為btnbtn-alt.
<a class="btn btn-alt">...</a>複製程式碼
  • 接下來我們在排版樣式之下為這兩個屬性值新增樣式。
  • 首先建立一個能被所有按鈕共享的樣式的class選擇器btn。我們希望所有的按鈕的border-radius5畫素,displayinline-block,並移除所有外邊距。
/*
  ========================================
  Buttons
  ========================================
*/

.btn {
  border-radius: 5px;
  display: inline-block;
  margin: 0;
}複製程式碼
  • 我們使用btn-alt為當前按鈕設定特殊的樣式。我們增加1畫素的灰色邊框,並且設定上下內邊距為10畫素,左右內邊距為30畫素
.btn-alt {
  border: 1px solid #dfe2e5;
  padding: 10px 30px;
}複製程式碼
  • 我們在同一<a>元素中使用了btnbtn-alt,那麼相應的樣式都會渲染上去。
  • 在主頁上,我們為包含上述<a>元素的<section>元素設定padding樣式。我們通過在其上新增一個class屬性值hero來實現。
<section class="hero container">
  ...
</section>複製程式碼
  • 最後,我們在CSS檔案分隔出一塊專門設定主頁的樣式,然後hero新增padding屬性。
/*
  ========================================
  Home
  ========================================
*/

.hero {
  padding: 22px 80px 66px 80px;
}複製程式碼

現在我們的網站更加完整了,尤其是主頁。


萬用字元選擇器

在此練習的第一步,我們提到了萬用字元選擇器*,它會選中所有的元素。相比於一一列出所有能想到的單個元素,不如使用它來選中所有的元素。

我們也在第一步中提到了偽元素:before:before,它們可以在CSS中動態生成元素。我們不會當前專案中使用它。不過在萬用字元選擇器中使用偽元素是很常用的做法。


演示原始碼

這是練習的原始碼。點選下載

總結

休息一下我們再繼續。

將盒子模型所有內容學完並不容易。這些概念雖然只是簡單介紹,卻花了很多時間來掌握它。

這節課所學內容概括如下:

  • 元素是如何顯示的
  • 什麼是盒子模型,它為什麼很重要
  • 怎麼修改元素的大小,包括寬度和高度
  • 怎麼新增元素的外邊距,內邊距和邊框
  • 怎麼修改元素box-sizing及其對盒子模型的影響

現在我們對如何顯示元素和設定尺寸有了更好的瞭解,接下來我們深入瞭解一下元素的定位。

文章來源

learn.shayhowe.com/html-css/op…

相關文章