居中是很常見(jiàn)的網(wǎng)頁(yè)布局顿膨,包括水平居中和垂直居中,看起來(lái)似乎很簡(jiǎn)單恋沃,但每次到實(shí)際用的時(shí)候總會(huì)發(fā)現(xiàn)“咦,怎么不 work”囊咏,到底是哪里出了差錯(cuò),明明這樣是可以的八稹?
不知道你有沒(méi)有這種經(jīng)歷户辞,反正我是經(jīng)常有,所以這里整理一下我們平時(shí)常見(jiàn)的居中場(chǎng)景以及分別實(shí)現(xiàn)水平居中和垂直居中的方法底燎。
常見(jiàn)的居中場(chǎng)景
- 文本居中
- div 中的 div 居中
- button 居中
- 圖片居中
其中垂直居中還包括元素高度固定和不定兩種。
水平居中
水平居中比較簡(jiǎn)單书蚪,主要實(shí)現(xiàn)方法如下。
對(duì)于行內(nèi)元素可以直接設(shè)置父元素為
text-align: center;
即可迅栅,對(duì)于文本居中读存、button 居中、圖片居中均適用让簿。對(duì)于塊級(jí)元素或者是
inline-block
的元素可以借助子元素的margin
值來(lái)實(shí)現(xiàn),設(shè)置子元素為margin: 0 auto;
即可秀睛。
如果內(nèi)層元素有多個(gè)的話想要整體居中怎么做呢,做法大致相同蹂安。
這種情況下內(nèi)層元素一般有設(shè)置寬度,因?yàn)槿绻菈K級(jí)元素的話默認(rèn)占滿整行田盈,這樣是談不上居中的。
將內(nèi)層的元素設(shè)置為 display: inline-block;
使其居于一行允瞧,然后外層元素設(shè)置 text-align: center;
蛮拔,如下圖:
- 若子元素包含
float:left
屬性痹升,為了讓子元素水平居中,則可讓父元素寬度設(shè)置為fit-content
疼蛾,并且配合margin, 作如下設(shè)置:
.parent{
width: -moz-fit-content;
width: -webkit-fit-content;
width: fit-content;
margin: 0 auto;
}
fit-content
是 CSS3 中給 width
屬性新加的一個(gè)屬性值,它配合 margin
可以輕松實(shí)現(xiàn)水平居中, 目前只支持 Chrome 和 Firefox 瀏覽器
- 使用絕對(duì)定位方式,以及負(fù)值的
margin-left
, 子元素設(shè)置如下:
.son{
position: absolute;
width: 固定;
left: 50%;
margin-left: -0.5寬度;
}
- 使用絕對(duì)定位方式, 以及
left:0;right:0;margin:0 auto;
子元素設(shè)置如下:
.son{
position: absolute;
width: 固定;
left: 0;
right: 0;
margin: 0 auto;
}
這里解釋一下為什么 left
和 right
要設(shè)置為 0
定位元素的寬度和水平放置滿足一個(gè)等式据过。
left
+ margin-left
+ border-left-width
+ padding-left
+ width
+ padding-right
+ border-right-width
+ margin-righ
+ right
= 包含塊的寬度
默認(rèn)情況下,這四個(gè)值都是 auto绳锅,會(huì)相對(duì)于其靜態(tài)位置放置,所謂靜態(tài)位置是指元素在浮動(dòng)之前所占據(jù)的位置鳞芙。在從左往右讀的語(yǔ)言中,left
會(huì)被設(shè)置為 auto
原朝,則值為靜態(tài)位置左邊界距離包含塊左邊界的像素值,同理 right
會(huì)設(shè)置為靜態(tài)位置右邊界距離包含塊右邊界的像素值喳坠,此時(shí)剛好
left
+ border-left-width
+ padding-left
+ width
+ padding-right
+ border-right-width
+ right
= 包含塊的寬度
因此左右 margin
自動(dòng)變?yōu)?0,這時(shí)我們?cè)O(shè)置 margin: 0 auto;
不會(huì)有任何左右壕鹉,所以需要將 left
和 right
設(shè)置為 0 使得 margin: 0 auto;
生效,從而實(shí)現(xiàn)居中晾浴。
- 使用 CSS3 中新增的
transform
屬性, 子元素設(shè)置如下:
(這種類似于上面提到的利用絕對(duì)定位以及負(fù)值的margin-left
负乡,同樣是先根據(jù)絕對(duì)定位偏移 50%抖棘,然后往回移動(dòng)自身寬度的一半達(dá)到居中)
.son{
position: absolute;
left: 50%;
transform: translateX(-50%);
}
- 使用
flex
在 Flex 出現(xiàn)之后,居中的實(shí)現(xiàn)變得簡(jiǎn)單了很多狸涌,它幾乎可以解決所有的居中問(wèn)題,目前主流瀏覽器均已支持 Flex杈抢,在某些低版本的 IE 尚不支持。
父元素設(shè)置如下:
.parent {
display: flex;
justify-content: center;
}
垂直居中
垂直居中比較狡猾惶楼,經(jīng)常會(huì)出現(xiàn)意想不到的問(wèn)題诊杆。
1. 元素高度固定
如果是單行文本何陆,可以設(shè)置
line-height
和height
同高使用相對(duì)定位,父元素設(shè)置
position: relative;
贷盲,子元素設(shè)置如下:
.son{
position:absolute;
top:50%;
height:固定;
margin-top:-0.5高度;
}
or
.son{
position:absolute;
height:固定;
top:0;
bottom:0;
margin:auto 0;
}
2. 元素高度不固定
- 使用
vertical-align: middle;
使用 vertical-align: middle;
來(lái)達(dá)到居中也是很常見(jiàn)的一種做法,但是在某些情況下巩剖,我們會(huì)發(fā)現(xiàn)加了并沒(méi)有起作用,這是因?yàn)?vertical-align: middle;
只有在某些情況下才會(huì)生效佳魔。
vertical-align: middle;
起作用的前提是元素為 inline
水平元素或者 display: table-cell;
元素曙聂,包括 span
鞠鲜, img
, span
贤姆, input
, button
霞捡, td
以及通過(guò) display
屬性使之顯示為 inline
或者 table-cell
的元素。這意味著碧信,默認(rèn)情況下,vertical-align: middle;
對(duì) div
和 p
元素等無(wú)效音婶。
此外,vertical-align: middle;
只有當(dāng)父元素設(shè)置了 line-height
時(shí)才會(huì)起作用衣式。(line-height
和 height
同高)
vertical-align不可繼承,必須對(duì)子元素單獨(dú)設(shè)置
- 使用
transform
碴卧,利用父元素相對(duì)定位(position:relative
),子元素設(shè)置如下:
.son {
transform: translateY(-50%);
position: absolute;
top: 50%;
}
- 使用 Flex 布局住册,父元素設(shè)置如下:
.parent {
display: flex;
align-items: center;
}
總結(jié)
水平居中的方法:
- 文本居中使用
text-align: center;
- 利用元素的
margin
- 元素寬度設(shè)置為
fit-content
(IE 不支持) - 使用絕對(duì)定位和元素的負(fù)
margin
或者left, right, top, bottom
- 使用絕對(duì)定位和
transform
- 使用 Flex
垂直居中的方式:
- 文本居中使用
line-height
- 使用相對(duì)定位和元素的負(fù)
margin
或者left, right, top, bottom
- 使用
vertical-align
(有一定使用環(huán)境和前提) - 使用絕對(duì)定位和
transform
- 使用 Flex