-
Notifications
You must be signed in to change notification settings - Fork 0
/
1-1-2.html
301 lines (289 loc) · 10.2 KB
/
1-1-2.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="./public/favicon.ico" />
<meta http-equiv="cache-control" content="no-cache" />
<title></title>
<link rel="stylesheet" href=" https://necolas.github.io/normalize.css/8.0.1/normalize.css" />
<link rel="stylesheet" href="./hightlight/default.min.css" />
<link rel="stylesheet" href="./css/main.css" />
<link rel="stylesheet" href="./css/copybutton.css" />
<link rel="stylesheet" href="./css/hightlight.css" />
<script src="./hightlight/hightlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.11/clipboard.min.js"></script>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-BEVZJDBC7Z"></script>
<script src="./js/gtag.js"></script>
</head>
<body>
<header>
<nav>
<h1>
<span id="toggle-menu"></span>
<a href="index.html"></a>
</h1>
</nav>
</header>
<main>
<aside>
<nav></nav>
</aside>
<article>
<h2 id="1-1-2">1-1-2 版面配置</h2>
<h3>BFC 背後的版面配置問題</h3>
<p>
BFC 是前端面試中的超級熱點,面試官經常喜歡問的問題是:請解釋一下 BFC 是什麼? BFC 是 Block
Formatting Context 的簡寫,我們可以直接將其翻譯成「區塊級格式化上下文」。話鋒一轉:
元素會建立一個特殊的區域,該區域可以發動該元素的隱藏效果。
</p>
<h3>如何形成 BFC</h3>
<p>
BFC 可以說是元素的特殊功能,除了 html
元素外其他元素在預設狀態下是關閉的。當元素達成某個條件後這個功能就會被開啟。也就是該元素形成了
BFC 。
</p>
<ul>
<li>根項目或其他包含根項目的元素 (html)</li>
<li>浮動元素(元素的float 不是 none)</li>
<li>絕對定位元素(元素的 position 為 absolute或 fixed)</li>
<li>行內區塊元素(元素具有 display: inline-block 屬性)</li>
<li>
表格儲存格(元素具有 display:table-cell,HTML 表格儲存格預設屬性) 表格標題(元素具有
display: table-caption,HTML 表格標題預設屬性)table thead tbody tfoot tr th td caption
等
</li>
<li>父元素具有 display: flex 系列的屬性</li>
<li>具有 overflow 且值不是 visible 的區塊元素</li>
<li>含有樣式屬性 column-span: all 的元素</li>
<li>含有樣式屬性 display: flow-root 的元素 (副作用最小,但 IE 沒用要注意。)</li>
</ul>
<h3>形成 BFC 解決什麼問題</h3>
<p></p>
<ul>
<li>子元素不會產生 margin 塌陷的問題。</li>
<li>該元素不會被其他 float 元素所覆蓋。</li>
<li>就算子元素 float 狀態,自身也不會產生塌陷。</li>
</ul>
<h3>BFC 決定了什麼</h3>
<p>這套規則的實際描述如下所示。</p>
<ul>
<li>內部的 box 將獨佔寬度,且在垂直方向上一個接一個排列。</li>
<li>
box 在垂直方向上的間距由 margin 屬性決定,但是同一個BFC的兩個相鄰 box 的 margin
會出現邊距折疊現象。
</li>
<li>每個 box 在水平方向上的左邊緣與 BFC 的左邊緣相對齊,即使存在浮動也是如此。</li>
<li>BFC 區域不會與浮動元素重疊,而是會依次排列。</li>
<li>BFC 區域是一個碼立的繪製容器•容器內的元素和 BFC區域外的元素員患不會有任何干擾。</li>
<li>浮動元素的高度也參與 BFC 的高度計算。</li>
</ul>
<p>從這些規則中,我們至少能歸納出以下一些關鍵要點。</p>
<ul>
<li>邊距折疊</li>
<li>
清除浮動(不一定要開啟 BFC 來清除,可以給該元素偽元素 ::after 設定 clear 為 both
來處理即可。)
</li>
<li>自我調整多欄版面配置</li>
</ul>
<h3>BFC 實際案例</h3>
<h4>範例1</h4>
<p>列出以下程式。</p>
<pre><code class="language-css">
.body {
width: 600px;
position: relative;
}
.left {
width: 80px;
height: 150px;
float: left;
background: blue;
}
.right {
height: 200px;
background: red;
}
</code></pre>
<p>執行以上程式,我們可以獲得的版面配置如下</p>
<pre><code class="language-html">
<div class="body">
<div class="left"></div>
<div class="right"></div>
</div>
</code></pre>
body
<div class="body">
<div class="left">left</div>
<div class="right">right</div>
</div>
<p>
請在不修改已有內容的情況下加入樣式,實現自我調整(left寬度固定,right
估滿剩下的寬度)兩欄版面配置。
</p>
<p>
我們想一下,根據BFC其中一筆版面配置規則,「每個在 box
水平方向上的左邊緣與BFC的左邊緣相對齊,即使存在浮動也是如此」接觸。出現這樣的版面配置並不意外。
</p>
<p>
再想一下另一筆BFC版面配置規則,「BFC區域不會與浮動元素重疊,而是會依次排列」,因此我們可以使
right:形成 BFC,來實現自我調整兩欄版面配置。
</p>
<pre><code class="language-css">
.overflow-hidden {
overflow: hidden;
}
</code></pre>
<pre><code class="language-html">
<div class="body">
<div class="left"></div>
<div class="right overflow-hidden"></div>
</div>
</code></pre>
body
<div class="body">
<div class="left">left</div>
<div class="right overflow-hidden">right + overflow-hidden</div>
</div>
<h4>範例2</h4>
<pre><code class="language-css">
.root {
border: 5px solid blue;
width: 100%;
}
.child {
border: 5px solid red;
width: 50%;
height: 100px;
float: left;
}
</code></pre>
<pre><code class="language-html">
<div class="root">
<div class="child child1"></div>
<div class="child child2"></div>
</div>
</code></pre>
root
<div class="root">
<div class="child child1">child child1</div>
<div class="child child2">child child2</div>
</div>
<p>
root 因為child 為浮動元素,因此會造成「高度塌陷」現象,root的高度為
0。如何解決「高度塌陷」?根據 BFC規則,「浮動元素的高度也參與BFC的高度計算」,因此使,root
形成 BFC 就能解決問題,程式如下。
</p>
<pre><code class="language-html">
<div class="root overflow-hidden">
<div class="child child1"></div>
<div class="child child2"></div>
</div>
</code></pre>
root overflow-hidden
<div class="root overflow-hidden">
<div class="child child1">child child1</div>
<div class="child child2">child child2</div>
</div>
<p>此時 .root 高度已經被撐開。</p>
<h4>範例3</h4>
<pre><code class="language-css">
.pWrap{
border: 1px solid #blue
}
.p{
color: blue;
background: red;
width: 400px;
line-height: 100px;
text-align: center;
margin: 40px;
}
</code></pre>
<pre><code class="language-html">
<div class="pWrap">
<p class="p">paragraph 1</p>
<p class="p">paragraph 2</p>
</div>
</code></pre>
<div class="pWrap">
<p class="p">paragraph 1</p>
<p class="p">paragraph 2</p>
</div>
<p>
首先回答問題:兩段之間的垂直距離為多少?根據 BFC版面配置規則:「box 在垂直方向上的間距由
margin 屬性決定,但是同一個BFC的兩個相鄰 box 的 margin
會出現邊距折疊現象」。事實上,因為存在邊距折疊現象,所以該問題的答案為 40px。
那麼,如何解決這個問題呢? 最簡單地,我們可以在p標籤中再包裹一個元素,並觸發該元素形成一個
BFC,那麼這兩個 p 標籤就不再屬於同一個 BFC 了,這樣便可以解決問題,程式如下。
</p>
<pre><code class="language-css">
.overflow-hidden {
overflow: hidden
}
</code></pre>
<pre><code class="language-html">
<div class="pWrap">
<p class="p">paragraph 1</p>
<div class="overflow-hidden">
<p class="p">paragraph 2</p>
</div>
</div>
</code></pre>
<div class="pWrap">
<p class="p">paragraph 1</p>
<div class="overflow-hidden">
<p class="p">paragraph 2</p>
</div>
</div>
<a href="https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context">
MDN Block_formatting_context
</a>
</article>
</main>
</body>
<script type="module" src="./js/main.js"></script>
<style>
.body {
width: 600px;
position: relative;
}
.left {
width: 80px;
height: 150px;
float: left;
background: rgb(255, 174, 0);
}
.right {
height: 200px;
background: rgb(255, 55, 0);
}
.overflow-hidden {
overflow: hidden;
}
.root {
border: 5px solid rgb(255, 174, 0);
width: 100%;
}
.child {
border: 5px solid rgb(255, 55, 0);
width: 50%;
height: 100px;
float: left;
}
.pWrap {
border: 1px solid rgb(255, 55, 0);
}
.p {
color: rgb(255, 55, 0);
background: rgb(255, 174, 0);
width: 400px;
line-height: 100px;
text-align: center;
margin: 40px;
}
</style>
</html>