經(jīng)常會(huì)遇到這樣一個(gè)場(chǎng)景:
寫一個(gè)兩側(cè)寬度固定金刁,中間寬度自適應(yīng)的三欄布局。
圣杯布局
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
body{
min-width: 620px; /* 格外注意:頁面的最小寬度 */
}
.middle,
.left,
.right {
position: relative;
float: left;
height: 100%;
}
.container {
padding: 0 220px 0 200px;
overflow: hidden;
}
.left {
/* 關(guān)鍵代碼:這里使用負(fù)外邊距(nagetive margin)將left放置到之前預(yù)留出的位置上 */
margin-left: -100%;
left: -200px;
width: 200px;
background: #002496;
}
.right {
margin-left: -220px; /* 關(guān)鍵代碼 */
right: -220px;
width: 220px;
background: #ed2738;
}
.middle {
width: 100%;
background: #c0c0d4;
word-break: break-all;
}
</style>
</head>
<body>
<div class='container'>
<div class='middle'>middle</div>
<div class='left'>left</div>
<div class='right'>right</div>
</div>
</body>
</html>
雙飛翼布局
基于圣杯布局進(jìn)行的優(yōu)化版本:雙飛翼布局
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
body{
min-width: 620px; /* 頁面的最小寬度 */
}
.middle,
.left,
.right {
position: relative;
float: left;
height: 100%;
}
.container {
overflow: hidden;
/* 圣杯布局在container塊上加內(nèi)邊距(padding: 0 220px 0 200px;) */
}
.left {
margin-left: -100%;
width: 200px;
background: #002496;
}
.right {
margin-left: -220px;
width: 220px;
background: #ed2738;
}
.middle {
width: 100%;
background: #c0c0d4;
}
.contant{
/* 雙飛翼布局將其改為contant塊上加外邊距(margin: 0 220px 0 200px;) */
margin: 0 220px 0 200px;
}
</style>
</head>
<body>
<div class='container'>
<div class='middle'>
<div class="contant">middle</div>
</div>
<div class='left'>left</div>
<div class='right'>right</div>
</div>
</body>
</html>
- 關(guān)于頁面最小寬度:
1、要想保證該布局效果正常顯示产捞,由于兩側(cè)都具有固定的寬度,所以需要給定頁面一個(gè)最小的寬度搂抒,但這并不只是簡(jiǎn)單的200+220=420px∏缶В回想之前l(fā)eft使用了position: relative衷笋,所以就意味著在center開始的區(qū)域,還存在著一個(gè)left的寬度辟宗。所以頁面的最小寬度應(yīng)該設(shè)置為200+200+220=620px;
2泊脐、由于雙飛翼布局沒有用到position:relative進(jìn)行定位,所以最小頁面寬度應(yīng)該為200+220=420px秕铛。
Flex布局
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
.container {
display: flex;
height: 100%;
}
.left {
background: #002496;
width: 200px;
}
.right {
width: 200px;
background: #ed2738;
}
.middle {
background: #c0c0d4;
flex: 1;
}
</style>
</head>
<body>
<div class='container'>
<div class='left'>left</div>
<div class='middle'>middle</div>
<div class='right'>right</div>
</div>
</body>
</html>
缺點(diǎn):
flex固有的兼容性問題缩挑,根據(jù)CanIUse的數(shù)據(jù)可以總結(jié)如下:
IE10部分支持2012,需要-ms-前綴
Android4.1/4.2-4.3部分支持2009 谨湘,需要-webkit-前綴
Safari7/7.1/8部分支持2012, 需要-webkit-前綴
IOS Safari7.0-7.1/8.1-8.3部分支持2012紧阔,需要-webkit-前綴
.box{
display: -webkit-flex; /* 新版本語法: Chrome 21+ */
display: flex; /* 新版本語法: Opera 12.1, Firefox 22+ */
display: -webkit-box; /* 老版本語法: Safari, iOS, Android browser, older WebKit browsers. */
display: -moz-box; /* 老版本語法: Firefox (buggy) */
display: -ms-flexbox; /* 混合版本語法: IE 10 */
}
.flex1 {
-webkit-flex: 1; /* Chrome */
-ms-flex: 1 /* IE 10 */
flex: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */
-webkit-box-flex: 1 /* OLD - iOS 6-, Safari 3.1-6 */
-moz-box-flex: 1; /* OLD - Firefox 19- */
}
Grid布局
Grid布局最簡(jiǎn)單了续担,兩句話搞定,但兼容性堪憂赤拒,(>= IE 10)
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
.container {
display: grid;
grid-template-columns: 200px 1fr 200px;
height: 100%;
}
.left {
background: #002496;
}
.right {
background: #ed2738;
}
.middle {
background: #c0c0d4;
}
</style>
</head>
<body>
<div class='container'>
<div class='left'>left</div>
<div class='middle'>middle</div>
<div class='right'>right</div>
</div>
</body>
</html>
面向移動(dòng)端的話,可以考慮引入grid了这敬,畢竟手機(jī)更新?lián)Q代快,瀏覽器兼容問題沒那么嚴(yán)重崔涂。
關(guān)于flex與grid布局的選擇,要結(jié)合起來用才能發(fā)揮他們各自的優(yōu)勢(shì)冷蚂,比如:
1、對(duì)于居中(特別是垂直居中)問題艺骂、還有元素的一維分布(一條線上如何分布),用flex再合適不過了钳恕。
2、如果涉及到二維(多行多列)確定的布局忧额,使用Grid。
3睦番、涉及到響應(yīng)式的頁面元素,使用flex + width百分比寬度簡(jiǎn)直太好用托嚣,因?yàn)閒lex天生的流式布局恬涧。