你知道CSS實現水平垂直居中的第10種方式嗎?

2021-02-14 前端之巔

本文已獲作者授權,轉載來源:

https://segmentfault.com/a/1190000016389031

劃重點,這是一道面試必考題,很多面試官都喜歡問這個問題,我就被問過好幾次了。

要實現上圖的效果看似很簡單,實則暗藏玄機,本文總結了一下 CSS 實現水平垂直居中的方式大概有下面這些,本文將逐一介紹一下,我將本文整理成了一個 github 倉庫在:https://github.com/yanhaijing/vertical-center

 歡迎大家 star。

僅居中元素定寬高適用:

absolute + 負 margin

absolute + margin auto

absolute + calc

居中元素不定寬高:

absolute + transform

lineheight

writing-mode

table

css-table

flex

grid

為了實現上面的效果先來做些準備工作,假設 HTML 代碼如下,總共兩個元素,父元素和子元素:

<div>    <div>123123</div></div>

wp 是父元素的類名,box 是子元素的類名,因為有定寬和不定寬的區別,size 用來表示指定寬度,下面是所有效果都要用到的公共代碼,主要是設置顏色和寬高。

注意:後面不在重複這段公共代碼,只會給出相應提示。

/* 公共代碼 */.wp {    border: 1px solid red;    width: 300px;    height: 300px;}.box {    background: green;    }.box.size{    width: 100px;    height: 100px;}/* 公共代碼 */

絕對定位的百分比是相對於父元素的寬高,通過這個特性可以讓子元素的居中顯示,但絕對定位是基於子元素的左上角,期望的效果是子元素的中心居中顯示。

為了修正這個問題,可以藉助外邊距的負值,負的外邊距可以讓元素向相反方向定位,通過指定子元素的外邊距為子元素寬度一半的負值,就可以讓子元素居中了,css 代碼如下。

/* 此處引用上面的公共代碼 *//* 此處引用上面的公共代碼 *//* 定位代碼 */.wp {    position: relative;}.box {    position: absolute;;    top: 50%;    left: 50%;    margin-left: -50px;    margin-top: -50px;}

這是我比較常用的方式,這種方式比較好理解,兼容性也很好,缺點是需要知道子元素的寬高。

點擊查看完整 DEMO:

http://yanhaijing.com/vertical-center/absolute1.html

這種方式也要求居中元素的寬高必須固定,HTML 代碼如下:

<div>    <div>123123</div></div>

這種方式通過設置各個方向的距離都是 0,此時再講 margin 設為 auto,就可以在各個方向上居中了。

/* 此處引用上面的公共代碼 *//* 此處引用上面的公共代碼 *//* 定位代碼 */.wp {    position: relative;}.box {    position: absolute;;    top: 0;    left: 0;    right: 0;    bottom: 0;    margin: auto;}

這種方法兼容性也很好,缺點是需要知道子元素的寬高。

點擊查看完整 DEMO:

http://yanhaijing.com/vertical-center/absolute2.html

這種方式也要求居中元素的寬高必須固定,所以我們為 box 增加 size 類,HTML 代碼如下:

<div>    <div>123123</div></div>

感謝 css3 帶來了計算屬性,既然 top 的百分比是基於元素的左上角,那麼在減去寬度的一半就好了,代碼如下

/* 此處引用上面的公共代碼 *//* 此處引用上面的公共代碼 *//* 定位代碼 */.wp {    position: relative;}.box {    position: absolute;;    top: calc(50% - 50px);    left: calc(50% - 50px);}

這種方法兼容性依賴 calc 的兼容性,缺點是需要知道子元素的寬高。

點擊查看完整 DEMO:

http://yanhaijing.com/vertical-center/absolute3.html

還是絕對定位,但這個方法不需要子元素固定寬高,所以不再需要 size 類了,HTML 代碼如下:

<div>    <div>123123</div></div>

修復絕對定位的問題,還可以使用 css3 新增的 transform,transform 的 translate 屬性也可以設置百分比,其是相對於自身的寬和高,所以可以講 translate 設置為 -50%,就可以做到居中了,代碼如下:

/* 此處引用上面的公共代碼 *//* 此處引用上面的公共代碼 *//* 定位代碼 */.wp {    position: relative;}.box {    position: absolute;    top: 50%;    left: 50%;    transform: translate(-50%, -50%);}

這種方法兼容性依賴 translate2d 的兼容性。

點擊查看完整 DEMO:

http://yanhaijing.com/vertical-center/absolute4.html

利用行內元素居中屬性也可以做到水平垂直居中,HTML 代碼如下:

<div>    <div>123123</div></div>

把 box 設置為行內元素,通過 text-align 就可以做到水平居中,但很多同學可能不知道通過通過 vertical-align 也可以在垂直方向做到居中,代碼如下:

/* 此處引用上面的公共代碼 *//* 此處引用上面的公共代碼 *//* 定位代碼 */.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; /* 修正文字 */}

這種方法需要在子元素中將文字顯示重置為想要的效果。

點擊查看完整 DEMO:

http://yanhaijing.com/vertical-center/lineheight.html

很多同學一定和我一樣不知道 writing-mode 屬性,感謝 @張鑫旭老師的反饋,簡單來說 writing-mode 可以改變文字的顯示方向,比如可以通過 writing-mode 讓文字的顯示變為垂直方向。

<div>水平方向</div><div>垂直方向</div>

.div2 {    writing-mode: vertical-lr;}

顯示效果如下:

水平方向垂直方向

更神奇的是所有水平方向上的 css 屬性,都會變為垂直方向上的屬性,比如 text-align,通過 writing-mode 和 text-align 就可以做到水平和垂直方向的居中了,只不過要稍微麻煩一點:

<div>    <div>        <div>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;}

這種方法實現起來和理解起來都稍微有些複雜。

點擊查看完整 DEMO:

http://yanhaijing.com/vertical-center/writing-mode.html

曾經 table 被用來做頁面布局,現在沒人這麼做了,但 table 也能夠實現水平垂直居中,但是會增加很多冗餘代碼:

<table>    <tbody>        <tr>            <td>                <div>123123</div>            </td>        </tr>    </tbody></table>

tabel 單元格中的內容天然就是垂直居中的,只要添加一個水平居中屬性就好了。

.wp {    text-align: center;}.box {    display: inline-block;}

這種方法就是代碼太冗餘,而且也不是 table 的正確用法。

點擊查看完整 DEMO:

http://yanhaijing.com/vertical-center/table.html

css 新增的 table 屬性,可以讓我們把普通元素,變為 table 元素的現實效果,通過這個特性也可以實現水平垂直居中。

<div>    <div>123123</div></div>

下面通過 css 屬性,可以讓 div 顯示的和 table 一樣:

.wp {    display: table-cell;    text-align: center;    vertical-align: middle;}.box {    display: inline-block;}

這種方法和 table 一樣的原理,但卻沒有那麼多冗餘代碼,兼容性也還不錯。

點擊查看完整 DEMO:

http://yanhaijing.com/vertical-center/css-table.html

flex 作為現代的布局方案,顛覆了過去的經驗,只需幾行代碼就可以優雅的做到水平垂直居中。

<div>    <div>123123</div></div>

.wp {    display: flex;    justify-content: center;    align-items: center;}

目前在移動端已經完全可以使用 flex 了,PC 端需要看自己業務的兼容性情況。

點擊查看完整 DEMO:

http://yanhaijing.com/vertical-center/flex.html

感謝 @一絲姐 反饋的這個方案,css 新出的網格布局,由於兼容性不太好,一直沒太關注,通過 grid 也可以實現水平垂直居中。

<div>    <div>123123</div></div>

.wp {    display: grid;}.box {    align-self: center;    justify-self: center;}

代碼量也很少,但兼容性不如 flex,不推薦使用。

點擊查看完整 DEMO:

http://yanhaijing.com/vertical-center/grid.html

下面對比下各個方式的優缺點,肯定又雙叒叕該有同學說回字的寫法了,簡單總結下:

小貼士:關於 flex 的兼容性決方案,請看這裡:

https://yanhaijing.com/css/2016/08/21/flex-practice-on-mobile/

最近發現很多同學都對 css 不夠重視,這其實是不正確的,比如下面的這麼簡單的問題都有那麼多同學不會,我也是很無語:

<div>123</div><div>123</div>

.red {    color: red}.blue {    color: blue}

問兩個 div 的顏色分別是什麼,竟然只有 40% 的同學能夠答對,這 40% 中還有很多同學不知道為什麼,希望這些同學好好補習下 CSS 基礎。

今年12 月 7-8 日在北京國際會議中心舉辦的 ArchSummit 全球架構師技術峰會邀請了超過百位的國內外專業講師,並設置了前端技術專題,分享他們的最新黑科技和研發經驗。

目前大會 8 折優惠購票火熱進行中,掃描以下圖片二維碼或點擊「閱讀原文」了解更多詳情!

如有疑問歡迎諮詢票務經理灰灰:17326843116(微信同號)

相關焦點

  • CSS實現水平垂直居中的10種方式
    ,實則暗藏玄機,本文總結了一下CSS實現水平垂直居中的方式大概有下面這些,本文將逐一介紹一下,我將本文整理成了一個github倉庫,歡迎大家star僅居中元素定寬高適用absolute + 負marginabsolute + margin autoabsolute + calc居中元素不定寬高absolute + transform
  • css 垂直居中的幾種實現方式
    前言設計是帶有主觀色彩的,同樣網頁設計中的 css 一樣讓人摸不頭腦。網上列舉的實現方式一大把,或許在這裡你都看到過,但既然來到這裡我希望這篇能讓你看有所收穫,畢竟這也是前端面試的基礎。實現方式備註:如下頁面效果中的灰色方框高度都做了限定為 100 px(即父元素)1、line-height 方式line-height 設置行高,多用於控制多行文本之間的間隔大小。但利用它的特性也可以控制垂直居中。
  • CSS實現水平垂直居中的1010種方式(史上最全)
    要實現上圖的效果看似很簡單,實則暗藏玄機,本文總結了一下CSS實現水平垂直居中的方式大概有下面這些,本文將逐一介紹一下,我將本文整理成了一個github倉庫,歡迎大家star。>更神奇的是所有水平方向上的css屬性,都會變為垂直方向上的屬性,比如text-align,通過writing-mode和text-align就可以做到水平和垂直方向的居中了,只不過要稍微麻煩一點<div class=
  • HTML技巧篇:實現元素水平與垂直居中的幾種方式
    本篇文章主要給大家介紹一下如何使用html+css實現元素的水平與垂直居中效果,這也是我們網頁在編碼製作中會經常用到的問題。1)單行文本的居中主要實現css代碼:水平居中:text-align:center;垂直居中:line-height:XXpx; /*line-height與元素的height的值一致*/我們先來看這樣一個例子,加入我們這裡有一個
  • css 水平居中的幾種實現方式
    前言設計是帶有主觀色彩的,同樣網頁設計中的 css 一樣讓人摸不頭腦。網上列舉的實現方式一大把,或許在這裡你都看到過,但既然來到這裡我希望這篇能讓你看有所收穫,畢竟這也是前端面試的基礎。代碼舉例頁面效果2、定寬 margin auto 方式這也是常見的水平居中方式,通過設置子元素的 margin 屬性來控制距離父元素的距離。
  • CSS 垂直水平完全居中手冊
    為什麼實現起來這麼辛苦?所以有人被嘲笑。我覺得問題不是沒有辦法做到,只是視情況而定,有很多不同方式,但是很難弄清楚應該用何種方式。因此我寫了這篇文章,希望能把他變得容易點。水平居中內聯元素(inline or inline-*)居中?
  • 前端面試:CSS 如何實現水平居中和垂直居中
    行內元素的水平居中如果該元素是行內元素,只需設置 text-align: center; 即可實現水平居中。如圖,我們看到文本在 <textarea> 元素中實現了水平居中。,然後設置 margin-left: 負值 將元素左移自身寬度一半距離即可實現水平居中。
  • 23種CSS的垂直居中技巧,你都學會了嗎?
    ,而其困難度也始終沒有讓人輕鬆過,據說部分公司甚至將CSS的垂直居中技巧當成面試題,其重要性可見一斑,經過了Amos通靈了一下之後把垂直居中的寫法擴展到了23種,今天就帶著大家輕鬆的了解一下CSS的垂直居中的方式。
  • CSS實例:水平居中和垂直居中的多種解決方案
    在定義網頁的CSS樣式的時候,我們或許並不怎麼用到垂直居中。在站長書庫(book.chinaz.com)中,大量的文章介紹了這些知識。在和別人合作的時候,你的代碼的自適應性就需要做到最大程度的好。
  • CSS垂直居中、水平居中
    如果你有新的方法,歡迎補充!👏👏👏我們先從固定寬高的div開始為方便演示,默認寬高各為100px的div<div class="wrapper"> <div class="content"></div></div>以下方式全部是水平及垂直居中
  • 對CSS居中的一點總結
    居中的技巧有很多,但在編寫代碼的過程中,發現有時候技巧管用,有時候不管用,於是就將每個知道的方案都試一遍,找到合適的。這種情況究其原因是對居中的認識不夠深入,只是停留在實現需求的水平上。為了更好的加深對居中的理解,搜集和閱讀相關資料,發現不錯的文章將其整理出來。
  • CSS的23個垂直居中技巧,你都學會了嗎?
    在不斷探索,發現中,CSS的垂直居中的方式竟然能達到23種,大家可以看看自己熟知的是哪幾種?1、Line-height適用情景:單行文字垂直居中技巧這個方式應該是最多人知道的了,常見於單行文字的應用,像是按鈕這一類對象,或者是下拉框、導航此類元素最常見到的方式了。
  • css常見問題:塊級元素和行內元素在水平和垂直方向怎樣居中呢?
    相信大家在寫css樣式的時候會經常遇到這樣一個問題,那就是塊級元素和行內元素在水平和垂直方向怎麼居中呢?又怎麼即在水平方向居中,又在垂直方向居中呢?和垂直方向居中以及即在水平方向居中,又在垂直方向居中的問題。
  • CSS布局奇技淫巧:各種居中
    4、使用表格 如果你使用的是表格的話,那完全不用為各種居中問題而煩惱了,只要用到 td(也可能會用到 th)元素的 align=」center」 以及 valign=」middle」 這兩個屬性就可以完美的處理它裡面內容的水平和垂直居中問題了,而且表格默認的就會對它裡面的內容進行垂直居中。
  • CSS垂直居中技巧,我只會23個,你會幾個?
    1、Line-height適用情景:單行文字垂直居中技巧這個方式應該是最多人知道的了,常見於單行文字的應用,像是按鈕這一類對象,或者是下拉框、導航此類元素最常見到的方式了。此方式的原理是在於將單行文字的行高設定後,文字會位於行高的垂直中間位置,利用此原理就能輕鬆達成垂直居中的需求了。
  • 常見的CSS文字居中顯示
    和vertical-align html<div> <span>測試文字</span></div>cssheight: 200px; overflow: hidden; background: #ccc; text-align: center;}.box span{ vertical-align: middle; line-height: 200px;}2、利用display:table-cell實現水平垂直居中顯示
  • 公司的一個面試題:如何用CSS讓一個容器水平垂直居中?
    2、利用絕對定位 position:absolute 配合margin的auto屬性 來達到居中的效果  我們可以將css修改為 .div1{  width: 100px0; top: 0; right: 0; bottom: 0;}---將div2設置為相對div1的絕對定位,margin設為四邊auto left、top、bottom、right設為0 瀏覽器會對絕對定位的容器margin:auto自動識別,最後得到類似於margin:0 auto的效果;而我們也可以將left、top、bottom、right設為你想要的值
  • CSS居中:完全指南(譯)
    但是我認為這個問題其實並沒有那麼難啦,就是有很多種不同的方式可以達到居中的目的,這取決於不同的情景,很難說用哪一種方式去實現居中。所以就讓我們做一個決策樹,希望能使這個問題簡單一點吧~水平居中行內或者具有行內元素性質的元素(比如文字或者連結)?
  • 10 個 CSS 高頻面試題,你都會嗎?
    n個子元素,第一個編號為1E:nth-last-child(n)匹配其父元素的倒數第n個子元素,第一個編號為1E:nth-of-type(n)與:nth-child()作用類似,但是僅匹配使用同種標籤的元素E:nth-last-of-type(n)與:nth-last-child() 作用類似,但是僅匹配使用同種標籤的元素E:last-child匹配父元素的最後一個子元素
  • DIV+CSS教程_DIV+CSS布局_DIV+CSS實例教程手冊
    7,三列固定寬度8,三列固定寬度居中9,IE6的3像素bug第4天:垂直導航菜單和輔助彈出菜單1,垂直列表>2,標籤的默認樣式3,css派生選擇器4,css選擇器的分組5,垂直二級清單6,相對定位和絕對定位