总结:使单一对象水平/垂直居中

明白单一对象的水平/垂直居中的写法和原理,有助于我们构造更加复杂的居中布局。

我们按照居中的“里面的内容”来分类,展开全文:

“里面的内容”为单行行内元素的时候(以单行文字为例)

由于设置text-align:center之后,行内的元素就会水平居中,比较简单。所以这里侧重讲垂直居中。

A法:令line-height和height相等–垂直居中

.parent {
  height: 300px;
  line-height: 300px;
}

事实上,不需要对于height属性的设置也是可以的。

  • 【缺点】:只能用于居中一行文字(否则就改为用别的方法)

B法:使用display:table-cell和vertical-align:middle–垂直居中

<style>
.parent {
  width: 300px;
  height: 250px;
  background: green;

  display: table-cell;
  vertical-align: middle;
}
</style>
<body>
<div class="parent">这是文字这是文字这是文字这是文字这是文字这是文字这是文字这是文字</div>
</body>

另外,常见的table-cell外面套一层display:table元素的作用:对table-cell元素设置百分比(如100%)的宽高值时无效的,但是可以将父元素设置display:table,再将父元素设置百分比宽高,子元素table-cell会自动撑满父元素。这就可以做相对于整个页面的水平垂直居中。

优点:

  • height和line-height可以自由定义,这方便内容从单行文字发展为多行文字
  • 在浏览器缩放的时候表现优异

缺点:

  • 设置.parent为float:left或者positon:absolute或者position:fixed 时居中会失效。如需兼顾他们,此时需要外面套多一层元素。
  • IE7及以下都不支持

备注:

  • 特点是在IE8及以上浏览器的时候,.grandparent 的高度其实是可以自动适应的。
兼容更老的IE的写法:【左侧角标展开见内容】
  • 《兼容更老的IE的写法》
    • HTML结构需要多套两层div:.grandparent.child
    • 宽度、高度和背景等属性需要转移到.grandparent 这一级
    • 文字内容需要转移到.child 这一级
<style>
.grandparent {
  width: 300px;
  /*自动高度:*/
  /*height: 250px;*/
  background: green;

  display: table;
  *position:relative;
  overflow:hidden;
}
.parent {
  display: table-cell;
  vertical-align: middle;

  *position:absolute;
  *top:50%;
}
.child {
  *position:relative;
  *top:-50%;
}
.someone {
  height: 400px;
  background: yellow;
}
</style>
<body>
<div class="grandparent">
  <div class="someone">用来增大高度用来增大高度用来增大高度,可以被删掉</div>
  <div class="parent">
    <div class="child">这是文字这是文字这是文字这是文字这是文字这是文字这是文字这是文字</div>
  </div>
</div>
</body>

C法:使用display: inline-block和vertical-align:middle–垂直居中

这里只给出近似垂直居中的例子,在实际项目中用得最多;而如果想设置为完美垂直居中或者了解更多,详见vertical-align:middle近似居中和完美居中

  • 统一封装、普适适用于“居中单行文字”、“居中图片”和“居中多行文字”(包括“居中单行文字”):
    • 再加上简单记忆一些其他的样式实现手段,就能快捷完成开发。
    • (当欲设置verticial-align:middle时,img可视为一个低配版的inline-block元素。)
    • 效果:父容器可以选择使用line-height或者height来撑高,放宽了适用场景
  • (备注:这个辅助元素可以是伪元素,也可以是 i 元素。)
<style>
.vertical-center:before {
    content:'';
    width: 0; /* 如果为了应对各种场景而普适省事,可以加上 width: 0 */

    display:inline-block;
    vertical-align:middle;
    height:100%;
}
.vertical-center > img {
  vertical-align: middle;
}
.vertical-center > .vertical-center__text {
  display: inline-block;
  vertical-align: middle;
}
/* 灵活:在此垂直居中基础上,加上水平居中 */
.vertical-center { text-align: center; }
/* 【测试代码,可删】: *//* 效果是:放宽了适用场景 */
.vertical-center { height: 300px }
</style>
<body>
  <div class="vertical-center">
    <img src="" alt="图片src要设置!!"/>
    <span class="vertical-center__text">一行文字AAA<br>一行文字<br>一行文字</span>
    <span class="vertical-center__text">单行文字</span>
    <!-- 如上,单行文字,如果想垂直居中,应放入span元素里面,然后和“多行文字”的样式处理一致:一致span套上对应的class -->
  </div>
</body>

D法:flex布局/grid布局–水平垂直居中

grid布局:(对于水平垂直居中这个问题,)方式和flex布局类似。因为浏览器兼容性不如flex,且flex能满足的场景挺多的。所以一般只用flex布局就够了。

<style>
.parent {
  width: 300px;
  height: 250px;
  background: green;

  /* display: -webkit-flex; */
  /* display: -ms-flex; *//* IE 10 */
  display: flex;
  align-items: center;
}
</style>
<body>
  <div class="parent">这是文字这是文字</div>
</body>
  • 【优点】:
    • .parent元素无须定高
    • 代码简单
  • 【缺点】:其实文字是可以自动换行的,这样就是多行文字了,但是需要IE11
  • 【兼容性】:IE要10才支持
    • (兼容IE10的写法为:display: -ms-flex;; 而且要求-ms-flex-preferred-size(即第三个参数)带单位,所以必须写成0px0%auto。)

“里面的内容”为多行行内元素的时候(以多行文字为例)

参考上文B法

参考上文C法

参考上文D法

“里面的内容”为大小不固定的图片的时候

参考上文B法

参考上文C法

参考上文D法

“里面的内容”为定宽高的块级元素的时候

定宽+margin auto–水平居中

<style>
.child {
    width: 300px;
    background: green;

    margin: 0 auto;
}
</style>
<body>
<div class="child">这是文字这是文字这是文字这是文字这是文字这是文字</div>
</body>
  • 【兼容性】:IE7及以上都是可以的

定宽高+绝对定位+负margin–水平垂直居中

<style>
.child {
    width: 300px;
    height: 250px;
    background: green;

    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -150px;
    margin-top: -125px;
}
</style>
<body>
<div class="child">这是文字这是文字这是文字这是文字这是文字这是文字</div>
</body>
  • 【兼容性】:兼容性好
  • 【备注】:将position: absolute;改成position: fixed;也是可以的,相信大家都懂什么意思。
    • 但是在老版本IE下会不支持fixed,在网上抄一下怎么兼容就行了。

定宽高+绝对定位+calc

思路和上面“要求定宽高+负margin”一样。

只不过特别之处在于,calc这个api,其实就是在这个问题中用于获取百分比数据作为临时量。

浏览器兼容性略差:即calc的兼容性和transform: translate方案相当。

<style>
.child {
    width: 300px;
    height: 250px;
    background: green;

    position: absolute;
    top: calc(50% - 150px);
    left: calc(50% - 125px);
    /* margin-left: -150px; */
    /* margin-top: -125px; */
}
</style>
<body>
<div class="child">这是文字这是文字这是文字这是文字这是文字这是文字</div>
</body>

“里面的内容”为不定宽高的块级元素的时候

绝对定位+margin:auto–水平垂直居中

<style>
.child {
  /*宽高可以不写:*/
  width: 300px;
  height: 250px;
  background: green;

  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;

  margin: auto;
}
</style>
<body>
<div class="child">这是文字这是文字这是文字</div>
</body>

绝对定位+translate–水平垂直居中

<style>
.parent {
    width: 300px;
    height: 300px;
    background: green;

    position: relative;
}
.child {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}
</style>
<body>
<div class="parent">
<div class="child">这是文字这是文字这是文字这是文字这是文字这是文字这是文字这是文字</div>
</div>
</body>
  • 【优点】:父子元素的width和height都可以自己定
  • 【兼容性】:IE8及以下不兼容

flex布局/grid布局–水平垂直居中

  • (对比grid布局:(对于水平垂直居中这个问题,)方式和flex布局类似。因为grid的浏览器兼容性不如flex,且flex能满足的场景挺多的。所以一般只用flex布局就够了。)
  • (flex布局在这个场景有点大才小用了。)

转换成行内块级元素 #个别场景下适用,容易被忽略

此次我们居中的目标是一个块级元素的块块,而非之前的行内元素

我们需要加上display: inline-block;使它变成行内块级元素,然后就可以参考行内元素的居中来弄了。

文章目录
  1. “里面的内容”为单行行内元素的时候(以单行文字为例)
    1. A法:令line-height和height相等–垂直居中
    2. B法:使用display:table-cell和vertical-align:middle–垂直居中
      1. 优点:
      2. 缺点:
      3. 备注:
    3. C法:使用display: inline-block和vertical-align:middle–垂直居中
    4. D法:flex布局/grid布局–水平垂直居中
  2. “里面的内容”为多行行内元素的时候(以多行文字为例)
  3. “里面的内容”为大小不固定的图片的时候
  4. “里面的内容”为定宽高的块级元素的时候
    1. 定宽+margin auto–水平居中
    2. 定宽高+绝对定位+负margin–水平垂直居中
    3. 定宽高+绝对定位+calc
  5. “里面的内容”为不定宽高的块级元素的时候
    1. 绝对定位+margin:auto–水平垂直居中
    2. 绝对定位+translate–水平垂直居中
    3. flex布局/grid布局–水平垂直居中
    4. 转换成行内块级元素 #个别场景下适用,容易被忽略