前端開發(fā)薪铜,離不開日常的網(wǎng)頁結(jié)構(gòu)布局众弓,現(xiàn)下有很多第三方的組件庫,也自帶著很多布局的方案隔箍,例如Ant Design
中就擁有一套自己的Grid 24柵格系統(tǒng)
和Layout布局
谓娃,方便我們進行網(wǎng)頁排版。
接下來蜒滩,我們從前端技術(shù)角度上滨达,去分析一下3種經(jīng)典布局的實現(xiàn)方案。
首先俯艰,我們列出一些比較常規(guī)的布局:
- 圣杯布局
- 雙飛翼布局
- 多列等分布局
1. 圣杯布局
圣杯布局: 左右兩欄的寬度固定不變捡遍,中間那一欄寬度自適應(yīng),且中間盒子的內(nèi)容優(yōu)先渲染竹握。
最早的圣杯布局的實現(xiàn)方案是:利用
浮動和負邊距
來實現(xiàn)画株。父級元素設(shè)置左右的 padding,三列均設(shè)置向左浮動,中間一列放在最前面谓传,寬度設(shè)置為父級元素的寬度蜈项,因此后面兩列都被擠到了下一行,通過設(shè)置
margin 負值
將其移動到上一行续挟,再利用相對定位紧卒,定位到兩邊。
圣杯布局的優(yōu)缺點:
- 優(yōu)點:不需要額外的DOM結(jié)構(gòu)诗祸,中間欄放在文檔流前面是優(yōu)先渲染
- 缺點:特殊情況下跑芳,當(dāng)中間盒子寬度小于左盒子的時候 就會發(fā)生布局混亂
我們可以通過3種技術(shù)方案來實現(xiàn)圣杯布局的布局效果,分別是float
直颅、float優(yōu)化
博个、Flex
實現(xiàn)代碼:
HTML結(jié)構(gòu):
<div class="main">
<!-- 如果是圣杯布局的原始方案,此處的center盒子要放在最前面 -->
<div class="center"></div>
<div class="left"></div>
<div class="right"></div>
</div>
- 實現(xiàn)方案1:
float
+position
+負邊距
.main {
height: 200px;
/* 外層大盒子設(shè)置左右的padding际乘,給兩側(cè)小盒子預(yù)留出位置 */
padding: 0 200px;
}
.center, .left, .right {
/* 三個盒子統(tǒng)一左浮動 */
float: left;
}
/* 注意坡倔,在HTML結(jié)構(gòu)中,center盒子一定要位于left和right盒子之前 */
.center {
/* 中間盒子占據(jù)父盒子寬度的100% */
width: 100%;
height: 100%;
background: lightgreen;
}
.left {
width: 200px;
height: 100%;
background: lightseagreen;
/* left被center盒子擠到了下方脖含,設(shè)置margin負值會讓三個盒子在一行上顯示 */
margin-left: -100%;
/* 通過定位負值讓left盒子位于main盒子預(yù)留出的padding的位置 */
position: relative;
left: -200px;
}
.right {
width: 200px;
height: 100%;
background: lightskyblue;
/* right被center盒子擠到了下方罪塔,設(shè)置margin負值會讓三個盒子在一行上顯示 */
margin-left: -200px;
/* 通過定位負值讓right盒子位于main盒子預(yù)留出的padding的位置 */
position: relative;
right: -200px;
}
- 實現(xiàn)方案2:
float
優(yōu)化
.main {
width: 100%;
height: 100px;
}
.left {
width: 200px;
height: 100%;
background: lightcoral;
/* 左盒子左浮動 */
float: left;
}
.right {
width: 200px;
height: 100%;
background: lightgreen;
/* 右盒子右浮動 */
float: right;
}
.center {
height: 100%;
background: lightsalmon;
/* 中間盒子左浮動 */
float: left;
/* 中間盒子使用css的calc()去自動計算寬度,思想為:父盒子寬度100% - (左盒子 + 右盒子) */
/* 注意:如果網(wǎng)頁中在意極致加載速度等優(yōu)化效率時养葵,盡量不要大量使用calc()函數(shù) */
width: calc(100% - 400px);
}
- 實現(xiàn)方案3:
Flex
.main {
width: 100%;
height: 100px;
/* 父盒子轉(zhuǎn)為flex彈性盒子 */
display: flex;
/* 子元素居中 */
justify-content: center;
align-items: center;
}
.left {
width: 200px;
height: 100%;
background: lightcoral;
}
.right {
width: 200px;
height: 100%;
background: lightgreen;
}
.center {
height: 100%;
background: lightsalmon;
/* 中間盒子占據(jù)剩下的全部空間 */
flex: 1;
}
當(dāng)然征堪,實現(xiàn)圣杯布局的效果,還可以使用其它的方案关拒,比如Grid
布局方式佃蚜,只要能夠?qū)崿F(xiàn)其圣杯布局的效果,用什么方式均可以着绊。
2. 雙飛翼布局
概念:雙飛翼布局最早是淘寶團隊提出的谐算,是針對圣杯局部優(yōu)化的解決方案。主要是優(yōu)化了圣杯布局中開啟定位的問題
雙飛翼布局的實現(xiàn)归露,本質(zhì)上也是利用了浮動和外邊距負值的思想洲脂。
雙飛翼布局與圣杯布局的不同之處在于,圣杯布局的左中右三列容器剧包,中間center盒子多了一個子容器恐锦,通過控制center中子容器的margin空出左右兩列的寬度。
<body>
<div class="main">
<div class="center">
<div class="inner"></div>
</div>
<div class="left"></div>
<div class="right"></div>
</div>
</body>
.main {
height: 200px;
}
.center,
.left,
.right {
/* 三個盒子統(tǒng)一左浮動 */
float: left;
}
.center {
/* 中間大盒子占據(jù)父盒子寬度的100% */
width: 100%;
height: 100%;
background: lightgreen;
}
.center .inner {
height: 100%;
/* 預(yù)留出左右兩個盒子的空間 */
margin: 0 200px;
background: lightcoral;
}
.left {
width: 200px;
height: 100%;
background: lightseagreen;
/* left被center盒子擠到了下方疆液,設(shè)置margin負值會讓三個盒子在一行上顯示 */
margin-left: -100%;
}
.right {
width: 200px;
height: 100%;
background: lightskyblue;
/* right被center盒子擠到了下方一铅,設(shè)置margin負值會讓三個盒子在一行上顯示 */
margin-left: -200px;
}
3. Flex實現(xiàn)多列等分布局
關(guān)鍵點:列數(shù)可自由控制(無固定寬度)
<div class="main">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
.main {
width: 100%;
display: flex;
/* 設(shè)置換行 */
flex-wrap: wrap;
/* 用來設(shè)置網(wǎng)格行與列之間的間隙,是row-gap(行間隙)和column-gap(列間隙)的簡寫形式 */
gap: 20px;
}
.main .item {
height: 200px;
/* 關(guān)鍵點在于子盒子寬度的計算上 */
/* flex: 0 0 calc((父元素寬度 - 列之間的寬度*(列數(shù)-1)) / 列數(shù)); */
flex: 0 0 calc((100% - 20px * 3) / 4);
background: lightskyblue;
}
以上3中布局,是我們開發(fā)中經(jīng)常見到的布局方式堕油,每種布局方式潘飘,都不僅限于一種技術(shù)來實現(xiàn)肮之,可以是Float
和Position
,也可以是Flex
卜录,還可以是Grid
局骤,甚至有的開發(fā)者對Boostrap
很熟悉,也是一種實現(xiàn)方式暴凑。
個人認為,每種技術(shù)方案的使用赘来,都有其優(yōu)缺點现喳,或考慮兼容性,或考慮性能犬辰,選擇適合當(dāng)下項目的內(nèi)容嗦篱,適當(dāng)做取舍,才是最關(guān)鍵的幌缝。
關(guān)注我灸促,下期我們一起探討Grid
和Flex
的不同之處。