博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CSS 拷问:水平垂直居中方法你会几种?
阅读量:3899 次
发布时间:2019-05-23

本文共 6217 字,大约阅读时间需要 20 分钟。

本文首发于我的个人博客:


CSS 实现水平垂直居中,这是一道经典的面试题,也是我们平时开发经常遇见的问题。本文总结了常用的方法,以及各种奇淫巧技,并且会注明每种方法的兼容性。

开始正文之前,我们准备一些元素:

hello world

为了便于查看,加上一些样式:

.outer {
width: 300px; height: 300px; border: 1px solid #999;}.inner {
width: 100px; height: 100px; border: 1px solid #999;}

上面这些代码会在下文中复用,并且不再提及,请注意记忆。

水平垂直居中

下面是水平和垂直居中都适用的方法:

  1. Flex 方案
  2. Grid 方案
  3. absolute + transform
  4. absolute + calc
  5. absolute + 负 margin
  6. absolute + margin: auto
  7. writing-mode

Flex 方案

/* 这里引用复用代码 */.outer {
display: flex; justify-content: center; /* 水平居中 */ align-items: center; /* 垂直居中 */}

该方案的另一种用法:

/* 这里引用复用代码 */.outer {
display: flex;}.inner {
margin: auto;}

目前在移动端已经完全可以使用 Flex 布局了,PC 端需要看自己业务的兼容性情况。

优点:不需要固定居中元素的宽高。

兼容性:

  • IE 10+, Chrome 4+, Firefox 2+
  • Android 2.3+, iOS 6+

Grid 方案

/* 这里引用复用代码 */.outer {
display: grid;}.inner {
justify-self: center; /* 水平居中 */ align-self: center; /* 垂直居中 */}

该方案的另一种使用方法:

/* 这里引用复用代码 */.outer {
display: grid;}.inner {
margin: auto;}

该方案的兼容性比 Flex 差一点,同样的根据自己业务的兼容情况选择使用。

优点:不需要固定居中元素的宽高。

兼容性:

  • IE 10+, Chrome 57+, Firefox 52+
  • Android 6+, iOS 10.3+

absolute + transform

CSS3 中新增的 transform,其 translate 属性是根据元素自身计算的。例如:设置 transform: translateX(-50%);,元素会向左偏移自身宽度的一半。根据这一特性,很容易实现元素的居中:

/* 这里引用复用代码 */.outer {
position: relative;}.inner {
position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);}

优点:不需要固定居中元素的宽高。

兼容性:

  • IE 9+, Chrome 4+, Firefox 3.5+
  • Android 3+, iOS 6+

absolute + calc

/* 这里引用复用代码 */.outer {
position: relative;}.inner {
position: absolute; left: calc(50% - 50px); top: calc(50% - 50px);}

缺点:需要固定居中元素的宽高。

兼容性:

  • IE 9+, Chrome 19+, Firefox 4+
  • Android 4.4+, iOS 6+

absolute + 负 margin

/* 这里引用复用代码 */.outer {
position: relative;}.inner {
position: absolute; left: 50%; top: 50%; margin-left: -50px; margin-top: -50px;}

缺点:需要固定居中元素的宽高。

兼容性:

  • IE 6+, Chrome 4+, Firefox 2+
  • Android 2.3+, iOS 6+

absolute + margin: auto

/* 这里引用复用代码 */.outer {
position: relative;}.inner {
position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto;}

该方案的原理是:使用了 CSS 中的定位属性(absolutefixed 等)后,如果 left 设置了具体值,没有设置 rightwidth,那么就会自动计算,把剩余的空间分配给 rightwidth。如果 leftrightwidth 都设置了具体值,并且没有占满横向空间,那么剩余空间就处于待分配状态,此时设置 margin: auto; 意味着把剩余的空间分配给 margin,并且左右均分,所以就实现了水平居中,垂直方向同理。

但是要知道该方法的副作用:

  • left: 0; right: 0; 相当于 width: 100%;
  • top: 0; bottom: 0; 相当于 height: 100%;

缺点:需要固定居中元素的宽高,否则其宽高会被设为 100%

兼容性:

  • IE 6+, Chrome 4+, Firefox 2+
  • Android 2.3+, iOS 6+

writing-mode

writing-mode 可以改变文字显示方向。例如,将文字显示为垂直方向:

垂直显示
div {
writing-mode: vertical-lr;}

显示效果如下:

垂直显示

该属性最神奇的地方在于,不仅可以使文字显示方向改变,还能使所有作用于水平方向上的属性,变成作用于垂直方向。所以,通过 writing-modetext-align: center 就可以实现垂直居中了。

这里,我们需要改造下复用代码中的 DOM 结构:

然后,该方案的核心代码如下:

/* 这里引用复用代码 */.outer {
writing-mode: vertical-lr; text-align: center;}.inner {
display: inline-block; width: 100%; height: auto; writing-mode: horizontal-tb; text-align: center;}.content {
display: inline-block; text-align: left; /* 重置文字位置(如果需要) */}

优点:不需要固定居中元素的宽高。

兼容性:

  • IE 6+, Chrome 4+, Firefox 3.5+
  • Android 2.3+, iOS 5.1+

水平居中

下面介绍只适用于水平居中的方案:

  1. margin: auto
  2. text-align + inline-block
  3. fit-content + margin

margin: auto

/* 这里引用复用代码 */.inner {
display: block; /* 还可以是 table | flex | grid,但不能是 inline-xxx */ margin: 0 auto;}

该方案的原理是:元素被设置成块级后,会独占一行,如果其宽度没有占满横向空间,那么剩余的空间就处于待分配状态,此时设置 margin: auto; 意味着把剩余的空间分配给 margin,并且左右均分,所以就实现了水平居中。

缺点:需要固定居中元素的宽。

text-align + inline-block

/* 这里引用复用代码 */.outer {
text-align: center;}.inner {
display: inline-block; text-align: left; /* 重置文字位置(如果需要) */}

该方案的原理是:上面代码中的 text-align: center; 会使文本居中,但是对元素无效,如果将元素设置为 inline-block,就会使元素被当做文本对待,从而实现元素居中。

缺点:为了居中元素,使文本也居中了,因此可能需要重置文本位置。

优点:不需要固定居中元素的宽。

fit-content + margin

该方案用法有两种,一种是直接应用于元素上,另一种是应用于元素的父元素上。

  • 直接应用于元素上

    /* 这里引用复用代码 */.inner {
    width: fit-content; margin: auto;}

    缺点:会使元素的宽度改变(同内容宽度)。

  • 应用于元素的父元素上

    /* 这里引用复用代码 */.outer {
    width: fit-content; margin: auto;}

    优点:即使子元素是浮动元素也适用。

由于目前 fit-content 属性兼容性较差,因此该方案不推荐使用。

垂直居中

下面介绍只适用于垂直居中的方案:

  1. table-cell + vertical-align
  2. inline-block + line-height
  3. inline-block + vertical-align

table-cell + vertical-align

/* 这里引用复用代码 */.outer {
display: table-cell; vertical-align: middle;}

优点:不需要固定居中元素的高。

该方案可配合水平居中的方案 1、2,实现水平垂直居中,如下所示:

  • 配合水平居中方案 1

    /* 这里引用复用代码 */.outer {
    display: table-cell; vertical-align: middle;}.inner {
    display: block; /* 还可以是 table | flex | grid,但不能是 inline-xxx */ margin: 0 auto;}

    缺点:需要固定居中元素的宽。

    优点:不需要固定居中元素的高。

  • 配合水平居中方案 2

    /* 这里引用复用代码 */.outer {
    display: table-cell; vertical-align: middle; text-align: center;}.inner {
    display: inline-block; text-align: left; /* 重置文字位置(如果需要) */}

    优点:不需要固定居中元素的宽高。

inline-block + line-height

/* 这里引用复用代码 */.outer {
line-height: 300px;}.inner {
line-height: initial; /* 重置 */ vertical-align: middle; display: inline-block;}

众所周知,元素的 heightline-height 相同的时候,会使其文本内容垂直居中。因此该方案利用了这一特点,不过文本内容虽然垂直居中了,但是元素并没有,因此再将元素设置为 display: inline-block;,这样元素就会被当做文本对待了。同时由于具有了 inline 属性,vertical-align: middle; 也就可以生效了。

缺点:需要知道其父元素高度。

优点:不需要固定居中元素的高。

该方案可配合水平居中的方案 2,实现水平垂直居中,如下所示:

/* 这里引用复用代码 */.outer {
line-height: 300px; text-align: center;}.inner {
line-height: initial; /* 重置行高 */ vertical-align: middle; display: inline-block; text-align: left; /* 重置文字位置(如果需要) */}

缺点:需要知道其父元素高度。

优点:不需要固定居中元素的宽高。

inline-block + vertical-align

/* 这里引用复用代码 */.outer::after {
content: ""; display: inline-block; vertical-align: middle; height: 100%;}.inner {
display: inline-block; vertical-align: middle;}

该方案的原理是:在居中元素的父元素上,使用一个伪元素,将这个伪元素设置为 inline-block 后,就好像它原来就是一个真正的 DOM 元素,存在于页面上。然后再将居中元素设置为 inline-block,根据 inline-block 的特性(多个相邻的 inline-block 元素会横向并排显示),居中元素会和伪元素横向并排显示。并且设置 vertical-align: middle; 后,它们会互相垂直对齐,最后将伪元素高度撑起来,居中元素会对齐伪元素,从而实现了垂直居中。

优点:不需要固定居中元素的高。

该方案可配合水平居中的方案 2,实现水平垂直居中,如下所示:

/* 这里引用复用代码 */.outer {
text-align: center;}.outer::after {
content: ""; display: inline-block; vertical-align: middle; height: 100%;}.inner {
display: inline-block; vertical-align: middle; text-align: left; /* 重置文字位置(如果需要) */}

优点:不需要固定居中元素的宽高。

文章小结

本文介绍的方法中,除了 fit-content 方案和 Grid 方案兼容性较差,其他的方案都可以在实际项目中使用。每种方案都有其应用场景,应该根据实际业务灵活运用,而不是 Flex 一把梭。

转载地址:http://wtden.baihongyu.com/

你可能感兴趣的文章
为窗口添加鼠标HOVER和LEAVE事件
查看>>
VC小技巧20个
查看>>
MFC Feature Pack for Visual C++ 2008的BUG之一
查看>>
POJ - 2739 Sum of Consecutive Prime Numbers
查看>>
STL map映照容器(一)map创建、元素插入、元素删除和遍历访问
查看>>
Leetcode - 557反转字符串中的单词III
查看>>
Leetcode - 160相交链表
查看>>
Leetcode - 11盛最多水的容器
查看>>
Leetcode - 141环形链表
查看>>
Leetcode - 14最长公共前缀
查看>>
Leetcode - 7整数反转
查看>>
PAT---B1022. D进制的A+B (20)
查看>>
PAT---B1037. 在霍格沃茨找零钱(20)
查看>>
PAT---A1019. General Palindromic Number (20)
查看>>
PAT---A1027. Colors in Mars (20)
查看>>
PAT---1058. A+B in Hogwarts (20)
查看>>
PAT---A1001. A+B Format (20)
查看>>
PAT---A1005. Spell It Right (20)
查看>>
PAT---A1035. Password (20)
查看>>
PAT---A1077. Kuchiguse (20)
查看>>