Centering in CSS: A Complete Guidecss
BY CHRIS COYIER ON SEPTEMBER 2, 2014html
附:文中涉及到了flex的一些用法,若是沒有接觸過flex佈局,建議看一下阮一峯老師的這篇指南:Flex 佈局教程:語法篇git
博客文章地址:https://guitong.github.io/blo... 顯示效果更佳。github
CSS居中是常被開發者抱怨的問題之一。Why dose it have to be so hard?? They jeer. 我認爲問題不在於它實現起來有多難,而是有太多可以實現它的方法。在不一樣的情景下,如何去選擇,纔是真正困惑咱們的地方。瀏覽器
因此如今,讓咱們來作一個決策樹,使CSS居中問題更容易解決。ide
它是行內或類行內元素嗎?(好比文本和連接)佈局
你能夠將行內元素置於塊級父元素內,而後用下面的CSS代碼來使其水平居中:flex
.center-children { text-align: center; }
https://codepen.io/chriscoyie...ui
這種方法適用於inline,inline-block,inline-table,inline-flex等類型的元素。flexbox
它是一個塊級元素嗎?
爲了居中一個塊級元素,你能夠設置它的margin-left
和margin-right
值爲auto
(它的width
值已給定,不然將佔滿容器,也就不須要居中了)。一般簡寫以下:
.center-me { margin: 0 auto; }
https://codepen.io/chriscoyie...
不管咱們將要居中的塊級元素或父元素的寬度如何,這都將起做用。
注意你不能將浮動元素居中。There is a trick though.
有多個塊級元素嗎?
若是你須要將多個塊級元素水平居中於單行,一個好的辦法是改變它們的dispaly
類型。這裏有兩個例子,分別使用了inline-block
和 flexbox 方法實現:
https://codepen.io/chriscoyie...
除非你是想讓它們堆疊在一塊兒,那麼剛纔使用的設置自動外邊距值將仍然有效。
https://codepen.io/chriscoyie...
垂直居中在CSS中比較棘手。
它是行內或類行內元素嗎?
是單行嗎?
有時行內/文本元素能垂直居中顯示,僅僅是由於它們有相等的上下padding
值。
.link { padding-top: 30px; padding-bottom: 30px; }
https://codepen.io/chriscoyie...
若是因爲某些緣由,設置padding的方法並不可選,而你須要居中已知不會換行的文本,有一個技巧是使其line-height
值與其height
值相等。
.center-text-trick { height: 100px; line-height: 100px; white-space: nowrap; }
https://codepen.io/chriscoyie...
是多行嗎?
對於多行文本的狀況,依然可使用上下padding相等的方法使其垂直居中,可是若是這種方法失效了,可能文本所在的元素是一個table cell,不論是經過字面量定義的仍是經過CSS定義的。(紅葉注:這裏的意思就是該元素能夠是直接使用<td>
表格標籤聲明,也能夠是爲元素設置display:table-cell;
屬性而使其成爲一個table cell,父元素設置display:table; )。若是是文本在<td>
這樣的元素內,該元素默認有CSS屬性vertical-align:middle;
,因此不須要咱們顯示地設置。然而,若是你是手動更改CSS使其成爲table cell元素的,就須要顯示地加入這個屬性vertical-align:middle;
。
下面的例子很是清晰地展現了這種方法:
https://codepen.io/chriscoyie...
若是你不喜歡或者這種方法也很差使,也許你能夠用flexbox?單個子flex元素能夠很是輕鬆地在父flex元素內垂直居中。
.flex-center-vertically { display: flex; justify-content: center; flex-direction: column; height: 400px; }
https://codepen.io/chriscoyie...
可是要記住,上面的討論都是基於元素父容器有一個固定的高度(px,%,etc)。
若是這些方法都沒法實現,你能夠採用「ghost element」技術,將一個全高度的僞元素將放置於容器中,文本將與其垂直對齊。
.ghost-center { position: relative; } .ghost-center::before { content: " "; display: inline-block; height: 100%; width: 1%; vertical-align: middle; } .ghost-center p { display: inline-block; vertical-align: middle; }
https://codepen.io/chriscoyie...
它是一個塊級元素嗎?
知道元素的高度嗎?
不知道網頁佈局的高度是至關常見的,有不少緣由:若是文本的寬度改變,那麼重佈局時高度就會改變;文本樣式的改變會改變高度;文本數量改變會改變高度;具備固定縱橫比的元素(如圖像),會在尺寸改變時影響高度。Etc。
可是若是你明確地知道高度,能夠像這樣使其垂直居中:
.parent { position: relative; } .child { position: absolute; top: 50%; height: 100px; margin-top: -50px;/* account for padding and border if not using box-sizing: border-box; */ }
https://codepen.io/chriscoyie...
未知元素高度?
不要緊。你仍然可使用相似上面的方法使其居中。先將其絕對定位至父元素半高位置,再提高自身半高距離便可。
.parent { position: relative; } .child { position: absolute; top: 50%; transform: translateY(-50%); }
https://codepen.io/chriscoyie...
~~> Can you use flexbox?
你可使用flexbox嗎?
若是能夠,那就至關簡單了。
.parent { display: flex; flex-direction: column; justify-content: center; }
https://codepen.io/chriscoyie...
你能夠將前面的方法任意組合起來,實現完美的居中效果。可是我發現一般能夠將其分爲三類:
元素有固定的寬度和高度嗎?
先將元素絕對定位至50%/50%位置,而後加入負margin值,使該值等於高度和寬度的一半(注:元素若是有padding要記得計算進去,參考下例)。這樣就可使元素水平且垂直居中,並具備良好的瀏覽器兼容性。
.parent { position: relative; } .child { width: 300px; height: 100px; padding: 20px; position: absolute; top: 50%; left: 50%; margin: -70px 0 0 -170px; }
https://codepen.io/chriscoyie...
元素的寬度與高度未知?
若是你不知道該元素的寬高,能夠將它的transform
屬性設置爲translate(-50%, -50%)
。也能夠達到相同的效果。
.parent { position: relative; } .child { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
https://codepen.io/chriscoyie...
你可使用flexbox嗎?
在水平和垂直兩個方向上居中元素,你須要用到flex的兩個屬性:
.parent { display: flex; justify-content: center; align-items: center; }
https://codepen.io/chriscoyie...
這是一個小技巧,對單個元素來講很是有效:
body, html { height: 100%; display: grid; } span { /* thing to center */ margin: auto; }
https://codepen.io/chriscoyie...
You can totally center things in CSS !!!