聖盃佈局
聖盃佈局是三欄(左中右)佈局的一種,其中,左右兩邊固定寬度,中間的主體內容自適應。
爲了行文方便,下面先定義一些公共代碼:
HTML
結構:
<div class="container">
<header>header</header>
<main>
<div class="center">center</div>
<div class="left">left</div>
<div class="right">right</div>
</main>
<footer>footer</footer>
</div>
公共樣式:
*{
margin: 0;
padding: 0;
}
header,footer{
height: 100px;
background-color: #eeeeee;
}
main>div{
height: 100px;
}
.center{
background-color: aqua;
}
.left{
width: 200px;
background-color: hotpink;
}
.right{
width: 200px;
background-color: rebeccapurple;
}
分析:從上面的結構和樣式來看,頁面上呈現了頭部,中間主體內容、左右兩欄以及尾部。默認情況下,他們獨佔一行。換句話說,就是五個塊級盒子垂直排列。接下來的事就是要將左、右兩個盒子挪到兩邊,接着讓中間的主體內容自適應。
圖示:
方式一:flex
通過 flex
實現元素水平排列就是一行代碼的事:
main{
display:flex;
}
加入上面的這行代碼確實達到了三個元素在同一行排列的效果,但是也出現了兩個問題:
- 主體元素因爲結構是在最前面的(爲了優先渲染),所以此時的排列順序不對,正確的排列順序應該是左、中、右這樣的順序。
- 因爲父級容器開啓了
flex
佈局,所以它裏面的所有直接子元素就成了flex
元素,這帶來最直接的問題就是破壞了塊級元素的流動性,他們不再是獨佔一行,取而代之的是shrink-to-fit
寬度收縮到合適,所以,此時的主體元素寬度被擠壓了。
效果如下:
只要解決上面的兩個問題就實現了聖盃佈局了,那麼首先來解決第一個問題:元素排列。在 flex
佈局中,改變元素的排列次序是非常簡單的一件事,直接通過 order
來指定次序就可以解決了:
.center{
order: 2;
background-color: aqua;
}
.left{
order: 1;
width: 200px;
background-color: hotpink;
}
.right{
order: 3;
width: 200px;
background-color: rebeccapurple;
}
好了,排列的順序對了,但是發現三個元素擠在一起了,我們需要將兩邊固定,中間自適應,所以要把左右兩個固定在兩端,這個也是非常容易,加上一行代碼:
main{
display: flex;
justify-content: space-between;/*加入這行代碼*/
}
加入的代碼改變了主軸的排列方式,左右兩個元素緊貼左右兩邊,中間的元素也居中了。
最後,剩下的就是將中間的主體改爲自適應,彈性佈局處理富裕空間還是一件難事嗎?一行代碼即可:
.center{
order: 2;
flex: 1;/*加入這行代碼*/
background-color: aqua;
}
效果:
完整代碼:
*{
margin: 0;
padding: 0;
}
header,footer{
height: 100px;
background-color: #eeeeee;
}
main>div{
height: 100px;
}
main{
display: flex;
justify-content: space-between;
}
.center{
order: 2;
flex: 1;
background-color: aqua;
}
.left{
order: 1;
width: 200px;
background-color: hotpink;
}
.right{
order: 3;
width: 200px;
background-color: rebeccapurple;
}
從上面來看,通過 flex
來實現聖盃佈局簡直再簡單不過了,代碼非常簡潔,但是如果要考慮兼容性的問題就不是那麼適合了。這時候就需要使用下面的第二種方式。
方式二:浮動 + 定位 + 負外邊距
首先,父級容器通過內邊距將容器壓縮,壓縮的空間就是左右兩欄固定的寬度:
main{
padding: 0 200px;/*添加這行代碼*/
}
顯然,此時的效果就是將盒子壓縮了,接着,通過浮動讓他們在同一行排列:
main>div{
height: 100px;
float: left;/*添加這行代碼*/
}
一旦開啓了浮動,則必然要考慮的問題就是高度塌陷。是的,此時的父容器已經無法由子元素撐開了,高度塌陷了。
main:after{
content: '';
display: block;
clear: both;
}
好了,高度塌陷解決了,但是此時的效果好像距離目標好像也差得太遠了,因爲浮動,改變了盒子模型,塊級元素的流動性被破壞了,所以沒有固定寬度的中間元素的寬度收縮到合適了(shrink-to-fit
)。所以,還需要解決這個問題:
.center{
width: 100%;/*添加這行代碼*/
background-color: aqua;
}
好了,寬度恢復正常了,但是左右兩欄的元素又被擠下去了,所以,最後的問題就是將它們挪動到適合的問題。然後解決這個問題也不難,使用負外邊距和定位足以:
.left{
/*相對定位將元素挪至左欄位置*/
position: relative;
left: -200px;
/*負外邊距將元素挪至跟中間元素的左上角重疊*/
margin-left: -100%;
width: 200px;
background-color: hotpink;
}
右欄元素:
.right{
margin-right: -200px;/*將元素挪到右欄位置*/
width: 200px;
background-color: rebeccapurple;
}
完整代碼:
*{
margin: 0;
padding: 0;
}
header,footer{
height: 100px;
background-color: #eeeeee;
}
main>div{
height: 100px;
float: left;
}
main{
padding: 0 200px;
}
main:after{
content: '';
display: block;
clear: both;
}
.center{
width: 100%;
background-color: aqua;
}
.left{
position: relative;
left: -200px;
margin-left: -100%;
width: 200px;
background-color: hotpink;
}
.right{
margin-right: -200px;
width: 200px;
background-color: rebeccapurple;
}