css居中的10種寫法(面試必考
github原文:https://github.com/yanhaijing/vertical-center
部落格原文:https://yanhaijing.com/css/2018/01/17/horizontal-vertical-center/
css居中作為Web前端中無可避免的話題,在面試中也是常常出現,可以說是面試必考。
以下是從掘金中一篇文章看到的10種居中方法,可以給大家作為參考
(當然一個沒什麼人氣的部落格只是寫給自己看的哈哈哈 不過說不定能被搜到呢
目錄:
僅居中元素定寬高適用
- absolute + 負margin
- absolute + margin auto
- absolute + calc
居中元素不定寬高
- absolute + transform
- lineheight
- writing-mode
- table
- css-table
- flex
- grid
<!--公共程式碼(特殊排版會按具體情況列出)--> <div class="wp"> <div class="box size">123123</div> </div>
/*公共程式碼*/ .wp { border: 1px solid red; width: 300px; height: 300px; } .box { background: green; } .box.size{ width: 100px; height: 100px; }
absolute + 負margin
絕對定位的百分比是相對於父元素的寬高,通過這個特性可以讓子元素的居中顯示,但絕對定位是基於子元素的左上角,期望的效果是子元素的中心居中顯示。
為了修正這個問題,可以藉助外邊距的負值,負的外邊距可以讓元素向相反方向定位,通過指定子元素的外邊距為子元素寬度一半的負值,就可以讓子元素居中了,css程式碼如下
.wp {
position: relative; } .box { position: absolute; top: 50%; left: 50%; margin-left: -50px; margin-top: -50px; }
這個方法較為簡單,但必須知道父元素的寬高,所以比較繁瑣。
absolute + margin auto
與上一個方法類似,同樣是使用絕對定位。其餘則是對各方向設為0,然後margin設為auto即可。
.wp { position: relative; } .box { position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; }
這個方法也是比較簡單,同時不用知道父元素的寬高,但每次需要設定各個方向為0,不過這個只要設定一個通用佈局就能解決,所以實際上不會太繁瑣。
absolute + calc
這個方法是利用了css3的新特性——計算屬性,這個方法類似absolute+負margin的方法,但這裡不用定父元素的寬高(但要定子元素的),因為用了計算屬性可以用百分比和具體數值來做計算。
這裡的是用上和左方向的50%減去子元素的一半實現。
(順便吐槽一下,之前寫過一個網站沒有發現計算屬性這玩意兒,搞得腦闊疼,現在發現了簡直豁然開朗發現新大陸啊!!!!
.wp {
position: relative; } .box { position: absolute;; top: calc(50% - 50px); left: calc(50% - 50px); }
看起來十分高大上的一種方法!也免去了父元素定寬高的尷尬,寫起來簡潔爆了有木有,但是不能寫成通用佈局,每次都要寫一遍calc也是有點蛋疼。
absolute + transform
哈哈這裡還是絕對佈局,別介。
這個方法也不用定父元素寬高,也不用定子元素的寬高,這也是用了css3的新特性,不過是另外一個新特性——transform,而這裡用的是transfrom的translate屬性。
這裡介紹一下translate屬性,這個屬性可以設定百分比,該屬性是css3的2d轉換屬性。個人感覺如果是直接填具體數值的話,有點像margin屬性,不知道有沒有感覺錯;而如果用百分比的話,這個百分比是相對自身的寬高作的百分比,而非父元素的,這裡和margin就有了區別。裡面的位置引數順序是左、上。
利用自身寬高百分比的原理,我們就容易理解了,top和left設為50%,然後兩個引數都填-50%即可。原理也類似absolute+calc的方法,只不過這裡連子元素的寬高都不用定了。
.wp { position: relative; } .box { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
這個方法完美排除定寬高的缺陷(不管是父還是子的),通用性也強,也可以作為通用佈局使用,可以說通用性槓槓的了!唯一的不足是這種方法相容性依賴translate2d的相容性。
lineheight
這個方法是將子元素設定為行內元素,父元素只要將text-align設為center即可設為水平居中,然後子元素設定vertical-align為middle即可垂直居中。
.wp { line-height: 300px; text-align: center; font-size: 0px; } .box { font-size: 16px; display: inline-block; vertical-align: middle; line-height: initial; text-align: left; /* 修正文字 */ }
這種方法不太友善的地方是需要在子元素中將文字顯示重置為想要的效果。
writing-mode
估計很多人也是一樣,在我看到這篇文章的原博文之前,根本沒見過writing-mode這個屬性,別說是用來幹什麼的了,一頭霧水。
簡單來講,writing-mode這個屬性就是可以將父元素中包含的行內元素的顯示方向和排列方向,即縱向、橫向及從左到右、從右到左,具體詳細可以看看css參考手冊
而這其中最神奇的是,writing-mode不僅僅會影響顯示和排列,甚至會影響到其css的作用方向,如width變成高度,text-align可以從水平居中變成垂直的居中!
值得注意的是,祖父元素的writing-mode會影響到孫元素的排列,因此要在該孫元素的父元素writing-mode屬性。
<div class="wp"> <div class="wp-inner"> <div class="box">123123</div> </div> </div>
.wp { writing-mode: vertical-lr; text-align: center; } .wp-inner { writing-mode: horizontal-tb; display: inline-block; text-align: center; width: 100%; } .box { display: inline-block; margin: auto; text-align: left; }
這種方法較為複雜和繁瑣,我也好不容易才理解了這玩意兒,果真實在是不太適合新手啊,酌情使用吧。
table
曾經table被用來做頁面佈局,現在沒人這麼做了,但table也能夠實現水平垂直居中,但是會增加很多冗餘程式碼。
<table> <tbody> <tr> <td class="wp"> <div class="box">123123</div> </td> </tr> </tbody> </table>
.wp { text-align: center; } .box { display: inline-block; }
這個方法雖然理解起來簡單,但就是太麻煩而且太冗餘,看起來都蛋疼,而且不算是table的正常用法,實在不太推薦。
css-table
css-table是css中display的的新特性,可以讓我們把普通元素,變為table元素的現實效果,通過這個特性也可以實現水平垂直居中。
.wp { display: table-cell; text-align: center; vertical-align: middle; } .box { display: inline-block; }
這個方法和table的原理一樣,相容性也ok,最重要的是沒那麼冗餘,相比起table的方法,更推薦這種。
flex
flex作為現代佈局方案,顛覆了過去的經驗,實現居中也僅需給父元素新增短短几行程式碼,十分的高大上。
.wp { display: flex; justify-content: center; align-items: center; }
目前移動端已經相容flex佈局,高階大氣上檔次,推薦。
grid
css中display的新特性,grid柵格化佈局,實現起來也是十分簡易,理解起來也不難。
.wp { display: grid; } .box { align-self: center; justify-self: center; }
這個方法使用的grid佈局雖然也實現了居中,但是對於相容性方面來講就不太ok了,比不了flex佈局,所以還是推薦flex的方法多一點,不推薦這個。
總結
下面對比下各個方式的優缺點,肯定又雙叒叕該有同學說回字的寫法了,簡單總結下
- PC端有相容性要求,寬高固定,推薦absolute + 負margin
- PC端有相容要求,寬高不固定,推薦css-table
- PC端無相容性要求,推薦flex
- 移動端推薦使用flex
小貼士:關於flex的相容性決方案,請看這裡《移動端flex佈局實戰》
方法 | 居中元素定寬高固定 | PC相容性 | 移動端相容性 |
---|---|---|---|
absolute + 負margin | 是 | ie6+, chrome4+, firefox2+ | 安卓2.3+, iOS6+ |
absolute + margin auto | 是 | ie6+, chrome4+, firefox2+ | 安卓2.3+, iOS6+ |
absolute + calc | 是 | ie9+, chrome19+, firefox4+ | 安卓4.4+, iOS6+ |
absolute + transform | 否 | ie9+, chrome4+, firefox3.5+ | 安卓3+, iOS6+ |
writing-mode | 否 | ie6+, chrome4+, firefox3.5+ | 安卓2.3+, iOS5.1+ |
lineheight | 否 | ie6+, chrome4+, firefox2+ | 安卓2.3+, iOS6+ |
table | 否 | ie6+, chrome4+, firefox2+ | 安卓2.3+, iOS6+ |
css-table | 否 | ie8+, chrome4+, firefox2+ | 安卓2.3+, iOS6+ |
flex | 否 | ie10+, chrome4+, firefox2+ | 安卓2.3+, iOS6+ |
grid | 否 | ie10+, chrome57+, firefox52+ | 安卓6+, iOS10.3+ |
另出個小題目:
<div class="red blue">123</div> <div class="blue red">123</div>
.red { color: red } .blue { color: blue }
例項答案點這裡
答錯的童鞋請自動去補一補css基礎知識。
問兩個div的顏色分別是什麼,竟然只有40%的同學能夠答對,這40%中還有很多同學不知道為什麼,希望這些同學好好補習下CSS基礎,下面給大家推薦幾本CSS的書籍:
喜歡看網路資料同學,可以看看MDN的這個CSS入門教程,強烈推薦,英語好的同學建議看英文版。
不說了,其實cv了大半篇,這小題目我都答錯了(捂臉,我要去補一補css基礎知識了!!!!