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

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

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

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

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

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

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

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

缺点:

只能居中一行文字:如果不想在页面缩放的时候让文字跑出元素的范围外,建议在后面加上overflow: hidden

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>

优点:

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

缺点:

  • 设置.parent为float:left或者positon:absolute或者position:fixed 时居中会失效。如需兼顾他们,此时需要外面套多一层元素。(因为vertical-align只适用于inline/inline-block元素或者table-cell元素,详见 深入理解vertical-align:middle
  • 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

<style>
.parent {
  line-height: 300px;
  text-align: center;
  background: green;
}
.text {
  display: inline-block;
  vertical-align: middle;
  
  line-height: normal;
  text-align: left;
  max-width: 100%;
}
</style>
<body>
<p class="parent">
<span class="text">一行文字<br>一行文字<br>一行文字</span><!-- 兼容IE7,这里要换行或空格 -->
</p>
</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元素不用定高
  • 代码简单

缺点:

  • IE要10才支持
    • (兼容IE10的写法为:display: -ms-flex;; 而且要求-ms-flex-preferred-size(即第三个参数)带单位,所以必须写成0px0%auto。)
  • 其实文字是可以自动换行的,这样就是多行文字了,但是需要IE11

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

参考上文B法

参考上文C法

参考上文D法

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

参考上文B法

参考上文C法

参考上文D法

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

定宽+margin auto–水平居中

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

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

备注:

首先,元素定宽是必须的。然后,大家都知道,只要margin-left和margin-right都为auto就行了。

优点:

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>

优点:

符合人的直觉思维习惯

缺点:

需要IE8及以上

备注:

  • 定位改成用fixed也是可以的
  • 其原理参考:

margin-auto-absolute-绝对定位-水平垂直居中-张鑫旭

为什么margin:auto可以让块级元素水平居中

绝对定位+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及以下不兼容

备注:

  • 绝对定位也可以改写为相对定位:
.parent {
  	/*子元素相对定位,父元素定高*/
    width: 300px;
    height: 250px;
    background: green;
}
.child {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
}

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

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

flex布局在这里有点大才小用了。关键在于了解flex布局的特点。因为写法较多,参考网上的。

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

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

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

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