居中是很常見的網頁布局,包括水平居中和垂直居中,看起來似乎很簡單,但每次到實際用的時候總會發現“咦,怎么不 work”,到底是哪里出了差錯,明明這樣是可以的啊?
不知道你有沒有這種經歷,反正我是經常有,所以這里整理一下我們平時常見的居中場景以及分別實現水平居中和垂直居中的方法。
常見的居中場景
- 文本居中
- div 中的 div 居中
- button 居中
- 圖片居中
其中垂直居中還包括元素高度固定和不定兩種。
水平居中
水平居中比較簡單,主要實現方法如下。
對于行內元素可以直接設置父元素為
text-align: center;
即可,對于文本居中、button 居中、圖片居中均適用。對于塊級元素或者是
inline-block
的元素可以借助子元素的margin
值來實現,設置子元素為margin: 0 auto;
即可。
如果內層元素有多個的話想要整體居中怎么做呢,做法大致相同。
這種情況下內層元素一般有設置寬度,因為如果是塊級元素的話默認占滿整行,這樣是談不上居中的。
將內層的元素設置為 display: inline-block;
使其居于一行,然后外層元素設置 text-align: center;
,如下圖:
- 若子元素包含
float:left
屬性,為了讓子元素水平居中,則可讓父元素寬度設置為fit-content
,并且配合margin, 作如下設置:
.parent{
width: -moz-fit-content;
width: -webkit-fit-content;
width: fit-content;
margin: 0 auto;
}
fit-content
是 CSS3 中給 width
屬性新加的一個屬性值,它配合 margin
可以輕松實現水平居中, 目前只支持 Chrome 和 Firefox 瀏覽器
- 使用絕對定位方式,以及負值的
margin-left
, 子元素設置如下:
.son{
position: absolute;
width: 固定;
left: 50%;
margin-left: -0.5寬度;
}
- 使用絕對定位方式, 以及
left:0;right:0;margin:0 auto;
子元素設置如下:
.son{
position: absolute;
width: 固定;
left: 0;
right: 0;
margin: 0 auto;
}
這里解釋一下為什么 left
和 right
要設置為 0
定位元素的寬度和水平放置滿足一個等式。
left
+ margin-left
+ border-left-width
+ padding-left
+ width
+ padding-right
+ border-right-width
+ margin-righ
+ right
= 包含塊的寬度
默認情況下,這四個值都是 auto,會相對于其靜態位置放置,所謂靜態位置是指元素在浮動之前所占據的位置。在從左往右讀的語言中,left
會被設置為 auto
,則值為靜態位置左邊界距離包含塊左邊界的像素值,同理 right
會設置為靜態位置右邊界距離包含塊右邊界的像素值,此時剛好
left
+ border-left-width
+ padding-left
+ width
+ padding-right
+ border-right-width
+ right
= 包含塊的寬度
因此左右 margin
自動變為 0,這時我們設置 margin: 0 auto;
不會有任何左右,所以需要將 left
和 right
設置為 0 使得 margin: 0 auto;
生效,從而實現居中。
- 使用 CSS3 中新增的
transform
屬性, 子元素設置如下:
(這種類似于上面提到的利用絕對定位以及負值的margin-left
,同樣是先根據絕對定位偏移 50%,然后往回移動自身寬度的一半達到居中)
.son{
position: absolute;
left: 50%;
transform: translateX(-50%);
}
- 使用
flex
在 Flex 出現之后,居中的實現變得簡單了很多,它幾乎可以解決所有的居中問題,目前主流瀏覽器均已支持 Flex,在某些低版本的 IE 尚不支持。
父元素設置如下:
.parent {
display: flex;
justify-content: center;
}
垂直居中
垂直居中比較狡猾,經常會出現意想不到的問題。
1. 元素高度固定
如果是單行文本,可以設置
line-height
和height
同高使用相對定位,父元素設置
position: relative;
,子元素設置如下:
.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;
來達到居中也是很常見的一種做法,但是在某些情況下,我們會發現加了并沒有起作用,這是因為 vertical-align: middle;
只有在某些情況下才會生效。
vertical-align: middle;
起作用的前提是元素為 inline
水平元素或者 display: table-cell;
元素,包括 span
, img
, span
, input
, button
, td
以及通過 display
屬性使之顯示為 inline
或者 table-cell
的元素。這意味著,默認情況下,vertical-align: middle;
對 div
和 p
元素等無效。
此外,vertical-align: middle;
只有當父元素設置了 line-height
時才會起作用。(line-height
和 height
同高)
vertical-align不可繼承,必須對子元素單獨設置
- 使用
transform
,利用父元素相對定位(position:relative
),子元素設置如下:
.son {
transform: translateY(-50%);
position: absolute;
top: 50%;
}
- 使用 Flex 布局,父元素設置如下:
.parent {
display: flex;
align-items: center;
}
總結
水平居中的方法:
- 文本居中使用
text-align: center;
- 利用元素的
margin
- 元素寬度設置為
fit-content
(IE 不支持) - 使用絕對定位和元素的負
margin
或者left, right, top, bottom
- 使用絕對定位和
transform
- 使用 Flex
垂直居中的方式:
- 文本居中使用
line-height
- 使用相對定位和元素的負
margin
或者left, right, top, bottom
- 使用
vertical-align
(有一定使用環境和前提) - 使用絕對定位和
transform
- 使用 Flex