前言
網頁布局是前端網頁開發的第一步,是最最基礎的部分,也是非常重要的部分。布局就是搭建網頁的整體結構,好的布局不僅可以增加代碼的可讀性,提高開發效率,讓人心中有丘壑,而且還可以提高代碼的可復用性,且便於后期維護,是從事前端開發的小伙伴們需要重視的基本技能。本篇就着重介紹幾種常用的頁面布局方法。
居中布局
開頭先說明一下,這里的居中方案都是可以適用於父容器和子容器都既不定寬也不定高的條件下的,所以自然也可以適用於定寬和定高的條件下。
一、水平居中布局
1. 水平居中:absolute + transform: translateX(-50%)
另外:
- 除了
transform: translateX(-50%)這種方式以外,還可以采用給子容器設置負margin值的方法實現居中(其絕對值必須為子容器寬度的一半),但前提是必須要知道子容器的寬度,也就是說子元素要定寬。
HTML:
<div class="parent">
<div class="child">DEMO</div>
</div>
CSS:
.parent {
position: relative; /* 如果不寫這句,下面子元素的定位將不會是相對父級的絕對定位 */
}
.child {
position: absolute;
left: 50%;
transform: translateX(-50%); /* 相對自身偏移-50% */
}
2. 水平居中:flex + justify content: center
另外:
- 除了給父容器設置
justify-content:center這種方式以外,還可以采用在子容器設置margin:0 auto的方法實現居中,因為flex元素是支持margin: 0 auto的。
HTML:
<div class="parent">
<div class="child">DEMO</div>
</div>
CSS:
.parent {
display: flex; /* flex布局 */
justify-content: center;
}
3. 水平居中:inline-block + text-align: center
在使用inline-block布局時需要注意的是:
vertical-align屬性會影響到inline-block元素,你可能會想把它的值設置為top;- 設置在父容器的
text-align:center會繼承到子容器,如果要改變子容器的text-align屬性,則需要重新設置進行覆蓋; - 如果HTML源代碼中元素之間有空格,那么列與列之間會產生空隙。
HTML:
<div class="parent">
<div class="child">DEMO</div>
</div>
CSS:
.parent {
text-align: center; /* text-align設置在塊級元素的時候可以對里面的inline元素起作用 */
}
.child {
display: inline-block;
}
4. 水平居中:table + margin: 0 auto
給子元素設置display:table屬性,並且不設置寬度時,可以使其寬度由內容撐開,適合需要寬度自適應的水平居中布局。
HTML:
<div class="parent">
<div class="child">DEMO</div>
</div>
CSS:
.child {
display: table; /* table在沒有對它進行寬度100%的設置的時候,它的寬度就是和內容一樣寬 */
margin: 0 auto;
}
5. 水平居中:table-cell + text-align: center + inline-block
display:table-cell屬性指讓標簽元素以表格單元格的形式呈現,類似於td標簽。td單元格有一些比較特別的屬性,例如元素的垂直居中對齊,關聯伸縮等,所以display:table-cell還是有不少潛在的使用價值的。需要注意的是:
- 與其他一些display屬性類似,
table-cell同樣會被其他一些CSS屬性破壞,例如float,position:absolute,所以,在使用display:table-cell時,與float:left或是position:absolute屬性盡量要同時使用; - 設置了
display:table-cell的元素對寬度高度敏感,對margin值無反應,響應padding屬性,基本上就是活脫脫的一個td標簽元素了。
HTML:
<div class="parent">
<div class="child">DEMO</div>
</div>
CSS:
.parent {
display: table-cell;
text-align: center;
}
.child {
display: inline-block;
}
二、垂直居中布局
1. 垂直居中:absolute + transform: translateY(-50%)
HTML:
<div class="parent">
<div class="child">DEMO</div>
</div>
CSS:
.parent {
position: relative; /* 如果不寫這句,下面子元素的定位將不會是相對父級的絕對定位 */
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%); /* 相對自身偏移-50% */
}
2. 垂直居中:flex + align-items
注意:如果不設置align-items:center,那么其默認值則是stretch,這時子容器將撐滿父容器的高度;
HTML:
<div class="parent">
<div class="child">DEMO</div>
</div>
CSS:
.parent {
display: flex;
align-items: center; /* 默認值是stretch, 即拉伸, 改為center即可居中 */
}
3. table-cell + vertical-align
display:table-cell的屬性上面的水平居中已經大致交代過了,這里再提醒一下需要注意:
- 與其他一些display屬性類似,
table-cell同樣會被其他一些CSS屬性破壞,例如float,position:absolute,所以,在使用display:table-cell時,與float:left或是position:absolute屬性盡量不要同時使用; - 設置了
display:table-cell的元素對寬度高度敏感,對margin值無反應,響應padding屬性,基本上就是活脫脫的一個td標簽元素了。
HTML:
<div class="parent">
<div class="child">DEMO</div>
</div>
CSS:
.parent {
display: table-cell;
vertical-align: middle;
}
三、水平方向和垂直方向同時居中布局
1. 同時居中:absolute + transform: translate(-50%, -50%)
另外:
- 除了
transform: translate(-50%, -50%)這種方式以外,還可以采用給子容器設置負margin值的方法實現居中(其絕對值必須為子容器寬度和高度的一半),但前提是必須要知道子容器的寬度和高度,也就是子元素要定寬定高。
HTML:
<div class="parent">
<div class="child">DEMO</div>
</div>
CSS:
.parent {
position: relative; /* 如果不寫這句,下面子元素的定位將不會是相對父級的絕對定位 */
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* 相對自身偏移-50% */
}
2. 同時居中:inline-block + text-align: center + table-cell + vertical-align
HTML:
<div class="parent">
<div class="child">DEMO</div>
</div>
CSS:
.parent {
text-align: center;
display: table-cell;
vertical-align: middle;
}
.child {
display: inline-block;
}
3. 同時居中:flex + justify-content + align-items
HTML:
<div class="parent">
<div class="child">DEMO</div>
</div>
CSS:
.parent {
display: flex;
justify-content: center;
align-items: center; /* 默認值是stretch, 即拉伸, 改為center即可居中 */
}
多列布局
一、定寬 + 自適應
left和center容器定寬,right容器自適應。
1. float + margin
HTML:
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
CSS:
.left {
float: left;
width: 100px;
}
.right {
margin-left: 120px; /* 多出的20px作為left容器與right容器之間的邊距 */
}
2. float + overflow
HTML:
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="center">
<p>center</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
CSS:
.left, .center {
float: left;
width: 100px;
margin-right: 20px; /* 邊距 */
}
.right {
overflow: hidden; /* BFC原理 */
}
3. table
HTML:
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="center">
<p>center</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
CSS:
.parent {
display: table;
width: 100%; /* 如果不設置,寬度將由內容決定 */
table-layout: fixed; /* 如果不設置,table內部子容器的寬度可能會被內容影響,即使設置了子容器的寬度也是如此 */
}
.left, .center, .right {
display: table-cell;
}
.left, .center {
width: 100px;
padding-right: 20px; /* table-cell相當於td元素,是不能設置margin的,所以用padding代替 */
}
4. flex
HTML:
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="center">
<p>center</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
CSS:
.parent {
display: flex;
}
.left, .center {
width: 100px;
margin-right: 20px; /* 邊距 */
}
.right {
flex: 1; /* flex: 1 1 0%; */
}
二、不定寬 + 自適應
left和center容器不定寬(即寬度由內容撐開),right容器自適應。
1. float + overflow
HTML:
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="center">
<p>center</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
CSS:
.left, .center {
float: left;
margin-right: 20px; /* 邊距 */
}
.right {
overflow: hidden;
}
2. table
HTML:
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="center">
<p>center</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
CSS:
.parent {
display: table;
width: 100%; /* 如果不設置,寬度將由內容決定 */
/* 這里不設置table-layout: fixed,因為我們需要table內部子容器的寬度由內容決定 */
}
.left, .center, .right {
display: table-cell;
}
.left, .center {
width: 0.1%; /* table-cell的特性,內容優先 */
padding-right: 20px; /* table-cell相當於td元素,是不能設置margin的,所以用padding代替 */
}
3. flex
HTML:
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="center">
<p>center</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
CSS:
.parent {
display: flex;
}
.left, .center {
margin-right: 20px; /* 邊距 */
}
.right {
flex: 1; /* flex: 1 1 0%; */
}
三、等寬
當父容器中有N個列時,它們的列寬相等,並且當父容器變寬(或變窄)時,這些列也要相應的變寬(或變窄)。
1. float
HTML:
<div class="parent">
<div class="column"><p>1</p></div>
<div class="column"><p>2</p></div>
<div class="column"><p>3</p></div>
<div class="column"><p>4</p></div>
</div>
CSS:
.parent {
margin-left: -20px; /* 將父容器撐開20px,但名義寬度不變,這20px是內部列與列之間的邊距 */
}
.column {
float: left;
width: 25%; /* 由列數決定 */
padding-left: 20px; /* 列與列之間的邊距 */
box-sizing: border-box; /* 意味着padding-left值被包含在25%的寬度中 */
}
2. table
HTML:
<div class="parent-fix">
<div class="parent">
<div class="column"><p>1</p></div>
<div class="column"><p>2</p></div>
<div class="column"><p>3</p></div>
<div class="column"><p>4</p></div>
</div>
</div>
CSS:
.parent-fix {
margin-left: -20px; /* 將父容器撐開20px,但名義寬度不變,這20px是內部列與列之間的邊距,但是table不能設置margin值,所以在parent外面再加一個修正用的容器 */
}
.parent {
display: table;
width: 100%;
table-layout: fixed; /* 設置為fixed時,列寬會相等 */
}
.column {
display: table-cell;
padding-left: 20px; /* 列與列之間的邊距 */
}
3. flex
HTML:
<div class="parent">
<div class="column"><p>1</p></div>
<div class="column"><p>2</p></div>
<div class="column"><p>3</p></div>
<div class="column"><p>4</p></div>
</div>
CSS:
.parent {
display: flex;
}
.column {
flex: 1;
}
.column + .column {
margin-left: 20px;
}
四、等高
1. table
HTML:
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
CSS:
.parent {
display: table;
width: 100%;
table-layout: fixed;
}
.left, .right {
display: table-cell;
}
.left {
width: 100px; /* 不設置也沒關系 */
border-right: 20px solid transparent; /* 通過border來設置間距 */
background-clip: padding-box; /* 背景顏色默認會顯示到border部分,也就是border-box,所以這里設置到padding-box */
}
2. flex
HTML:
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
CSS:
.parent {
display: flex;
}
.left {
width: 100px;
margin-right: 20px;
}
.right {
flex: 1;
}
3. float
偽等高方案,只是背景顏色一樣高,不推薦。
HTML:
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
CSS:
.parent {
overflow: hidden; /* 必須 */
}
.left {
float: left;
width: 100px;
margin-right: 20px;
}
.right {
overflow: hidden;
}
.left, .right {
padding-bottom: 9999px;
margin-bottom: -9999px;
} /* 一升一降 */
