告別搜一次忘一次的過去,徹底總結(jié)五個(gè)垂直居中的方法.

作為一個(gè)切圖的頁面仔,工作中總是要用到垂直居中.忙的時(shí)候一般就隨便google一個(gè)復(fù)制粘貼上去,也從來沒有思考過內(nèi)在的聯(lián)系與原因,但是今天晚上聽聽音樂想看看書的時(shí)候,突然心血來潮.擇日不如撞日,就今天吧,夯實(shí)一下我的基礎(chǔ),從此讓所有垂直居中都變成紙老虎!!!

那么,先談?wù)労?jiǎn)單的垂直居中吧.

在CSS中想要實(shí)現(xiàn)水平居中可以說是十分簡(jiǎn)單了,行內(nèi)元素用text-align:center,塊級(jí)元素用margin:auto,元素就會(huì)乖乖的自己跑到元素水平中間去.

但是這么多年下來,垂直居中已經(jīng)成為了CSS領(lǐng)域的圣杯.

可以說,一個(gè)不能解決這個(gè)問題的人簡(jiǎn)直是寸步難行.不管你想做一個(gè)怎樣的網(wǎng)頁,垂直居中都有很大的可能性會(huì)用到.但是,它并不簡(jiǎn)單,甚至可以說難于登天.

為了解決這個(gè)絕世難題,前端開發(fā)者們從各個(gè)方面想出了各種不同的點(diǎn)子.之前也許你在百度的某個(gè)角落里找到過一些碎片,今天我嘗試將這些碎片組裝起來,還原一個(gè)真正的垂直居中,也將自己的基礎(chǔ)進(jìn)行一次夯實(shí).

1.表格布局法.

第一個(gè)想到表格布局法的人已經(jīng)無法考證,但是不得不說這真的是一個(gè)Excited的做法.

 <body>    
<div class="Center-Container is-Table">  
<div class="Table-Cell">  
<div class="Center-Block">  
<!-- CONTENT -->  
</div>  
</div>  
</div>  
</body>
<style>
.Center-Container.is-Table { display: table; }  
.is-Table .Table-Cell {  
  display: table-cell;  
  vertical-align: middle;  
}  
.is-Table .Center-Block {  
  width: 50%;  
  margin: 0 auto;  
}  
</style>

寫一個(gè)表格,將需要居中顯示的內(nèi)容放在表格正中間.自適應(yīng),內(nèi)容變方塊大小也跟著變,兼容性更是不得了.


97.72%.基本沒有不能兼容的.

嗯,所以應(yīng)該說:
表格布局法的優(yōu)點(diǎn)就是兼容性及其變態(tài),基本沒有不能兼容的.缺點(diǎn)也很明顯,需要添加冗余的HTML樣式,這在網(wǎng)頁開發(fā)中一般是不能被接受的.而且display:table有極大的可能性會(huì)擾亂整個(gè)頁面的布局,使用這種方法還是有一定風(fēng)險(xiǎn)的.

2.行內(nèi)塊法.

這個(gè)方法的本質(zhì)是使用

display: inline-block;
vertical-align: middle;

讓一個(gè)偽元素居于容器中央.

<div class="Center-Container is-Inline">  
  <div class="Center-Block">  
    <!-- CONTENT -->  
  </div>  
</div>  
<Style>

.Center-Container.is-Inline {   
  text-align: center;  
  overflow: auto;  
}  
  
.Center-Container.is-Inline:after,  
.is-Inline .Center-Block {  
  display: inline-block;  
  vertical-align: middle;  
}  
  
.Center-Container.is-Inline:after {  
  content: '';  
  height: 100%;  
  margin-left: -0.25em; /* To offset spacing. May vary by font */  
}  
  
.is-Inline .Center-Block {  
  max-width: 99%; /* Prevents issues with long content causes the content block to be pushed to the top */  
  /* max-width: calc(100% - 0.25em) /* Only for IE9+ */   
}  
</style>

也沒什么好說的,看代碼基本秒懂的級(jí)別.通過加一個(gè)翻看公司的項(xiàng)目,好像帶我的老哥使用的就是這種辦法.

但是我個(gè)人不喜歡這種方法.

先不說CSS寫的又長(zhǎng)又臭,在我看來這完全就是一種Hack,需要死記硬背且難以理解.如果有的選擇,我不會(huì)選擇這種方法.

3.基于絕對(duì)定位的解決方案.

這是一個(gè)古老的方法,具體有多古老?大概是在2013年4月6日.(鏈接至StackOverFlow)網(wǎng)上已經(jīng)有了不少考古學(xué)家做了考證,我就不深挖了.它要求元素具有固定的寬度和高度.

<style>
    main{
        position:absolute; /*絕對(duì)定位*/
        top: 50%;/*向下移動(dòng)父元素高度一半*/
        left:50%;/*向右移動(dòng)父元素寬度一半*/
        margin-top: -3em;/*1em為相對(duì)于父元素font-size的100%,-3em為向上移動(dòng)6/2=3em*/
        margin-left: -9em;
        width: 18em;
        height: 6em;
    }
</style>
<body>
<main>
    <h1>A quick brown fox jump over the lazy dog</h1>
</main>
</body

效果嘛...


title

可以看到,可以幾乎完美的實(shí)現(xiàn)垂直居中.它的原理可以這么解釋:

  1. top: 50%;
    left:50%;
    通過這個(gè)操作,我們將要添加的元素的左上角固定在了屏幕的正中間.
  2. margin-top: -3em;
    margin-left: -9em;
    因?yàn)橹涝氐拇笮?我們用它的一半作為移動(dòng)值,將元素進(jìn)行了移動(dòng).

等等,這樣寫好像有點(diǎn)累贅.讓我們用calc()改一下.

<style>
    main{
        position:absolute; /*絕對(duì)定位*/
        top: calc(50%-3em);/*向下移動(dòng)父元素高度一半*/
        left:calc(50%-9em)/*向右移動(dòng)父元素寬度一半*/
        width: 18em;
        height: 6em;
    }
</style>
<body>
<main>
    <h1>A quick brown fox jump over the lazy dog</h1>
</main>
</body>

這樣就明顯好得多了.

這種做法看起來在大多數(shù)情況下都可以滿足需求了.但是它有一個(gè)很大的局限性,就是我們需要計(jì)算偏移的量,這意味著我們必須知道這個(gè)元素多大.想到了什么沒有?對(duì)啊,CSS為啥沒有This?如果有This的話,這種問題就根本不是問題了.但是很遺憾的是,這個(gè)真沒有.

等等,那就沒有辦法了?

不,為什么說后端學(xué)不會(huì)CSS呢?因?yàn)镃SS是一個(gè)很.....神奇的東西.我們?cè)趖ranslate()這個(gè)八竿子打不著的屬性上居然找到了解決方法.translate()就是以自己本身為目標(biāo)進(jìn)行變換.查查API,略微思考以后,我們可以很輕易的寫出這樣的方法:

 <style>
    main{
        position:absolute; /*絕對(duì)定位*/
        top: 50%;/*向下移動(dòng)父元素高度一半*/
        left:50%;/*向右移動(dòng)父元素寬度一半*/
        transform: translate(-50%,-50%);
    }
</style>
<body>
<main>
    <h1>A quick brown fox jump over the lazy dog</h1>
</main>
</body>

這樣就沒什么問題了.
但是缺點(diǎn)還是存在的.首先當(dāng)然是絕對(duì)定位的問題,老司機(jī)教導(dǎo)我們,能不用絕對(duì)定位盡量不要用絕對(duì)定位,不然布局出問題了調(diào)試起來很麻煩.然后嘛,就是這樣的問題:

假如元素的高度超過了View層大小,怎么辦?

比如這樣:


title

title

可以很明顯的看到,有一半的文字因?yàn)槌龃笮”徊玫袅?這可不好玩.

另外,這種寫法我也認(rèn)為是一種Hack.如果在確定絕對(duì)定位可用且方便的情況下,我也許會(huì)用它.

4.使用VH?一個(gè)不錯(cuò)的主意.

我想使用translate()來移動(dòng)元素進(jìn)行定位.但是我不想用絕對(duì)定位,因?yàn)榻^對(duì)定位是邪惡的.

這個(gè)問題很值得思考,那么如何在不用絕對(duì)定位的前提下進(jìn)行定位呢?

我知道有朋友可能要搶答了:"用margin啊,我margin一個(gè)50%,不就實(shí)現(xiàn)居中了?弄這么多破事干啥?"
很遺憾,這是不行的.

<style>
    main{
        width: 10em;
        padding: 1em 1em;
        margin: 50% auto 0;
        transform: translateY(-50%);
    }
</style>
<body>
<main>
    <h1>A quick brown fox jump over the lazy dog</h1>
</main>
title

這令人窒息的效果!令人窒息的滾動(dòng)條!

深究其原因,margin的百分比是以父元素的寬度作為解析基準(zhǔn)的.等等,父元素的寬度?那我用margin-top,margin-bottom怎么算?難道是不父元素的高度?

很遺憾,還是父元素的寬度為基準(zhǔn).這就可以說是相當(dāng)?shù)目拥?

那就沒有辦法了嗎?不,現(xiàn)在我們有了CSS3,我們有了VH/VW!1VH相當(dāng)于視口高度的1%,1VW相當(dāng)于視口寬度的1%,完美!再也不用擔(dān)心兼容大小屏幕啦!

在這里例子中如果我們使用VH單位:

<style>
    main{
        width: 10em;
        padding: 1em 1em;
        margin: 50vh auto 0;
        transform: translateY(-50%);
    }
</style>
<body>
<main>
    <h1>A quick brown fox jump over the lazy dog</h1>
</main>
</body>

完美的效果.


title

這個(gè)方法我認(rèn)為沒有缺點(diǎn).但是適用性一般,畢竟只能應(yīng)用于需要視口居中的頁面

5.在座的各位都是垃圾-byFlex

終于講到每天都在用的東西了.一個(gè)不會(huì)用Flex的前端,真是太可怕了.
我們只需要給父元素聲明display:flex,再給這個(gè)元素在設(shè)置margin:auto,就可以做到垂直居中了.

<style>
    body{
        display: flex;
        min-height: 100vh;
        margin: 0;
    }
    main{
        margin: auto;
    }
</style>
<body>
<main>
    <h1>A quick brown fox jump over the lazy dog</h1>
</main>
title

什么你問我兼容性?


title

97.19%的兼容性,你還有什么不滿意的?簡(jiǎn)單粗暴高效.

但是它真的完美嗎?不見得.

仔細(xì)看圖不難發(fā)現(xiàn),在你設(shè)置margin-auto之后,不只是垂直,水平也進(jìn)行了居中.雖然我們可以用

 main{
        margin:auto 0 auto 0;
        /*等同于margin-top: auto;margin-bottom: auto;*/
        
    }

這樣的寫法讓元素實(shí)現(xiàn)只垂直居中,但是畢竟又多考慮了兩個(gè)屬性.就沒有更好的辦法了嗎?

5.plus,新的曙光.align-self.

于是我們有了更殘暴的align-self(鏈接至MDN)這一屬性.

它讓垂直居中從圣杯變成了隨便寫寫的東西.

我們只需要:
main{
align-self:center;
}
就能夠徹底實(shí)現(xiàn)上面margin來margin去的效果.

總結(jié)的比較粗淺,所幸沒有留下什么疑問.這個(gè)周末也過得非常充實(shí),以后再碰到垂直居中的問題再也不會(huì)去搜啦!

我的blog是blog.codermagefox.com 歡迎來看看!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 14,095評(píng)論 1 92
  • 收聽音頻,戳鏈接,舊號(hào)itclan已暫停使用,歡迎關(guān)注微信itclanCoder公眾號(hào)可收聽更多音頻 前言 關(guān)于網(wǎng)...
    itclanCoder閱讀 8,346評(píng)論 3 30
  • 垂直居中作為一個(gè)常見布局形式,或多或少的會(huì)給不熟悉頁面布局的人帶來困擾,這里參考Steven Bradley總結(jié)的...
    留七七閱讀 2,535評(píng)論 6 18
  • 一 外部式css樣式 (也可稱為外聯(lián)式)就是把css代碼寫一個(gè)單獨(dú)的外部文件中,這個(gè)css樣式文件以“.css...
    KunMitnic閱讀 1,112評(píng)論 0 1
  • 文/柳慕唐 一篇舊作,翻出來蹭熱點(diǎn)咯~ 周末無事,在宿舍用電腦看《分手合約》。幾年前的老電影,下載了卻一直忘了...
    柳慕唐閱讀 1,150評(píng)論 0 2

友情鏈接更多精彩內(nèi)容