從頭開始 — CSS — 垂直居中

事實上,每次面試前端必問的問題就是這個。及其常見的需求,看起來似乎非常簡單,但是實現(xiàn)起來很費勁,尤其是涉及尺寸不固定的元素。

本篇文章將介紹比較流行的幾種方法。

行內塊

<body>
    <div id="ghost"></div>
    <span>
        hello
    </span>
</body>
 #ghost {
            display: inline-block;
            height: 20em;
            vertical-align: middle;
        }

本質上是利用了內聯(lián)元素的 vertical-align 屬性,通過將此屬性置為middle,同一行內的內聯(lián)元素都將以設置這一屬性的內聯(lián)元素的基線對齊。

基于inline-block特有的屬性:擁有內聯(lián)元素的特性同時可以定義寬高,我們可以設置一個ghost行內塊用于定義高度,再讓其他內聯(lián)元素與其對齊,實現(xiàn)垂直居中。

當然我們也可以將其它元素置為行內塊,再設置寬度并添加text-align使其水平居中。

總結一下,此方法太過hack。

絕對定位

子元素固定寬高

<div id="main">
        <div id="child">
            hello
        </div>
</div>
#main {
            background-color: green;
            height: 20em;
            width: 20em;
            position: relative;
}

#child {
            position: absolute;
            background: yellow;
            top: 50%;
            left: 50%;
            height: 10em;
            width: 10em;
            margin-top: -5em;
            margin-left: -5em;
}

顯然,這種方法的原理是:先利用絕對定位將這個元素的左上角放置與父元素的正中間,再利用負邊距將它向左上移動它本身的一半。

如果借助calc()函數可以說明得更加清楚:

#child {
    position: absolute;
    top: calc(50%-5em);
    left: calc(50%-5em);
    height: 10em;
    width: 10em;
}

不固定寬高

實際中大多數時候我們并不知道子元素的實際寬高。

如果你屬性translate()函數,你一定知道當它的參數為百分比時,它會按照元素本身的百分比值進行變換,我們可以通過這個方法徹底擺脫對尺寸的依賴!

#child {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
}

看起來已經完美解決了,但是它還有以下的缺陷:

  1. 絕對定位會對整體的布局造成很強烈的影響。
  2. 如果居中的元素超過了視窗會被裁剪掉。
  3. 在某些瀏覽器中,元素可能會被放置在半個像素上造成模糊。

視口居中

如果我們不采用絕對定位,對子元素設置margin使其左上角置于父元素中點,再用translate重復上一種方法的操作,是否可以實現(xiàn)呢?

答案是不可以,因為margin的百分比是以父元素的寬度為基準的,即便是top和bottom也是! 沒錯,很扯。

如果僅僅想要垂直于視口,我們可以采用css中相對于視口的單位 vwvh、vminvmax

  • 1vw 表示視口寬度的1%,同理1vh等于視口高度的1%
  • 當視口寬度小于高度時,1vmin=1vw,否則1vmin=1vh,另一種情況同理。
#child {
            margin:50vh auto 0;
            transform: translateY(-50%);
}

它只能基于視口居中。

Flexbox

flex當然是未來的趨勢,上面的一切都可以理解成為了照顧老舊的瀏覽器的猴戲(雖然translate和視口單位的兼容性也不怎么好)。

<body>
    <div id="main">hello</div>
</body>
#main {
           margin: auto;
        }
 body {
            display: flex;  
        }

啊,很難受。使用flexbox時,margin:auto不僅在水平方向上將元素居中,垂直方向上也是如此。

如果你熟悉flex的話,其實還有多種實現(xiàn)方式。

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

或者對子元素單獨設置交叉軸對齊方式:

body {
            display: flex;  
            justify-content: center;
        }
#main {
            align-self:center;
}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 14,199評論 1 92
  • CSS 是什么 css(Cascading Style Sheets),層疊樣式表,選擇器{屬性:值;屬性:值}h...
    崔敏嫣閱讀 1,582評論 0 5
  • 一 外部式css樣式 (也可稱為外聯(lián)式)就是把css代碼寫一個單獨的外部文件中,這個css樣式文件以“.css...
    KunMitnic閱讀 1,140評論 0 1
  • 高考后離婚綜合癥在新學期的第一天就爆發(fā)了。多年的夫妻們,忍無可忍,無需再忍,平靜又決絕。。。 男女之間愛情與婚姻的...
    鷺風閱讀 347評論 3 0
  • 本來應該昨天回家的,在上海參加三天學習實在累、腳疼的走不動,沒能在和女兒約定的時間回家。中午,父女倆去車站接我,...
    武春麗閱讀 434評論 0 0

友情鏈接更多精彩內容