CSS 居中?来一探究竟

个人博客原文: https://wzb.me/posts/2019/10/28/css-centering.html

「居中」是进行布局时最多见的需求之一了。CSS 有多种居中的方式,在何时挑选适合的方案?是一个值得思考的问题。css

法律声明

警告:本做品遵循 署名-非商业性使用-禁止演绎 4.0 未本地化版本(CC BY-NC-ND 4.0) 协议发布。你应该明白与本文有关的一切行为都应该遵循此协议。html

这是什么?

写在前面

本文将会按照具体场景来选择相应的居中方式,帮助你系统地理清 CSS 居中。css3

注意:为了简洁,文中给出的 CSS 代码只会给出关键的定义布局的代码。浏览器

在水平方向上的居中(Horizontally Centering)

对于行内(inline / inline-* )元素

要将行内元素居中,只须要给其父块级元素(block-level parent element)定义如下 CSS 规则:ide

.block-level-parent-of-inline-element {
  text-align: center;
}

centering-inline-element

这对 inline inline-block inline-table inline-flex etc. 都生效

text-align 不单单是针对于 text 的对齐描述,实际上,它影响的是块级元素下的行内元素与文本(inline contents)。布局

参考: text-align - CSS | MDN

对于块级元素(block element)

要将块级元素居中,给其定宽(width)以后定义如下 CSS 规则post

.block-element {
  margin: 0 auto;
}

css-centering-block-element

若是没有给定块级元素宽度?那它会充满整行,以致于不须要居中了... 🔨flex

就像这样ui

full-witdh

若是有多个块级元素?

若是你想将多个块级元素在水平方向上居中,有如下两种方法。spa

  • 将多个块级元素设置 display: inline-box; 而后给父级元素定义 text-align: center;(与上文的行内元素居中同理)
.parent {
  text-align: center;
}
.block-elements {
  display: inline-block;
}

inline-blocks-centering

  • 使用 Flexbox
.parent {
  display: flex;
  justify-content: center;
}

centering-blocks-in-flex

在竖直方向上的居中(Vertically Centering)

对于行内(inline / inline-* )元素

好比文字(text)和连接(links)

只有一行时

  • 要让行内元素/文字看起来在竖直方向上的中间,能够给其定义上下相等的内边距(padding)
a {
  padding-top: 20px;
  padding-bottom: 20px;
}

centering-links

  • 还有一种方案是,将文字的行高值设置与其元素高度相同。
.box {
  height: 60px;
  line-height: 60px;
}

centering-a-line

仔细思考,若是文字的内容超过一行,或者是父级元素的大小在响应式变化的状况下变小致使文字须要换行,会出现这样的状况。

lines-wraps

解决这个问题,只须要设置文字不换行便可

.box {
  height: 60px;
  line-height: 60px;
  white-space: nowarp;
}

lines-center-no-wrap

有多行文字时

  • 一样的,能够给元素设置上下相等的 padding,让文字看起来在中间
  • 将父元素定义为 display: table; 同时将子元素设置为 display: tabel-cell; 而且给予 vertical-align: middle; 属性。
.box {
  display: table;
  height: 60px;
}

.box p {
  display: table-cell;
  vertical-align: middle;
}
  • 使用 Flexbox 居中

将文字放在块级元素中,给其父元素使用 Flex

.box {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

以上效果相同,以下图。

muti-lines-centering

对于块级(block)元素

已经肯定块级元素的高度

在实际状况下,不多会明确地肯定某一个元素的高度。若是真的可以肯定某个元素的高度,可使用下面的方法。

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  height: 100px;
  margin-top: -50px;
}

这里须要注意的是 top 属性的计算方法,能够参考 CSS - top | MDN

centerring-position-block

不能肯定块级元素的高度

咱们仍可使用与上例相似的方法,不过须要使用 transform 属性。

.parent {
  position: relative;
}
.box {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}
对于 translate 的计算方式,能够参考 Is the CSS3 transform translate percentage values relative to its width and/or height? - Stack Overflow

若是你不在意元素撑大的话

你不在意元素是否撑开,只想要它的内容竖直居中,可使用 table 或者是 CSS display 将其变成 table 行为。

main {
  padding: 5px;
  display: table;
}
main div {
  display: table-cell;
  vertical-align: middle;
}

table-vertical-centering

可见,元素被撑大了。🔨

Flexbox

使用 Flexbox 在竖直方向上居中是一样的方便。

.parent {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

flex-vertical-center

水平和竖直方向上同时居中

你能够将上面的方法结合使用达到此目的。不过这里总结了几种比较方便的方式。

元素肯定了高度和宽度时

使用绝对定位以后,设置为负的margin属性,其值等于 高度/宽度 的50%。

.parent {
  position: relative;
}

.child {
    height: 60px;
    width: 180px;

    position: absolute;
    top: 50%;
    left: 50%;

    margin: -30px 0 0 -90px;
}

centering-positon-nagetive

这样进行居中的浏览器兼容性很是好。

不肯定元素高宽

与上例相同,使用绝对定位,不过换成了 translate 属性。

.parent {
  position: relative;
}

.child {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

unknow-height-width-centering

Flexbox

相信你已经想到了 Flexbox 如何实现,只须要把主轴和侧轴方向上都设置为居中就行了。

.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

flex-centerring

Gird

对于居中一个元素来讲,可使用 Gird 的 trick。

.parent {
  display: grid;
}
.parent div {
  margin: auto;
}

flex-centerring

写在最后

如今你对居中的方法与选择有了清楚的认识,你不再怕居中了。XD

References

相关文章
相关标签/搜索