震驚!CSS中實(shí)現(xiàn)塊級(jí)元素水平居中的N種方法
首先聲明我不是標(biāo)題黨,這篇博客還是干貨滿滿的~
最近寫作業(yè)的時(shí)候遇到這么一道題:
網(wǎng)頁由box1、box2、box3、box4四個(gè)盒子組成,請(qǐng)實(shí)現(xiàn)如下效果:
1、2、3號(hào)盒子在一行;
4號(hào)盒子在2號(hào)盒子的正下方。
最簡(jiǎn)單的想法是四個(gè)盒子均用絕對(duì)定位,但是這種實(shí)現(xiàn)方法代碼量大、需要計(jì)算每個(gè)盒子的位置、不靈活(如果盒子的大小改變了難以修改)。
另一種想法是,三個(gè)盒子排在一行可以用float實(shí)現(xiàn),第四個(gè)盒子用絕對(duì)定位,但是依然存在上述問題。
因此如果能讓這些盒子自己在頁面居中,那無論盒子的尺寸和數(shù)目如何改變均可輕松實(shí)現(xiàn)想要的效果了。
學(xué)習(xí)了一下網(wǎng)上大牛們給出的方法,發(fā)現(xiàn)塊級(jí)元素的水平居中可以通過N種方式實(shí)現(xiàn)!
1. 利用margin-left&right=auto實(shí)現(xiàn)元素居中
對(duì)于單個(gè)塊級(jí)元素的水平居中可以通過將margin-left和margin-left設(shè)置為auto來實(shí)現(xiàn)。
以一個(gè)box為例,CSS部分具體代碼為:
div {
background: grey;
color: white;
text-align: center;
width: 400px;
height: 400px;
margin-left: auto;
margin-right: auto;
}
實(shí)現(xiàn)的效果為:

注意:該方法需要元素的寬度已知。
另外,如果需要水平居中多個(gè)塊級(jí)元素,就要使用另外的方法了。
2. 利用inline-block實(shí)現(xiàn)元素居中
將需要居中的塊級(jí)元素的display屬性設(shè)置為inline-block,并將其父元素的text-align屬性設(shè)置為center即可實(shí)現(xiàn)多個(gè)塊級(jí)元素的水平居中。
這里用到了行級(jí)格式化上下文(IFC)的概念。這種方法實(shí)際上是通過inline-block將三個(gè)box組成一個(gè)整體,此時(shí)<body>作為一個(gè)行盒可以通過text-align屬性設(shè)置其內(nèi)部元素的水平分布。
以三個(gè)box為例,HTML部分代碼為:
<body>
<div id="box1">
<p>box1</p>
</div>
<div id="box2">
<p>box2</p>
</div>
<div id="box3">
<p>box3</p>
</div>
</body>
CSS部分代碼為:
div {
height: 200px;
width: 200px;
background: grey;
color: white;
display: inline-block;
}
body {
text-align: center;
}
實(shí)現(xiàn)的效果為:

3. 利用fit-content實(shí)現(xiàn)元素居中
該方法需要將box塊設(shè)置為浮動(dòng)布局(float),并將其父元素的寬度設(shè)定為自適應(yīng)(width:fit-content),再結(jié)合方法一即可實(shí)現(xiàn)效果。
仍以上述三個(gè)box為例,CSS部分具體代碼為:
div {
background: grey;
color: white;
text-align: center;
width: 200px;
height: 200px;
margin: 10px;
float: left;
}
body {
width: fit-content;
margin-left: auto;
margin-right: auto;
}
實(shí)現(xiàn)的效果為:

4. 利用float+relative實(shí)現(xiàn)元素水平居中
這種方式分為兩步:
- 將需要居中的塊級(jí)元素設(shè)置為
float布局,采用相對(duì)定位方式(position:relative),并相對(duì)現(xiàn)在的位置向右(或向左)移動(dòng)50%; - 將需要居中的塊級(jí)元素的父元素設(shè)置為
float布局,采用相對(duì)定位方式(position:relative),并相對(duì)現(xiàn)在的位置向左(即其子元素移動(dòng)的反方向)移動(dòng)50%。
仍以上述三個(gè)box為例,CSS部分具體代碼為:
div {
height: 200px;
width: 200px;
background: grey;
color: white;
text-align: center;
margin: 10px;
float: left;
position: relative;
right: 50%;
}
body {
float: left;
position: relative;
left: 50%; /*一定要與子元素移動(dòng)方向相反*/
}
實(shí)現(xiàn)的效果為:

5. 利用float+absolute實(shí)現(xiàn)元素居中
這種方式也分兩步實(shí)現(xiàn):
第一步與方法四(float+relative)相同;
第二步中,需要居中的塊級(jí)元素的父元素應(yīng)采用絕對(duì)定位方式(
position:absolute)、向其子元素移動(dòng)的反方向移動(dòng)50%,并將文本對(duì)齊方式設(shè)置為居中(text-align: center)。
以上述三個(gè)box為例,CSS部分具體代碼為:
div {
height: 200px;
width: 200px;
background: grey;
color: white;
text-align: center;
margin: 10px;
float: left;
position: relative;
right: 50%;
}
body {
position: absolute; /*這里與方法四不同*/
left: 50%; /*一定要與子元素移動(dòng)方向相反*/
}
實(shí)現(xiàn)的效果為:

6. 利用flex實(shí)現(xiàn)元素居中
對(duì)于需要所有元素均在一排并且居中的情況,flex非常好用。只用將需要居中的塊級(jí)元素的父元素的display屬性設(shè)置為flex,justify-content屬性設(shè)置為center即可。
以上述三個(gè)box為例,CSS部分具體代碼為:
div {
background: grey;
color: white;
text-align: center;
width: 200px;
height: 200px;
margin: 10px;
}
body {
display: flex;
justify-content:center;
}
實(shí)現(xiàn)的效果為:

7. 使用偽元素模擬float:center效果
最后一種方法比較復(fù)雜但是可以實(shí)現(xiàn)文字環(huán)繞圖片的效果(對(duì)于分欄排版的段落很有效)。
(實(shí)際上對(duì)于單欄文字環(huán)繞圖片的效果通過設(shè)置圖片的float屬性即可實(shí)現(xiàn),因此思考一下也很容易將這種方法拓展到多欄文字上)
目前CSS中沒有float:center這種效果,但是可以利用偽元素進(jìn)行模擬。該方法分為兩步:
- 使用偽元素
:before分別在多欄文字上用空內(nèi)容占位,并通過設(shè)置不同的float方向使段落的文字重新布局,產(chǎn)生環(huán)繞的效果。(注意:占位符的大小不能小于所插入圖片的大小。) - 采用絕對(duì)定位將需要插入的圖片移動(dòng)到占位符處。
舉一個(gè)例子看具體實(shí)現(xiàn)。
HTML部分代碼為:
<body>
<div id="leftText">
<p>
第一欄...(此處省略內(nèi)容)
</p>
</div>
<div id="rightText">
<p>
第二欄...(此處省略內(nèi)容)
</p>
</div>
<div>
<img src=".\我是一張圖片(大小為:160*160px).png">
</div>
</body>
CSS部分代碼為:
#leftText {
float: left;
width: 40%;
margin-left: 120px;
}
#rightText {
float: right;
width: 40%;
margin-right: 120px;
}
/*兩欄內(nèi)容需要兩個(gè)占位符,以使圖片位于兩欄內(nèi)容中間*/
#leftText:before, #rightText:before {
content: ""; /*以空內(nèi)容占位*/
width: 102px; /*寬度大于圖片寬度的一半*/
height: 180px; /*高度大于圖片高度*/
}
#leftText:before {
float: right; /*第一欄占位符右浮動(dòng)*/
}
#rightText:before {
float: left; /*第一欄占位符左浮動(dòng)*/
}
img {
position: absolute; /*用絕對(duì)定位的方式調(diào)整圖片的位置*/
top: 30px;
left: 44%;
transform: -50%;
}
實(shí)現(xiàn)的效果為:

這種方法雖然步驟略復(fù)雜,但是效果還是蠻好的。
回到最初的問題
那對(duì)于開頭的作業(yè)比較好的實(shí)現(xiàn)方式是什么呢?
對(duì)于這道題,我目前覺得最好的方式是inline-block。
可以看一下具體實(shí)現(xiàn)。
HTML部分代碼為:
<body>
<div id="box123">
<div id="box1">
<p>box1</p>
</div>
<div id="box2">
<p>box2</p>
</div>
<div id="box3">
<p>box3</p>
</div>
</div>
<div id="box4">
<p>box4</p>
</div>
</body>
CSS部分代碼為:
#box1, #box2, #box3 {
height: 200px;
width: 200px;
background: gray;
color: white;
display: inline-block;
}
#box4 {
height: 200px;
width: 200px;
background: gray;
color: white;
display: inline-block;
margin-top: 5px;
}
body {
text-align: center;
}
實(shí)現(xiàn)的效果為:

參考文章: