阅读(1746) (0)

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

2017-06-07 14:46:40 更新

水平(垂直)居中是CSS布局中经常会遇到的一个场景。但是由于各个元素的差异(比如不同的元素可分为行内元素行内块级元素块级元素等),其水平或者垂直居中的策略也是不一样的。本篇文章将会详细介绍各种元素的水平垂直居中策略。

水平居中

针对行内元素块级元素,各自的水平居中策略其实是不太一致的。

行内元素

如果被设置元素为文本、图片等行内元素时,可以通过给其父元素设置text-align:center来实现水平居中。看下面的代码,


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

块级元素

针对块级元素,比如div这种,我们使用text-align:center就不起作用了。

这里,块级元素将会分两种情况,宽度确定以及宽度不确定的块级元素,因为针对这两种情况的水平居中策略是不同的。

定宽块级元素

满足定宽条件的块级元素,我们一般可以通过设置其margin-leftmargin-right属性为auto来实现居中。

代码如下,


<head>
<style>
div{
    width: 500px;/*定宽*/
    margin: 20px auto;/* margin-left 与 margin-right 设置为 auto */
}
</style>
</head>
<body>
    <div>我是定宽块状元素,哈哈,我要水平居中显示。</div>
</body>

不定宽块级元素

在上述(1.2.1)的代码中,如果我们去掉明确的宽度设置,则使用margin: 0 auto就不能使元素水平居中了。

在实际的工作中,某些元素(块)常常由于种种原因,其内容(宽度)是不确定的,我们显然不能显式的限制其宽度。那么此时我们如何对这些元素进行水平居中呢。

通常会有三种方法,

  • 使用table标签进行包装
  • 设置display: inline方法
  • 设置position: relative;left: 50%

使用table标签进行包装

首先我们需要在要水平居中的元素的外面包装一层table,然后给table设置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>

效果如下图,

很显然这种方法有一些不足之处,需要添加一些无意义的标签,从而造成html代码的冗余

设置display: inline方法

块级元素通常包括两种,display: block或者display: inline-block。这种方法将块级元素的display属性设置为inline,然后使用text-align: center来实现水平居中。

示例代码如下,


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

这种方法虽然不需要增加一些冗余的标签,简化了标签的嵌套深度,但是也存在一些问题。它将display属性设置成inline变成了行内元素,所以少了一些可操作性,比如你不能给行内元素设置宽度等。

浮动加相对定位

通过给父元素设置float,然后给父元素设置position:relativeleft:50%,子元素设置position:relativeleft:-50%来实现水平居中。

示例代码如下,


<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的形式显示,优点不添加无语议表标签,不增加嵌套深度,但它的缺点是设置了position:relative,带来了一定的副作用。

垂直居中

元素的垂直居中不像水平居中那么复杂。这里我们只讨论简单的垂直居中问题,其他更加复杂的垂直居中问题可以参考以前的这篇文章

父元素高度确定的单行文本

父元素高度确定的单行文本的垂直居中的方法是通过设置父元素的heightline-height属性一致来实现的。

示例代码如下,


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

效果如下,

父元素高度确定的多行文本、图片、块级元素

针对父元素高度确定的多行文本、图片以及块级元素,我们通常有两种间接的方法来设置其垂直居中。

使用table标签包装

与上面同样的原理,我们将待垂直居中的元素(块)使用table标签进行封装,设置th或者td标签的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>

效果如下,

注意一点,td标签默认情况下就默认设置了vertical-align: middle,所以我们不需要显式地设置了。

设置display: table-cell

在chrome、firefox 及IE8+的浏览器下可以设置块级元素的display: table-cell,激活vertical-align: middle属性,但注意IE6、7并不支持这个样式。

示例代码如下,


<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>

效果如下,

这里,我们设置元素的display: table-cell属性,让其展示属性呈现单元格的特性,这样就不必再包装冗余的table标签代码了。这里的原理其实和第一种方法是一致的。

间接改变display属性

CSS中有一个奇怪的现象,不管元素之前的display属性是什么(none除外),当元素满足下列条件任何一个时,

  • position: absolute
  • float: left/right

元素会自动变为以display:inline-block的方式显示。此时我们可以设置元素的widthheight且默认宽度不占满父元素。

我们在实际工作中可以利用这个特性,能够更加灵活的布局。

至于为什么会出现这种情况,我的猜测是,当元素设置position: absolute或者float: left/right时,元素将摆脱原始的文档流变成游离的元素,此时元素的位置可以手动任意设置,而且此时元素的大小(宽高)可以由其位置元素(top/right/bottom/left)来确定。

以上猜测若有不妥,请指正。