參考:http://www.html5cn.org/article-9787-1.html
示例代碼:
<!DOCTYPE html>
<html>
<head>
<style>
body {margin: 0;padding: 0;background: #4AC291;font-size: 100% / 1.5 sans-serif;}
main {background: #655;color: white;text-align: center;line-height: 2em;}
</style>
</head>
<body>
<main>這是要居中的元素</main>
</body>
</html>
效果:
方法一:元素具有固定的寬度和高度,添加樣式1
main {
position: absolute;
top: 50%;
left: 50%;
width: 12em;
height: 2em;
margin-top: -1em; /* 2/1 = 1 */
margin-left: -6em; /* 12/2 = 6 */
}
效果:
方法二:藉助強大的 calc() 函數
效果圖:
方法三:利用元素變形屬性,元素寬高不確定的情況下,寬高由元素內容決定
main {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
效果圖:
注意:這個元素已經完美居中了,完全滿足我們的期望。當然沒有任何技巧是十全十美的,上面這個方法也有一些需要注意的地方:
我們有時不能選用絕對定位,因爲它對整個佈局的影響太過強烈。
如果需要居中的元素已經在高度上超過了視口,那麼它的頂部會被視口裁剪掉。有一些辦法可以繞過這個問題,但hack味道過濃。
在某些瀏覽器中,這個方法可能會導致元素的顯示有一些模糊,因爲元素可能被放置在半個像素上。這個問題可以用 transform-style: preserve-3d 來修復,不過這個修復手段也可以認爲是一個hack,而且很難保證它在未來不會出問題。
基於視口單位的解決方案
假設我們不想使用絕對定位,仍然可以採用translate()技巧來把這個元素以其自身寬高的一半爲距離進行移動;但是在缺少left和top的情況下,如何把這個元素的左上角放置的容器的正中心呢?
我們的第一反應很可能是用margin屬性的百分比值來實現,就像這樣:
效果圖:
基於margin屬性百分比值的樣式效果
這段代碼產生的效果十分離譜。原因在於margin的百分比值時以父元素的寬度作爲解析基準的。沒錯,即使對於margin-top和margin-bottom來說也是這樣!
不過幸運的是,如果只是想把元素相對於視口進行居中,仍然是有希望的。CSS值與單位(第三版)定義了一套新的單位,稱爲視口相關的長度單位。
vw 是與視口寬度相關的。與常人的直覺不符的是,1vw 實際上表示視口寬度的 1%,而不是 100%。
與 vw 類似,1vh 表示視口高度的 1%。
當視口寬度小於高度時,1vmin 等於 1vw,否則等於 1vh。
當視口寬度大於高度時,1vmax 等於 1vw,否則等於 1vh。
在我們這個例子中,適用於外邊距的是vh單位:
main {
width: 12em;
margin: 50vh auto 0;
transform: translateY(-50%);
}
效果圖:
基於Flexbox的解決方案
body {
display: flex;
min-height: 100vh;
margin: 0;
}
main {
margin: auto;
}
效果圖:
若限定寬度,高度超過可視區域高度,則會出現滾動欄
代碼:
wibody {
display: flex;
min-height: 100vh;
margin: 0;
}
main {
margin: auto;
width:100px;
}
效果圖:
請注意,當我們使用Flexbox時,margin: auto不僅在水平方向上將元素居中,垂直方向上也是如此。還有一點,我們甚至不需要指定任何寬度(當然,如果需要的話,也是可以指定的):這個居中元素分配到的寬度等於 max-content。
如果瀏覽器不支持Flexbox,頁面渲染結果看起來就跟我們的起點圖是一樣的了(如果設置了寬度的話)。雖然沒有垂直居中效果,但也是完全可以接受的。
Flexbo 的另一個好處在於,它還可以將匿名容器(即沒有被標籤包裹的文本節點)垂直居中。
我們先給這個<main>元素指定一個固定的尺寸,然後藉助Flexbox 規範所引入的align-items和justify-content屬性,我們可以讓它內部的文本也實現居中(我們可以對<body>使用相同的屬性來使<main>元素居中,但margin: auto方法要更加優雅一些,並且同時起到了回退的作用)。
代碼:
body {
display: flex;
min-height: 100vh;
margin: 0;
}
main {
margin: auto;
display: flex;
align-items: center;
justify-content: center;
width: 12em;
height: 8em;
}
效果圖: