CSS常用布局之各種元素的水平垂直居中

2018-06-07 16:51 更新

水平(垂直)居中是CSS布局中經(jīng)常會遇到的一個(gè)場景。但是由于各個(gè)元素的差異(比如不同的元素可分為行內(nèi)元素,行內(nèi)塊級元素,塊級元素等),其水平或者垂直居中的策略也是不一樣的。本篇文章將會詳細(xì)介紹各種元素的水平垂直居中策略。

水平居中

針對行內(nèi)元素塊級元素,各自的水平居中策略其實(shí)是不太一致的。

行內(nèi)元素

如果被設(shè)置元素為文本、圖片等行內(nèi)元素時(shí),可以通過給其父元素設(shè)置text-align:center來實(shí)現(xiàn)水平居中。看下面的代碼,


<head>
<style>
    div.txtCenter{
        text-align:center;
    }
</style>
</head>
<body>
  <div class="txtCenter">我是文本,哈哈,我想要在父容器中水平居中顯示。</div>
</body>

塊級元素

針對塊級元素,比如div這種,我們使用text-align:center就不起作用了。

這里,塊級元素將會分兩種情況,寬度確定以及寬度不確定的塊級元素,因?yàn)獒槍@兩種情況的水平居中策略是不同的。

定寬塊級元素

滿足定寬條件的塊級元素,我們一般可以通過設(shè)置其margin-leftmargin-right屬性為auto來實(shí)現(xiàn)居中。

代碼如下,


<head>
<style>
div{
    width: 500px;/*定寬*/
    margin: 20px auto;/* margin-left 與 margin-right 設(shè)置為 auto */
}
</style>
</head>
<body>
    <div>我是定寬塊狀元素,哈哈,我要水平居中顯示。</div>
</body>

不定寬塊級元素

在上述(1.2.1)的代碼中,如果我們?nèi)サ裘鞔_的寬度設(shè)置,則使用margin: 0 auto就不能使元素水平居中了。

在實(shí)際的工作中,某些元素(塊)常常由于種種原因,其內(nèi)容(寬度)是不確定的,我們顯然不能顯式的限制其寬度。那么此時(shí)我們?nèi)绾螌@些元素進(jìn)行水平居中呢。

通常會有三種方法,

  • 使用table標(biāo)簽進(jìn)行包裝
  • 設(shè)置display: inline方法
  • 設(shè)置position: relative;left: 50%

使用table標(biāo)簽進(jìn)行包裝

首先我們需要在要水平居中的元素的外面包裝一層table,然后給table設(shè)置margin: 0 auto。代碼如下,


<head>
<style>
table {
    margin: 0 auto;
}
.div1 {
    background-color: pink;
}
.div2 {
    background-color: #ccc;
}
</style>
</head>
<div>
    <table>
        <tbody>
            <tr><td>
                <div class="div1">我被水平居中了</div>
            </td></tr>
        </tbody>
    </table>
</div>
<div class="div2">我沒水平居中</div>

效果如下圖,

很顯然這種方法有一些不足之處,需要添加一些無意義的標(biāo)簽,從而造成html代碼的冗余。

設(shè)置display: inline方法

塊級元素通常包括兩種,display: block或者display: inline-block。這種方法將塊級元素的display屬性設(shè)置為inline,然后使用text-align: center來實(shí)現(xiàn)水平居中。

示例代碼如下,


<head>
<style>
.container {
    text-aligin: center;
}
.div1 {
    display: inline;
}
</style>
</head>
<body>
<div class="container">
    <div class="div1">我要水平居中</div>
</div>
</body>

這種方法雖然不需要增加一些冗余的標(biāo)簽,簡化了標(biāo)簽的嵌套深度,但是也存在一些問題。它將display屬性設(shè)置成inline變成了行內(nèi)元素,所以少了一些可操作性,比如你不能給行內(nèi)元素設(shè)置寬度等。

浮動加相對定位

通過給父元素設(shè)置float,然后給父元素設(shè)置position:relativeleft:50%,子元素設(shè)置position:relativeleft:-50%來實(shí)現(xiàn)水平居中。

示例代碼如下,


<style>
.container{
    float: left;
    position: relative;
    left:50%
}
.div1 {
    position: relative;
    left: -50%;
    background-color: pink;
}
.div2 {
    background-color: #ccc;
}
<body>
<div class="container">
    <div class="div1">我要水平居中</div>
</div>
<div class="div2">我沒有水平居中</div>
</body>

這種方法可以保留塊狀元素仍以display:block的形式顯示,優(yōu)點(diǎn)不添加無語議表標(biāo)簽,不增加嵌套深度,但它的缺點(diǎn)是設(shè)置了position:relative,帶來了一定的副作用。

垂直居中

元素的垂直居中不像水平居中那么復(fù)雜。這里我們只討論簡單的垂直居中問題,其他更加復(fù)雜的垂直居中問題可以參考以前的這篇文章。

父元素高度確定的單行文本

父元素高度確定的單行文本的垂直居中的方法是通過設(shè)置父元素的heightline-height屬性一致來實(shí)現(xiàn)的。

示例代碼如下,


<head>
<style>
.container {
    height: 100px;
    line-height: 100px;
    background: #ddd;
}
</style>
</head>
<div class="container">我要垂直居中</div>

效果如下,

父元素高度確定的多行文本、圖片、塊級元素

針對父元素高度確定的多行文本、圖片以及塊級元素,我們通常有兩種間接的方法來設(shè)置其垂直居中。

使用table標(biāo)簽包裝

與上面同樣的原理,我們將待垂直居中的元素(塊)使用table標(biāo)簽進(jìn)行封裝,設(shè)置th或者td標(biāo)簽的vertical-align: middle。

示例代碼如下,


<head>
<style>
    table td {
        height: 500px;
    }
    .wrap {
        border: 1px solid red;
        height: 500px;
        width: 650px;
    }
    .div1 {
        background-color: pink;
    }
</style>
</head>
<body>
<div class="wrap">
    <table><tbody><tr><td>
        <div class="div1">
            我要垂直居中<br>
            我要垂直居中<br>
            我要垂直居中<br>
            我要垂直居中<br>
            我要垂直居中<br>
        </div>
    </td><tr></tbody></table>
</div>
</body>

效果如下,

注意一點(diǎn),td標(biāo)簽?zāi)J(rèn)情況下就默認(rèn)設(shè)置了vertical-align: middle,所以我們不需要顯式地設(shè)置了。

設(shè)置display: table-cell

在chrome、firefox 及IE8+的瀏覽器下可以設(shè)置塊級元素的display: table-cell,激活vertical-align: middle屬性,但注意IE6、7并不支持這個(gè)樣式。

示例代碼如下,


<head>
<style>
.wrap{
    height: 500px;
    border: 1px solid red;
    height: 500px;
    width: 650px;
    display: table-cell; /*IE8以上及Chrome、Firefox*/
    vertical-align: middle; /*IE8以上及Chrome、Firefox*/
}
.div1 {
    background-color: pink;
}
</style>
</head>
<body>
<div class="wrap">
    <div class="div1">
        我要垂直居中<br>
        我要垂直居中<br>
        我要垂直居中<br>
        我要垂直居中<br>
        我要垂直居中<br>
    </div>
</div>
</body>

效果如下,

這里,我們設(shè)置元素的display: table-cell屬性,讓其展示屬性呈現(xiàn)單元格的特性,這樣就不必再包裝冗余的table標(biāo)簽代碼了。這里的原理其實(shí)和第一種方法是一致的。

間接改變display屬性

CSS中有一個(gè)奇怪的現(xiàn)象,不管元素之前的display屬性是什么(none除外),當(dāng)元素滿足下列條件任何一個(gè)時(shí),

  • position: absolute
  • float: left/right

元素會自動變?yōu)橐?code>display:inline-block的方式顯示。此時(shí)我們可以設(shè)置元素的widthheight且默認(rèn)寬度不占滿父元素。

我們在實(shí)際工作中可以利用這個(gè)特性,能夠更加靈活的布局。

至于為什么會出現(xiàn)這種情況,我的猜測是,當(dāng)元素設(shè)置position: absolute或者float: left/right時(shí),元素將擺脫原始的文檔流變成游離的元素,此時(shí)元素的位置可以手動任意設(shè)置,而且此時(shí)元素的大?。▽捀撸┛梢杂善湮恢迷兀?code>top/right/bottom/left)來確定。

以上猜測若有不妥,請指正。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號