我們前端開發過程中,寫css(包括sass, less, stylus這樣的預處理器)進行設計稿的樣式還原是一項重要的工作,而其中,關於頁面佈局的部分,又是書寫樣式代碼時候的重點和難點,這篇文章就儘可能的去總結常見的一些頁面佈局實現方案(並不是全部,佈局實現方法太多了),希望能夠對大家有所幫助。
在開始正題之前,有一點要說明:css佈局中遇到的一個繞不開的問題就是瀏覽器兼容性,下面方案會遇到類似transform, flex等的兼容性問題,且由於grid佈局兼容性問題,暫不涉及grid佈局內容,在不同場景,大家選擇合適的佈局實現方案即可。
1. 居中相關的佈局
1.1 水平居中佈局
效果圖如下:
方案一. inline-block + text-align
分析:display設置爲inline-block的元素,具有文本元素的性質,其父元素可以通過設置文本對齊屬性text-align來控制其在行內的對齊方式,text-align: center即爲水平對齊
注意:text-align屬性是具有繼承性的,會導致自己元素內部的文本也是居中顯示的,需要自身設置text-align覆蓋
<style>
.wrap {
width: 100%;
height: 200px;
background-color: aqua;
text-align: center;
}
.content {
width: 200px;
height: 200px;
background-color: blueviolet;
display: inline-block;
}
</style>
<body>
<div class="wrap">
<div class="content"></div>
</div>
</body>
方案二. 定位 + transform
分析:父元素開啓定位(relative,absolute,fixed都可以)後,子元素設置絕對定位absolute後,left設置爲50%,再使用transform: translateX(-50%)將子元素往反方向移動自身寬度的50%,便完成水平居中。
注意:父級元素是否脫離文檔流,不影響子元素水平居中效果,但是transform是css3屬性,存在瀏覽器兼容問題
本次給大家推薦一個免費的學習蔻qun,前面603 中間985最後993,裏面概括應用網站開發,css,html,JavaScript,jQuery,Ajax,node,angular等。對web前端開發技術感興趣的同學,不管你是小白還是大牛我都歡迎,每天技術分享。
<style>
.wrap {
position: relative;
width: 100%;
height: 200px;
background-color: aqua;
}
.content {
position: absolute;
left: 50%;
transform: translateX(-50%);
width: 200px;
height: 200px;
background-color: blueviolet;
}
</style>
<body>
<div class="wrap">
<div class="content"></div>
</div>
</body>
方案三. display: block + margin: 0 auto
分析:這個方法只需要對子元素進行設置就可以實現水平居中,margin設置auto表示瀏覽器會自動分配,實現來外邊距等分效果。
注意:這裏子元素設置display爲block或者table都是可以的,如果子元素脫離文檔流(浮動,定位),會導致margin屬性的值無效。
<style>
.wrap {
width: 100%;
height: 200px;
background-color: aqua;
}
.content {
width: 200px;
height: 200px;
background-color: blueviolet;
display: table;
margin: 0 auto;
}
</style>
<body>
<div class="wrap">
<div class="content"></div>
</div>
</body>
1.2 垂直居中佈局
效果圖如下:
方案一. 定位 + transform
這種方案和之前水平居中佈局的方案二是同樣的原理,不在贅述
<style>
.wrap {
position: relative;
width: 200px;
height: 600px;
background-color: aqua;
}
.content {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 200px;
height: 200px;
background-color: blueviolet;
}
</style>
<body>
<div class="wrap">
<div class="content"></div>
</div>
</body>
方案二. display: table-cell + vertical-align
分析:設置display: table-cell的元素具有td元素的行爲,它的子元素佈局方式類似文本元素,可以在父元素使用vertical-align: middle;實現子元素的垂直居中。
注意:vertical-align屬性具有繼承性,導致父元素內文本也是垂直居中顯示的。
<style>
.wrap {
display: table-cell;
vertical-align: middle;
width: 200px;
height: 600px;
background-color: aqua;
}
.content {
width: 200px;
height: 200px;
background-color: blueviolet;
}
</style>
<body>
<div class="wrap">
<div class="content"></div>
</div>
</body>
1.3 水平垂直居中佈局
效果圖如下:
前面分別總結了一些水平居中和垂直居中的佈局方式,那麼進行水平垂直居中的佈局,也就沒什麼特別要說的了,直接上代碼:
方案一.定位 + transform
<style>
.wrap {
position: relative;
width: 1200px;
height: 800px;
background-color: aqua;
}
.content {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 200px;
height: 200px;
background-color: blueviolet;
}
</style>
<body>
<div class="wrap">
<div class="content"></div>
</div>
</body>
方案二. 結合水平佈局方案三,垂直佈局方案二
<style>
.wrap {
display: table-cell;
vertical-align: middle;
width: 1200px;
height: 800px;
background-color: aqua;
}
.content {
margin: 0 auto;
width: 200px;
height: 200px;
background-color: blueviolet;
}
</style>
<body>
<div class="wrap">
<div class="content"></div>
</div>
</body>
1.4 使用flex進行居中佈局
分析:使用flex,水平垂直居中會變得非常容易,默認情況下,align-items: center垂直居中(交叉軸排列方式),justify-content: center水平居中(主軸排列方式) 注意:需要考慮瀏覽器兼容性問題。
<style>
.wrap {
display: flex;
align-items: center;
justify-content: center;
width: 1200px;
height: 800px;
background-color: aqua;
}
.content {
width: 200px;
height: 200px;
background-color: blueviolet;
}
</style>
<body>
<div class="wrap">
<div class="content"></div>
</div>
</body>
2. N列布局
2.1 兩列布局
這裏的兩列布局指的是,其中一列是定寬元素,另一列元素寬度自適應。比如,我們實現左列定寬,右列自適應的佈局。
效果圖如下:
方案一. 左邊元素浮動,定寬,右邊元素設置margin-left
分析:一個最簡單的做法,左邊元素設置浮動,定寬,右邊元素的margin-left設置爲左邊元素寬度大小,可以實現效果。
注意:我們左邊元素使用了浮動,但是右邊元素沒有浮動
<style>
.l, .r {
height: 600px;
}
.l {
width: 400px;
background-color: aqua;
float: left;
}
.r {
background-color: blueviolet;
margin-left: 400px;
}
</style>
<body>
<div class="l">定寬</div>
<div class="r">自適應</div>
</body>
方案二. 左邊元素浮動,定寬,右邊元素設置overflow:hidden
分析:右邊元素由於設置overflow:hidden開啓BFC,與外界隔離,所以能實現效果
注意:overflow:hidden的設置也使得右邊元素內容超出隱藏。這裏如果不設置overflow:hidden,右邊元素的寬度是100%,有一部分被左邊浮動元素蓋住,不是我們要的結果,雖然看起來沒什麼區別。
<style>
.l, .r {
height: 600px;
}
.l {
width: 400px;
background-color: aqua;
float: left;
}
.r {
background-color: blueviolet;
overflow: hidden;
}
</style>
<body>
<div class="l">定寬</div>
<div class="r">自適應</div>
</body>
方案三.將左右元素用一個display:table的元素包裹,左右元素設置爲display: table-cell
分析:這裏主要是基於表格元素,在沒有設置寬度時,會自動分配寬度來實現佈局的。
注意:設置爲表格後,在某些瀏覽器可能會受到表格本身特有行爲的影響,比如表格邊框等等。
<style>
.w {
display: table;
table-layout: fixed;
width: 100%;
}
.l, .r {
display: table-cell;
height: 600px;
}
.l {
width: 400px;
background-color: aqua;
}
.r {
background-color: blueviolet;
}
</style>
<body>
<div class="w">
<div class="l">定寬</div>
<div class="r">自適應</div>
</div>
</body>
方案四. flex佈局
分析:父容器採用flex佈局,左邊元素定寬之後,右邊元素,因爲只有一個,所以flex屬性設置爲不是0的正值(也就是設置flex-grow),都會佔滿剩餘空間。
注意:依然是,注意兼容性問題。
2.2 三列布局
這裏的三列布局,主要分三種情況介紹,第一種是普通三列布局,還有兩種是比較有名的聖盃佈局和雙飛翼佈局(兩者都是實現一個兩側寬度固定,中間寬度自適應的三列布局,區別在於雙飛翼佈局比起聖盃佈局,中間元素會多一個子元素,而左右元素需要定位relative)
2.2.1. 普通三列布局
我們這裏實現的是,左中兩列定寬,右邊一列自適應的佈局,這個實際上和前面的兩列布局是類似的。
效果圖如下:<style>
.p {
display: flex;
height: 600px;
}
.l {
background-color: aqua;
width: 400px;
}
.r {
flex: 1;
background-color: blueviolet;
}
</style>
<body>
<div class="p">
<div class="l">定寬</div>
<div class="r">自適應</div>
</div>
</body>
2.2 三列布局
這裏的三列布局,主要分三種情況介紹,第一種是普通三列布局,還有兩種是比較有名的聖盃佈局和雙飛翼佈局(兩者都是實現一個兩側寬度固定,中間寬度自適應的三列布局,區別在於雙飛翼佈局比起聖盃佈局,中間元素會多一個子元素,而左右元素需要定位relative)
2.2.1. 普通三列布局
我們這裏實現的是,左中兩列定寬,右邊一列自適應的佈局,這個實際上和前面的兩列布局是類似的。
效果圖如下:
方案一. 定寬 + overflow:hidden
分析:這個方案和兩列布局方案二是相同的。
<style>
.l, .c, .r {
height: 600px;
}
.l {
width: 400px;
background-color: aqua;
float: left;
}
.c {
width: 400px;
background-color: blueviolet;
float: left;
}
.r {
background-color: brown;
overflow: hidden;
}
</style>
<body>
<div class="l">定寬</div>
<div class="c">定寬</div>
<div class="r">自適應</div>
</body>
方案二. flex佈局
分析:這裏佈局原理和兩列布局中flex佈局方式是相同的。
<style>
.w {
display: flex;
height: 600px;
}
.l {
width: 400px;
background-color: aqua;
}
.c {
width: 400px;
background-color: blueviolet;
}
.r {
flex: 1;
background-color: brown;
}
</style>
<body>
<div class="w">
<div class="l">定寬</div>
<div class="c">定寬</div>
<div class="r">自適應</div>
</div>
</body>
2.2.2. 聖盃佈局
兩側寬度固定,中間寬度自適應的三列布局(中間元素不需要嵌套子元素)
效果圖如下:
方案一. 左右兩側浮動,中間元素使用margin
分析:這種方法就是左右兩邊浮動,給定寬度,中間元素使用margin空出左右兩邊元素的位置,實現比較簡單。
注意:這種方式,需要在書寫html結構時,將右側元素寫在中間元素的前面,因爲如果右側元素在中間元素後面,由於浮動元素位置上不能高於(或平級)前面的非浮動元素,導致右側元素會下沉。但是,中間元素一般都是頁面的核心部分,放在比較後面的位置,不利於SEO。
<style>
.l, .c, .r {
height: 600px;
}
.l {
width: 400px;
background-color: aqua;
float: left;
}
.c {
background-color: blueviolet;
margin-left: 400px;
margin-right: 400px;
}
.r {
width: 400px;
background-color: brown;
float: right;
}
</style>
<body>
<div class="l">定寬</div>
<div class="r">定寬</div>
<div class="c">自適應</div>
</body>
方案二. 父容器使用margin,左中右元素均浮動,利用定位和margin移動到正確位置
分析:這種方法將中間元素c放置在最前面,有利於SEO。
注意:實現細節在參考下面代碼中的註釋。
<style>
.w {
/* margin-left對應左邊元素l的寬度,margin-right對應右邊元素r的寬度 */
margin-left: 400px;
margin-right: 400px;
}
.l, .c, .r {
height: 600px;
float: left;
}
.l {
width: 400px;
background-color: aqua;
position: relative;
/* 爲了讓l元素從當前行移動到第一行同一位置*/
margin-left: -100%;
/* 移動到中間元素左側正確位置 */
left: -400px;
}
.c {
width: 100%;
background-color: blueviolet;
}
.r {
width: 400px;
background-color: brown;
position: relative;
/* 爲了讓l元素從當前行移動到上一行*/
margin-left: -400px;
right: -400px;
}
</style>
<body>
<div class="w">
<div class="c">自適應</div>
<div class="l">定寬</div>
<div class="r">定寬</div>
</div>
</body>
2.2.3. 雙飛翼佈局
兩側寬度固定,中間寬度自適應的三列布局(中間元素內部增加子元素用於放置內容)
效果圖如下:
方案一. 中間元素子元素設置margin,左中右元素均設置浮動,左右元素通過margin移動到正確位置
分析:這種方法爲中間元素增加子元素作爲內容區域,通過子元素設置margin完成。
注意:和聖盃佈局對照,有相似處,也有不同,實現的結果是一樣的。
<style>
.l, .c, .r {
height: 600px;
float: left;
}
.l {
width: 400px;
background-color: aqua;
/* 爲了讓l元素從當前行移動到第一行同一位置*/
margin-left: -100%;
}
.c {
width: 100%;
background-color: blue;
}
.i {
height: 600px;
background-color: blueviolet;
margin-left: 400px;
margin-right: 400px;
}
.r {
width: 400px;
background-color: brown;
/* 爲了讓r元素移動到第一行*/
margin-left: -400px;
}
</style>
<body>
<div class="c">
<div class="i">自適應</div>
</div>
<div class="l">定寬</div>
<div class="r">定寬</div>
</body>
2.2.4. flex佈局實現(中間自適應,左右等寬)
分析:flex實現就很簡單了,可以參照普通三列布局flex實現。
注意:還是要注意瀏覽器兼容性問題。
<style>
.w {
display: flex;
height: 600px;
}
.l {
width: 400px;
background-color: aqua;
}
.c {
flex: 1;
background-color: blueviolet;
}
.r {
width: 400px;
background-color: brown;
}
</style>
<body>
<div class="w">
<div class="l">定寬</div>
<div class="c">自適應</div>
<div class="r">定寬</div>
</div>
</body>
2.3 多列等分佈局
所謂多列等分佈局,就是若干列在容器中自適應等分寬度,我們以五列等分佈局爲例。
效果圖如下:
方案一. 浮動 + 百分數平分
分析:這種方案就是每一列浮動,之後按照百分比平分寬度,實現簡單。
<style>
.col {
float: left;
width: 20%;
height: 300px;
}
.col1 {
background-color: blue;
}
.col2 {
background-color: blueviolet;
}
.col3 {
background-color: aqua;
}
.col4 {
background-color: beige;
}
.col5 {
background-color: salmon;
}
</style>
<body>
<div class="w">
<div class="col col1"></div>
<div class="col col2"></div>
<div class="col col3"></div>
<div class="col col4"></div>
<div class="col col5"></div>
</div>
</body>
方案二. 使用display: table佈局
分析:父容器指定display: table,設置佈局行爲table-layout: fixed,指定每個表格等寬。
注意:table-layout: fixed是需要設置的,默認情況下,列寬度由單元格內容設定,設置之後,列寬由表格寬度和列寬度設定。
<style>
.w {
display: table;
/* 列寬由表格寬度和列寬度設定 */
table-layout: fixed;
width: 100%;
}
.col {
display: table-cell;
height: 300px;
}
.col1 {
background-color: blue;
}
.col2 {
background-color: blueviolet;
}
.col3 {
background-color: aqua;
}
.col4 {
background-color: beige;
}
.col5 {
background-color: salmon;
}
</style>
<body>
<div class="w">
<div class="col col1"></div>
<div class="col col2"></div>
<div class="col col3"></div>
<div class="col col4"></div>
<div class="col col5"></div>
</div>
</body>
方案三. 使用column佈局
分析:使用column佈局,指定內容區域需要分爲5列即可。
注意:瀏覽器兼容性問題。
<style>
.w {
/* 指定列數 */
column-count: 5;
/* 指定列與列之間的間隙,默認1em */
column-gap: 0;
}
.col {
height: 300px;
}
.col1 {
background-color: blue;
}
.col2 {
background-color: blueviolet;
}
.col3 {
background-color: aqua;
}
.col4 {
background-color: beige;
}
.col5 {
background-color: salmon;
}
</style>
<body>
<div class="w">
<div class="col col1"></div>
<div class="col col2"></div>
<div class="col col3"></div>
<div class="col col4"></div>
<div class="col col5"></div>
</div>
</body>
方案四. 使用flex佈局
分析:使用flex佈局十分簡單,指定每一列所佔空間相同即可
<style>
.w {
display: flex;
}
.col {
height: 300px;
flex: 1;
}
.col1 {
background-color: blue;
}
.col2 {
background-color: blueviolet;
}
.col3 {
background-color: aqua;
}
.col4 {
background-color: beige;
}
.col5 {
background-color: salmon;
}
</style>
<body>
<div class="w">
<div class="col col1"></div>
<div class="col col2"></div>
<div class="col col3"></div>
<div class="col col4"></div>
<div class="col col5"></div>
</div>
</body>
</html>
2.4 多列等高佈局
所謂多列等高佈局,就是多類內容可能不一樣,但是保證每一列的高度是相同的,這個高度應該由內容最多的那一列決定。
效果圖如下:
方案一. 使用display: table佈局
分析:父元素設置display: table,子元素設置display: table-cell,這樣佈局就是按照表格行爲佈局,表格單元格默認等高。
<style>
.w {
display: table;
}
.col {
display: table-cell;
width: 20%;
}
.col1 {
background-color: blue;
}
.col2 {
background-color: blueviolet;
}
.col3 {
background-color: aqua;
}
.col4 {
background-color: beige;
}
.col5 {
background-color: salmon;
}
</style>
<body>
<div class="w">
<div class="col col1">啊啊啊啊啊啊啊啊啊啊啊啊</div>
<div class="col col2">啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊</div>
<div class="col col3">啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊</div>
<div class="col col4"></div>
<div class="col col5">啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊</div>
</div>
</body>
方案二. 使用flex佈局
分析:默認情況下,display: flex的元素align-items屬性值爲stretch,如果項目未設置高度或設爲auto,將佔滿整個容器的高度。
<style>
.w {
display: flex;
}
.col {
flex: 1;
}
.col1 {
background-color: blue;
}
.col2 {
background-color: blueviolet;
}
.col3 {
background-color: aqua;
}
.col4 {
background-color: beige;
}
.col5 {
background-color: salmon;
}
</style>
<body>
<div class="w">
<div class="col col1">啊啊啊啊啊啊啊啊啊啊啊啊</div>
<div class="col col2">啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊</div>
<div class="col col3">啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊</div>
<div class="col col4"></div>
<div class="col col5">啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊</div>
</div>
</body>
- 全屏佈局
所謂全屏佈局,就是實現經典的頭部,內容區,底部三大區域佔滿全屏的佈局,這種佈局很常見。
實現效果如下:
分析:這裏採用的方案是,頭部底部使用fixed定位,中間使用之前講到的兩列布局技術。
注意:頭部底部可以使用header, footer標籤,內容區域結構與佈局都是多種多樣的。
<style>
html, body {
margin: 0;
overflow: hidden;
}
.header {
position: fixed;
left: 0;
top: 0;
right: 0;
height: 100px;
background-color: salmon;
}
.w {
position: fixed;
left: 0;
right: 0;
top: 100px;
bottom: 100px;
overflow: auto;
background-color: palevioletred;
}
.w .l {
width: 400px;
/* height: 100%; */
position: fixed;
left: 0;
top: 100px;
bottom: 100px;
background-color: greenyellow;
}
.w .r {
position: fixed;
left: 400px;
right: 0;
top: 100px;
bottom: 100px;
background-color: blueviolet;
}
.footer {
position: fixed;
left: 0;
right: 0;
bottom: 0;
height: 100px;
background-color: goldenrod;
}
</style>
<body>
<div class="header"></div>
<div class="w">
<div class="l"></div>
<div class="r"></div>
</div>
<div class="footer"></div>
</body>
本篇文章總結了一些常見佈局的實現方案,css佈局的實現方案很多,需要我們平時多去積累,選擇合適的方案。
最後,希望隨着時間的推移,兼容性不再成爲我們技術實現的障礙,願世界越來越美好。