本文推薦 PC 端閱讀~
本文版權歸 「公衆號 | 前端一萬小時」 全部,未經受權,請勿轉載!
複製代碼
css_07
複製代碼
1. 塊級元素和行內元素分別有哪些? 空(void)元素有那些?塊級元素和行內元素有什麼區別?
2. IE 盒模型和 W3C 盒模型有什麼區別?
3. 在什麼場景下會出現外邊距合併?如何合併?如何不讓相鄰元素外邊距合併?給個父子外邊距合併的範例?
4. 關於 .item { width: 100%; },如下說法正確的是:
❌ .item 的寬度(包括左右 margin、左右邊框、左右 padding、content)等於它父親的寬度(包括左右 margin、左右邊框、左右 padding、content)。
❌ .item 的寬度(包括左右邊框、左右 padding、content)等於它父親的寬度(左右邊框、左右 padding、content)。
❌ .item 的寬度(左右 padding、content)等於它父親的寬度(左右 padding、content)。
✅ .item 的寬度(content)等於它父親的寬度(content)。
❌ 若是設置了 * {box-sizing:border-box},.item 的寬度(包括左右邊框、左右 padding、content)等於它父親的寬度(左右邊框、左右 padding、content)。
複製代碼
前言: 接下來的幾篇系列文章咱們講一個東西:盒子(BOX)。
「盒模型」(box model)做爲 CSS 看待元素的一種方式,CSS 將每一個元素都看做由一個盒子表示。從某方面來講,對於初級、中級學習者的咱們,大可將 CSS 的學習看做是對「盒子」的學習。
爲何這麼說?請看下圖我我的的 CSS 學習流程:css
圖中咱們能夠看到,幾乎全部的內容都是圍繞着「盒子」這個東西在展開。
本篇咱們將闡述最基本的理論知識,將「盒子」的方方面面一步步帶到咱們跟前。html
「盒子 box」由 CSS 引擎根據文檔中的內容所建立,主要用於文檔元素的格式化、定位和佈局等。前端
盒子與元素並非一一對應的,有時多個元素會合並生成一個盒子,有時一個元素會生成多個盒子(如匿名盒子)。面試
一個完整的「盒子」中心有一個內容區(content area)。這個內容區周圍有可選的 padding、邊框和 margin。這些項之因此被認爲是可選的,是由於它們的寬度能夠設置爲 0,實際上就是從「盒子」上去除這些項。瀏覽器
一個完整的「盒子」CSS 視覺格式化模型(visual formatting model)是用來處理和在視覺媒體上顯示文檔時使用的計算規則。bash
通俗的講就是:頁面(文檔樹)能夠想象成是由一個個 box 組合而成的,而「視覺格式化模型(Visual formatting model)」 是一套規則,將這些 box 「佈局」成訪問者看到的樣子。ide
每一個盒子的「佈局」由如下因素決定(本篇文章和下一篇文章主要講解第①、②點,其屬於「最基本的視覺格式化」,而對於剩下的要點,咱們在接下來的系列文章中會挨個討論):佈局
① 盒子的尺寸:精確指定、由約束條件指定或沒有指定;
② 盒子的類型:行內盒子(inline box)、行內級盒子(inline-level box)、原子行內級盒子(atomic inline-level box)、塊盒子(block box);學習
③ 定位方案(positioning scheme):普通流定位、浮動定位或絕對定位;
④ 文檔樹中的其它元素:即當前盒子的子元素或兄弟元素;
⑤ 視口尺寸與位置;
⑥ 所包含的圖片的尺寸;
⑦ 其餘的某些外部因素。atom
💡如上圖所示,視覺格式化模型會根據盒子的「包含塊」(containing block)——(包含其餘盒子的塊稱爲「包含塊」)的邊界來渲染盒子。一般,盒子會建立一個包含其後代元素的「包含塊」,可是盒子並不禁「包含塊」所限制,當盒子的佈局跑到」包含塊「的外面時稱爲溢出(overflow)。
上圖中,section 的包含塊是 body ,header、article、footer 的包含塊是 section。
⚠️區別:
盒子的生成是 CSS 「視覺格式化模型」的一部分,用於從文檔元素生成盒子。
盒子有不一樣的類型,盒子的類型取決於 CSS 的 display 屬性——元素「角色」的改變。
設置元素的 display 屬性爲 block、list-item 或 table 時,該元素將成爲「塊級元素」。
這些元素在正常流中時,會在其框以前和以後生成「換行」,因此處於正常流中的塊級元素會「垂直」擺放。
選擇器 {
display: block、list-item 或 table;
}
複製代碼
💡(「正常流」是指:西方語言文本從左向右、從上向下顯示的方向,這也是咱們熟悉的傳統 HTML 文檔的文本佈局方向。注意,在非西方語言中,流方向可能不一樣。)
但,元素是不是「塊級元素」僅是元素自己的屬性,並不直接用於格式化上下文的建立或佈局。
一個「塊級元素」會被格式化成一個塊(例如文章的一個段落),且默認按照垂直方向依次排列。
💡一個「塊級元素」都會至少生成一個「塊級盒子」,也有可能生成多個(例如列表項元素)。而「塊級盒子」纔會參與「塊格式化上下文(block formatting context)」的建立。
當元素的 display 屬性爲 inline、inline-block 或 inline-table 時,該元素將成爲「行內級元素」。
選擇器 {
display: inline、inline-block 或 inline-table;
}
複製代碼
這些元素不會在以前或以後生成「行分隔符」,因此處於正常流中的塊級元素會 「水平」 擺放,它們是塊級元素的後代。
顯示時,它不會生成內容塊,可是能夠與其餘行內級內容一塊兒顯示爲多行。
💡同理,「行內級元素」會生成「行內級盒子」,該盒子同時會參與「行內格式化上下文(inline formatting context)」的建立。
🏆小總結: 相對更詳細的「盒子」細分:
⚠️注意: 必定要記得的是,display 之因此得名,是由於它影響的是元素如何「顯示」,而不影響他本質上是何種元素,也就不能亂玩「嵌套關係」!
一個極端的反例就是:你不能讓一個「連接」來包圍一個「段落」。
<a href="http://…" style="display: block;">
<p style="display: inline;">這是一個錯誤的示例</p>
</a>
複製代碼
(對於生成不一樣類型「盒子」在實際項目中的運用,咱們將在後續文章詳細討論。例如:怎樣給「連接」加樣式——生成導航欄、怎樣給「表單」加樣式等。)
本篇咱們主要探討 「塊盒子」格式化,下篇文章討論「行內盒子」格式化。
塊盒子正常流中,「塊盒子」的水平部分 = 其父元素的 width = 7 個屬性之和——(margin-left ➕ margin-right) ➕ (padding-left ➕padding-right)➕(border-left➕border-right)➕內容區自身 width 。
在這 7 個屬性中只有 3 個屬性的值能夠設置爲 auto:width、margin-left、margin-right。其他的要沒必要須是肯定的值,要不就是默認值 0。
🚀可詳細分爲如下 5 種組合:
⚠️注意:因爲水平 margin 不會合並,父元素的 padding 、邊框、margin 可能會對子元素帶來「偏移」的影響。
正常流中,「塊盒子」的垂直部分 = 其父元素的 height = 7 個屬性之和——(margin-top ➕margin-bottom) ➕ (padding-top ➕padding-bottom)➕(border-top ➕border-bottom)➕內容區自身 height 。
同理,在這 7 個屬性中只有 3 個的值能夠設置爲 auto:height、margin-top、margin-bottom。其他的要沒必要須是肯定的值,要不就是默認值 0。
⚠️不過,margin-top 和 margin-bottom 設置爲 auto 也沒有什麼用,由於會被重置爲 0。因此,想利用上下 margin 都是 auto 來垂直居中是不可能的。
垂直格式化的另外一個重要方面是垂直相鄰 margin 的合併。
這種合併行爲只應用於 margin,若是元素有 padding 和邊框,padding 和邊框是不會合並的。當兩個或更多垂直 margin 相遇時,他們將造成惟一一個 margin,這個 margin 的高度等於兩個發生疊加的 margin 的高度中的較大者。
⚠️注意:當一個元素包含在另外一個元素中時,彼此相鄰的 margin-bottom 和 magin-top 也會發生疊加,取較大者。
🤔提問:水平或垂直方向各自 7 大屬性相加要等於父元素的 width 或 height,那 margin 爲負值會形成什麼結果?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div>
<p class="wide">How are you?</p>
<p>Fine,thank you,and you?</p>
</div>
</body>
</html>
複製代碼
(1)類型①
div {
width: 400px;
border: 3px solid black;
}
p.wide {
border: 1px dashed black;
margin-left: 20px;
width: auto;
margin-right: -50px;
background-color: yellow;
}
複製代碼
(2)類型②
div {
width: 400px;
border: 3px solid black;
}
p.wide {
border: 1px dashed black;
margin-left: 20px;
width: 500px;
margin-right: auto;
background-color: yellow;
}
複製代碼
(3)類型③
div {
width: 400px;
border: 3px solid black;
}
p.wide {
border: 1px dashed black;
margin-left: -50px;
width: auto;
margin-right: 10px;
background-color: yellow;
}
複製代碼
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div>
<p class="wide1">How are you?</p>
<p class="wide2">Fine,thank you,and you?</p>
</div>
</body>
</html>
複製代碼
div {
width: 400px;
border: 3px solid black;
}
p.wide1 {
border: 1px dashed black;
margin-top: -20px; /*修改這裏的值來觀察效果*/
margin-right: 20px;
margin-bottom: 30px;
margin-left: 20px;
width: auto;
background-color: yellow;
}
p.wide2 {
border: 1px dashed black;
margin-top: ;
margin-right: 20px;
margin-bottom: ;
margin-left: 20px;
width: auto;
background-color: grey;
}
複製代碼
💡把段落1的 margin-top 設爲「負」,它就被向上「拉」了 20 像素,且緊挨它的段落2也相應向上拉了 20 像素。
(2)類型 ②:負 margin-bottom
🔗效果及源碼連接
div {
width: 400px;
border: 3px solid black;
}
p.wide1 {
border: 1px dashed black;
margin-top: px;
margin-right: 20px;
margin-bottom: -50px; /*修改這裏的值來觀察效果*/
margin-left: 20px;
width: auto;
background-color: yellow;
}
p.wide2 {border: 1px dashed black;
margin-top: ;
margin-right: 20px;
margin-bottom: ;
margin-left: 20px;
width: auto;
background-color: grey;
}
複製代碼
💡把段落1的 margin-bottom 設爲「負」,段落2會根據段落1底端的位置放置。
(3)類型 ③:正負 margin 合併
「塊盒子」重疊的時候,若是垂直 margin 都爲負值,瀏覽器會取兩個 margin 絕對值的最大值;若是一個正 margin 與一個負 margin 合併,則會從正 margin 減去這個負 margin 的絕對值。
🔗效果及源碼連接
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div>
<ul>
<li>Fine</li>
<li>thank you</li>
<li>and you?</li>
</ul>
<p>回答 How are you? 的方式!</p>
</div>
</body>
</html>
複製代碼
div {
width: 400px;
border: 3px solid black;
}
ul {
border: 1px dashed black;
margin-top: px;
margin-right: 20px;
margin-bottom: -15px; /*①修改這裏的值來觀察效果*/
margin-left: 20px;
width: auto;
background-color: yellow;
}
li {
border: 1px dashed black;
margin-top: ;
margin-right: 20px;
margin-bottom: 20px; /*②修改這裏的值來觀察效果*/
margin-left: 20px;
width: auto;
background-color: grey;
}
p {
border: 1px dashed black;
margin-top: -18px; /*①修改這裏的值來觀察效果*/
margin-right: 20px;
margin-bottom: px;
margin-left: 20px;
width: auto;
background-color: yellow;
}
複製代碼
💡ul 和 p 重疊的 margin 都爲「負」,則取絕對值較大者(-18px)
💡當上邊的較大者(-18px)增長到 li 的最大正 margin 上(20px)時,就獲得了 20px - 18px =2px
後記: 這篇咱們學習了「塊盒子」的格式化方式,下一篇咱們接着這篇繼續探討「行內盒子」的格式化方式。在「行內盒子」格式化方式中,咱們會談到不少細小的基礎知識,和本篇的學習方式同樣,讓咱們儘量的用代碼、用圖片來攻克它們。
祝好,qdywxs ♥ you!