聖盃佈局和雙飛翼佈局
聖盃佈局和雙飛翼佈局是前端工程師需要日常掌握的重要佈局方式。兩者的功能相同,都是爲了實現一個兩側寬度固定,中間寬度自適應的三欄佈局,都遵循了以下要點:
- 兩側寬度固定,中間寬度自適應
- 中間部分在DOM結構上優先,以便先行渲染
- 允許三列中的任意一列成爲最高列
- 只需要使用一個額外的
<div>
標籤
1. 聖盃佈局
結構
<div class="container">
<div class="main">中間</div>
<div class="left">左邊</div>
<div class="right">右邊</div>
</div>
樣式
.container {
/* 初始化 */
height: 100px;
background-color: wheat;
/* 防止left和right遮住main */
padding: 0 100px;
/* 防止轉行 */
min-width: 100px;
}
.left,
.right {
/* 初始化 */
background-color: mediumslateblue;
width: 100px;
height: 100px;
float: left;
}
.main {
/* 初始化 */
width: 100%;
height: 100px;
background-color: mediumseagreen;
float: left;
}
.left {
/* 回到上一行開頭 */
margin-left: -100%;
/* 移動到父元素padding區域 */
position: relative;
left: -100px;
}
.right {
/* 回到上一行結尾 */
margin-left: -100px;
/* 移動到父元素padding區域 */
position: relative;
right: -100px;
}
實現過程
- 給main,left,right加浮動,left,right寬100px,main寬度100%;
- 左右元素設置margin-left,到達上一行左右兩端
- main部分區域被left,right遮掉了, 設置container左右padding爲100px,然後相對定位移動left,right位置
- 設置container最小寬度100px防止窗口縮小轉行
2. 雙飛翼佈局
結構
<div class="container">
<div class="main">中間</div>
</div>
<div class="right">右邊</div>
<div class="left">左邊</div>
樣式
body {
min-width: 300px;/* 防止換行 */
}
.container {
/* 初始化 */
width: 100%;
height: 100px;
background-color: wheat;
}
.main {
height: 100px;
margin: 0 100px;
background-color: mediumseagreen;
}
.left {
/* 初始化 */
width: 100px;
height: 100px;
background-color: mediumslateblue;
/* 轉到上一行 */
margin-left: -100%;
}
.right {
/* 初始化 */
width: 100px;
height: 100px;
background-color: mediumturquoise;
/* 轉到上一行 */
margin-left: -100px;
}
.left,
.right,
.container {
/* 給三個盒子加浮動從而可以通過margin換行 */
float: left;
}
實現過程
- 設置main的左右margin(或者padding)使其內容在container中間,流出兩邊位置給left,right
- 設置container,left,right的浮動
- 設值left和right的margin使其回到上一行
- 防止換行,設置三者的父元素min-width=left的寬度+right的寬度+container的最小寬度(假設100)=300px
通過對聖盃佈局和雙飛翼佈局的介紹可以看出,聖盃佈局在DOM結構上顯得更加直觀和自然,且在日常開發過程中,更容易形成這樣的DOM結構(通常<aside>
和<article>
/<section>
一起被嵌套在<main>
中);而雙飛翼佈局在實現上由於不需要使用定位,所以更加簡潔,且允許的頁面最小寬度通常比聖盃佈局更小。
其實通過思考不難發現,兩者在代碼實現上都額外引入了一個<div>
標籤,其目的都是爲了既能保證中間欄產生浮動(浮動後還必須顯式設置寬度),又能限制自身寬度爲兩側欄留出空間。
3. 其他實現方式
若不考慮兼容性,可以使用更簡單的實現方式:
flex佈局
<div class="container">
<div class="main"> 中間 </div>
<div class="left">左邊</div>
<div class="right">右邊</div>
</div>
.container {
display: flex;
background-color: mediumslateblue;
}
.main {
flex: 1;
background-color: mediumseagreen;
}
.left {
order: -1;/* 排列順序 */
flex: 0 0 100px;
background-color: mediumslateblue;
}
.right {
flex: 0 0 100px;
background-color: mediumslateblue;
}
calc計算
/* 省略... */
.main, .left, .right {
float: left;
}
.main {
margin: 0 100px;/* 左右邊距 */
width: calc(100% - 200px);/* 計算寬度 */
}
border-box
.main,
.left,
.right {
float: left;
}
.main {
width: 100%;
box-sizing: border-box;
padding: 0 100px;/* padding值從width裏減 */
}