們前端開發(fā)過程中,寫css(包括sass, less, stylus這樣的預處理器)進行設計稿的樣式還原是一項重要的工作,而其中,關于頁面布局的部分,又是書寫樣式代碼時候的重點和難點,這篇文章就盡可能的去總結常見的一些頁面布局實現(xiàn)方案(并不是全部,布局實現(xiàn)方法太多了),希望能夠對大家有所幫助。
在開始正題之前,有一點要說明:css布局中遇到的一個繞不開的問題就是瀏覽器兼容性,下面方案會遇到類似transform, flex等的兼容性問題,且由于grid布局兼容性問題,暫不涉及grid布局內容,在不同場景,大家選擇合適的布局實現(xiàn)方案即可。
1.1 水平居中布局
效果圖如下:
分析: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>
分析:父元素開啟定位(relative,absolute,fixed都可以)后,子元素設置絕對定位absolute后,left設置為50%,再使用transform: translateX(-50%)將子元素往反方向移動自身寬度的50%,便完成水平居中。
注意:父級元素是否脫離文檔流,不影響子元素水平居中效果,但是transform是css3屬性,存在瀏覽器兼容問題
<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>
分析:這個方法只需要對子元素進行設置就可以實現(xiàn)水平居中,margin設置auto表示瀏覽器會自動分配,實現(xiàn)來外邊距等分效果。
注意:這里子元素設置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>
效果圖如下:
這種方案和之前水平居中布局的方案二是同樣的原理,不在贅述
<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的元素具有td元素的行為,它的子元素布局方式類似文本元素,可以在父元素使用vertical-align: middle;實現(xiàn)子元素的垂直居中。
注意: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>
效果圖如下:
前面分別總結了一些水平居中和垂直居中的布局方式,那么進行水平垂直居中的布局,也就沒什么特別要說的了,直接上代碼:
方案一.定位 + 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>
分析:使用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.1 兩列布局
這里的兩列布局指的是,其中一列是定寬元素,另一列元素寬度自適應。比如,我們實現(xiàn)左列定寬,右列自適應的布局。
效果圖如下:
分析:一個最簡單的做法,左邊元素設置浮動,定寬,右邊元素的margin-left設置為左邊元素寬度大小,可以實現(xiàn)效果。
注意:我們左邊元素使用了浮動,但是右邊元素沒有浮動
<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開啟BFC,與外界隔離,所以能實現(xiàn)效果
注意:overflow:hidden的設置也使得右邊元素內容超出隱藏。這里如果不設置overflow:hidden,右邊元素的寬度是100%,有一部分被左邊浮動元素蓋住,不是我們要的結果,雖然看起來沒什么區(qū)別。
<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>
分析:這里主要是基于表格元素,在沒有設置寬度時,會自動分配寬度來實現(xiàn)布局的。
注意:設置為表格后,在某些瀏覽器可能會受到表格本身特有行為的影響,比如表格邊框等等。
<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屬性設置為不是0的正值(也就是設置flex-grow),都會占滿剩余空間。
注意:依然是,注意兼容性問題。
2.2 三列布局
這里的三列布局,主要分三種情況介紹,第一種是普通三列布局,還有兩種是比較有名的圣杯布局和雙飛翼布局(兩者都是實現(xiàn)一個兩側寬度固定,中間寬度自適應的三列布局,區(qū)別在于雙飛翼布局比起圣杯布局,中間元素會多一個子元素,而左右元素需要定位relative)
2.2.1. 普通三列布局
我們這里實現(xiàn)的是,左中兩列定寬,右邊一列自適應的布局,這個實際上和前面的兩列布局是類似的。
效果圖如下:<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>
這里的三列布局,主要分三種情況介紹,第一種是普通三列布局,還有兩種是比較有名的圣杯布局和雙飛翼布局(兩者都是實現(xiàn)一個兩側寬度固定,中間寬度自適應的三列布局,區(qū)別在于雙飛翼布局比起圣杯布局,中間元素會多一個子元素,而左右元素需要定位relative)
我們這里實現(xiàn)的是,左中兩列定寬,右邊一列自適應的布局,這個實際上和前面的兩列布局是類似的。
效果圖如下:
分析:這個方案和兩列布局方案二是相同的。
<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布局方式是相同的。
<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>
兩側寬度固定,中間寬度自適應的三列布局(中間元素不需要嵌套子元素)
效果圖如下:
分析:這種方法就是左右兩邊浮動,給定寬度,中間元素使用margin空出左右兩邊元素的位置,實現(xiàn)比較簡單。
注意:這種方式,需要在書寫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>
分析:這種方法將中間元素c放置在最前面,有利于SEO。
注意:實現(xiàn)細節(jié)在參考下面代碼中的注釋。
<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>
兩側寬度固定,中間寬度自適應的三列布局(中間元素內部增加子元素用于放置內容)
效果圖如下:
分析:這種方法為中間元素增加子元素作為內容區(qū)域,通過子元素設置margin完成。
注意:和圣杯布局對照,有相似處,也有不同,實現(xiàn)的結果是一樣的。
<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>
分析:flex實現(xiàn)就很簡單了,可以參照普通三列布局flex實現(xiàn)。
注意:還是要注意瀏覽器兼容性問題。
<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>
所謂多列等分布局,就是若干列在容器中自適應等分寬度,我們以五列等分布局為例。
效果圖如下:
分析:這種方案就是每一列浮動,之后按照百分比平分寬度,實現(xiàn)簡單。
<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,設置布局行為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布局,指定內容區(qū)域需要分為5列即可。
注意:瀏覽器兼容性問題。
<style>
.w {
/* 指定列數(shù) */
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布局十分簡單,指定每一列所占空間相同即可
<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>
所謂多列等高布局,就是多類內容可能不一樣,但是保證每一列的高度是相同的,這個高度應該由內容最多的那一列決定。
效果圖如下:
分析:父元素設置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>
分析:默認情況下,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>
所謂全屏布局,就是實現(xiàn)經典的頭部,內容區(qū),底部三大區(qū)域占滿全屏的布局,這種布局很常見。
實現(xiàn)效果如下:
分析:這里采用的方案是,頭部底部使用fixed定位,中間使用之前講到的兩列布局技術。
注意:頭部底部可以使用header, footer標簽,內容區(qū)域結構與布局都是多種多樣的。
<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>
本篇文章總結了一些常見布局的實現(xiàn)方案,css布局的實現(xiàn)方案很多,需要我們平時多去積累,選擇合適的方案。
最后,希望隨著時間的推移,兼容性不再成為我們技術實現(xiàn)的障礙,愿世界越來越美好。
最后送福利了,自己是從事了五年的前端工程師,整理了一份最全面前端學習資料,只要私信:“前端"等3秒后即可獲取地址,
里面概括應用網站開發(fā),css,html,JavaScript,jQuery,Ajax,node,angular等。等多個知識點高級進階干貨的相關視頻資料,等你來拿
網站的布局是一個網站設計的根本,CSS的Grid布局已經成為了未來網站布局的基本方式。
今天這篇文章我們通過圖文,一起看看如何自己實現(xiàn)Grid布局方式。
CSS
首先我們看看最基本的Grid布局是什么樣的,HTML頁面的代碼如下所示。
HTML代碼
然后設置其CSS屬性,這里主要展示容器的CSS屬性,給子元素添加的color屬性就不在這里展示了。
CSS屬性
在頁面上看到的效果如下,目前因為沒有對子div元素做任何設置,會自動將子div沿垂直方向排列。
頁面效果
為了讓外層的div(wrapper)為一個網格容器,需要設置其行數(shù)和列數(shù),就像一個表格一樣。
此時就需要用到grid-template-columns和grid-template-rows兩個屬性值。
grid-template-columns
用于設置網格容器的列屬性,其實就相當于列的寬度。當我們需要幾列展示時,就設置幾個值,這個屬性可以接收具體數(shù)值比如100px,也可以接收百分比值,表示占據容器的寬度。
需要注意的是:當給容器設定了寬度時,grid-template-columns設定的百分比值是以容器的寬度值為基礎計算的。如果未設置寬度時,會一直向上追溯到設置了寬度的父容器,直到body元素。
比如我們設置了以下的CSS屬性。
CSS屬性
可以看出三列寬度加起來的百分比值為120%,而且wrapper容器并未設置寬度,會一直向上追溯到body元素,這樣三列的總寬度已經超過了body的寬度,因此會出現(xiàn)滾動條。
頁面效果
grid-template-rows
用于設置網格容器的行屬性,其實就相當于行的高度,其特性與grid-template-columns屬性類似。
下面簡單修改grid-template-columns和grid-template-rows兩個屬性的值。
CSS值
得到的效果圖如下所示。
效果圖
接下來我們看看別的情況,通過CSS屬性設置3*3的網格。
CSS屬性
在頁面上的呈現(xiàn)方式如下所示。
頁面呈現(xiàn)
從頁面上看我們看不出有什么問題,但是打開控制臺后可以發(fā)現(xiàn),這個網格已經占據了3*3的空間。它后面的元素只能排列在所有的網格后面。
頁面實際情況
當我們需要得到特殊的排列方式,比如占滿整行,占滿整列,二三行合并等等。
這就需要用到grid-column和grid-row屬性,表示行網線和列網線的序號。通過設置start和end值,來進行網格的合并。
網線序號
我們重新給wrapper容器內部的div添加class類。
HTML代碼
然后添加以下的CSS代碼,給不同的網格特定的行號和列號。
CSS代碼
最終得到的效果圖如下所示。
頁面效果圖
今天這篇文章介紹了CSS中Grid布局的基礎知識,應該可以很快掌握,其他的復雜點的網格布局大家也可以自己去嘗試。
載說明:原創(chuàng)不易,未經授權,謝絕任何形式的轉載
布局是減少代碼重復并創(chuàng)建易于維護和專業(yè)外觀的應用程序的重要模式。如果您正在使用Nuxt,它提供了一個優(yōu)雅的解決方案。但不幸的是,在Vue中,官方文檔根本沒有提到它們。這經常導致對于應該在多個應用程序中相似的問題而言,采用次優(yōu)和不太正規(guī)的解決方案。
經過多次嘗試,我總結出了一種既有效又無需煩惱地擴展的架構。讓我用一個小的概念驗證來演示一下。
首先,讓我們確定一些我們的布局架構需要滿足的規(guī)則:
我們需要在頁面之間進行導航,這就是為什么我們要設置vue-router。 Vue-cli 和 vite 腳手架在創(chuàng)建新項目時提供了包含它的選項,但如果你不是從頭開始,以下是安裝它的步驟。
安裝 vue-router 依賴
npm i -D vue-router@4
聲明路由
const routes = [
{ path: "/", component: () => import("./pages/HomePage.vue") },
{ path: "/explore", component: () => import("./pages/ExplorePage.vue") },
];
導入項目
import { createApp } from "vue";
import { createRouter, createWebHashHistory } from "vue-router";
import App from "./App.vue";
import routes from "./routes.ts"
const router = createRouter({
history: createWebHashHistory(),
routes,
});
const app = createApp(App);
app.use(router);
app.mount("#app");
最后,更新App.vue文件,只包含一個 router-view 標簽。
<template>
<router-view />
</template>
我們現(xiàn)在可以在兩個頁面之間導航了,但這并不令人興奮,因為它們目前是空的。讓我們改變這種情況。
我們將創(chuàng)建以下頁面:首頁、Explore、文章和404。還有三種布局:三列、兩列和空白。
主頁是每個流行社交網絡都使用的典型三欄布局。第一欄包含應用程序的標志和導航,這在使用此布局的每個頁面上都保持不變。底部右側的頁腳也是如此。主要內容和側邊欄小部件在每個頁面上都會有所變化。
讓我們從 HomePage.vue 組件開始實施。
<script setup lang="ts">
import ThreeColumnLayout from "../layouts/ThreeColumnLayout.vue";
import ArticleCard from "../components/ArticleCard.vue";
import WidgetFriendSuggestions from "../components/WidgetFriendSuggestions.vue";
import useArticles from "../composables/useArticles";
const articles = useArticles().getArticles();
</script>
<template>
<ThreeColumnLayout>
<h2 class="text-3xl font-bold mb-4">Homepage content</h2>
<ArticleCard v-for="article in articles" :article="article" />
<template #aside>
<WidgetFriendSuggestions />
</template>
</ThreeColumnLayout>
</template>
我們將很快實現(xiàn)一個 ThreeColumnLayout 組件。默認插槽包含一個標題和一系列文章,這些文章是頁面的主要內容。此外,我們還有一個名為 aside 的具名插槽,用于聲明一個小部件。
按照通常的約定, ThreeColumnLayout 組件被放置在 /layouts 文件夾中。它將使用網格容器,并利用 grid-template-areas 來創(chuàng)建一個三列布局。
布局的實現(xiàn)細節(jié)應該是該組件的關注點,而不是頁面的關注點。可以使用flexbox、網格系統(tǒng)或任何其他技術來實現(xiàn)。如果使用全寬、盒狀或流體布局,同樣適用。
這個布局有3列
<script setup>
import AppNavigation from "../components/AppNavigation.vue";
import AppFooter from "../components/AppFooter.vue";
import AppLogo from "../components/AppLogo.vue";
</script>
<template>
<div class="three-column-layout">
<header>
<AppLogo />
<AppNavigation />
</header>
<main>
<slot />
</main>
<aside>
<slot name="aside" />
<AppFooter />
</aside>
</div>
</template>
<style scoped lang="scss">
.three-column-layout {
display: grid;
grid-template-areas:
"header"
"main"
"aside";
header {
grid-area: header;
margin-top: 30px;
}
main {
grid-area: main;
margin-top: 10px;
padding: 20px;
}
aside {
grid-area: aside;
margin-top: 10px;
padding: 20px;
}
@media (min-width: 768px) {
grid-template-columns: 1fr 3fr 1fr;
grid-template-areas: "header main aside";
}
}
</style>
創(chuàng)建一個具有相同布局的新頁面將展示出這種方法的簡潔性。
文章頁面還將在默認插槽中包含獨特的內容,并在側邊欄上添加一個額外的小部件:
<script setup>
import ThreeColumnLayout from "../layouts/ThreeColumnLayout.vue";
import WidgetRelatedContent from "../components/WidgetRelatedContent.vue";
import WidgetFriendSuggestions from "../components/WidgetFriendSuggestions.vue";
import { useRoute } from "vue-router";
import useArticles from "../composables/useArticles";
const article = useArticles().getArticle(useRoute().params.id);
</script>
<template>
<ThreeColumnLayout>
<h2 class="text-3xl font-bold mb-4">{{ article.title }}</h2>
<div class="max-w-md" v-html="article.description"></div>
<template #aside>
<WidgetFriendSuggestions />
<WidgetRelatedContent />
</template>
</ThreeColumnLayout>
</template>
對于探索頁面(Explore),我們將創(chuàng)建一個兩列布局。第一列將與三列布局相同,但主要部分將占據屏幕的其余部分,并在底部放置頁腳。
這次的實現(xiàn)看起來與之前的并沒有太大的區(qū)別。但是這次我們使用 flex 和 flex-basis 只是為了展示一種不同的創(chuàng)建CSS布局的方式。在實際情況中,所有的實現(xiàn)都應該使用相同的技術。
<script setup>
import AppNavigation from "../components/AppNavigation.vue";
import AppLogo from "../components/AppLogo.vue";
import AppFooter from "../components/AppFooter.vue";
</script>
<template>
<div class="two-column-layout">
<header>
<AppLogo />
<AppNavigation />
</header>
<main>
<slot />
<AppFooter />
</main>
</div>
</template>
<style scoped>
.two-column-layout {
display: flex;
@media (max-width: 768px) {
flex-direction: column;
}
}
header {
flex-basis: 20%;
margin-top: 30px;
}
main {
flex-basis: 80%;
margin-top: 10px;
padding: 20px;
}
</style>
使用這種布局的探索頁面非常簡單
<script setup>
import TwoColumnLayout from "../layouts/TwoColumnLayout.vue";
import ExploreItem from "../components/ExploreItem.vue";
import useArticles from "../composables/useArticles";
const articles = useArticles().getExploreArticles();
</script>
<template>
<TwoColumnLayout>
<h2 class="text-3xl font-bold mb-12">
Latest content on <a target="_blank" href="https://dev.to/">Dev.to</a>
</h2>
<div class="grid lg:grid-cols-3 gap-6">
<ExploreItem v-for="article in articles" :article="article" />
</div>
</TwoColumnLayout>
</template>
最后,讓我們創(chuàng)建一個可以用于404頁面的空白全頁布局。
<template>
<main class="container my-24 px-6 mx-auto">
<slot />
</main>
</template>
即使實現(xiàn)簡單,只使用一個居中容器(這次使用tailwind.css),使用布局仍然很重要。
這樣我們可以保持頁面組件的簡潔,并確保使用此布局的多個頁面外觀和行為一致。
<script setup>
import BlankLayout from "../layouts/BlankLayout.vue";
import PageNotFound from "../components/PageNotFound.vue";
</script>
<template>
<BlankLayout>
<PageNotFound />
</BlankLayout>
</template>
布局是減少樣板代碼和保持專業(yè)外觀的重要工具。結合完善的文件夾結構,可以創(chuàng)建一個讓每個人都喜歡使用的代碼庫。
由于文章內容篇幅有限,今天的內容就分享到這里,文章結尾,我想提醒您,文章的創(chuàng)作不易,如果您喜歡我的分享,請別忘了點贊和轉發(fā),讓更多有需要的人看到。同時,如果您想獲取更多前端技術的知識,歡迎關注我,您的支持將是我分享最大的動力。我會持續(xù)輸出更多內容,敬請期待。
*請認真填寫需求信息,我們會在24小時內與您取得聯(lián)系。