Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Centering in CSS: A Complete Guide(css居中方案完全指南) #8

Open
qppq54s opened this issue Apr 28, 2019 · 0 comments
Open

Comments

@qppq54s
Copy link
Owner

qppq54s commented Apr 28, 2019

翻译自centering-css-complete-guide

居中是人们对css抱怨的最多的问题之一。它为什么这么难?要吃人。我认为问题并不在居中很难,而是在于在各种情况下要采取不同的方案去实现,合适的使用才是关键。

所以,让我们画一个决定树去尝试让居中变得容易一点。

我需要在这种情况下实现居中...

水平居中

是否为行内元素(inline 或者 inline-*)?

在块级父元素中对行内元素居中,可以使用下面的方法

.center-children {
  text-align: center;
}

这种方法对于inline,inline-block,inline-table,inline-flex等等都适用。

是否为块级元素(inline 或者 inline-*)?

要让块级元素居中,可以设置margin-left和margin-right为auto(而且必须设置width,不然这个元素就是全宽的,不需要居中)。看下面的代码:

.center-me {
  width: 10px;
  margin: 0 auto;
}

这样无论在什么宽度的宽级元素或者父元素中都可以实现居中。
注意:你不能使用float让元素居中。但是有一个特殊方法

是否有多个块级元素?

如果存在多个块级元素在同一行居中,更好的选择可能是使用另外一种display类型。下面是将块级元素设置为inline-block和使用flexbox居中的案例:

.inline-block-center {
  text-align: center;
}
.inline-block-center div {
  display: inline-block;
  text-align: left;
}

.flex-center {
  display: flex;
  justify-content: center;
}

垂直居中

垂直居中在css中有点棘手。

是否为行内元素

是否为单行的行内元素

有些情况下行内元素/文字能够垂直居中是因为它们的上面和下面填充了一样的padding

.link {
  padding-top: 30px;
  padding-bottom: 30px;
}

如果在某些情况下不能使用padding,那么对于不换行的元素,有个技巧就是设定line-height和height一样,内容就会居中。

.center-text-trick {
  height: 100px;
  line-height: 100px;
  white-space: nowrap;
}

是否为多行的行内元素

给元素的顶部和底部赋予相同的padding也能让多行文字居中,但是如果这样行不通的话,可能是文字所在的元素是table内,或者css设置的display:table内。在这种情况下,就要用到vertical-align属性了,这种方法和通常的垂直居中方式不太一样。

<table>
  <tr>
    <td>
      I'm vertically centered multiple lines of text in a real table cell.
    </td>
  </tr>
</table>

<div class="center-table">
  <p>I'm vertically centered multiple lines of text in a CSS-created table layout.</p>
</div>


table {
  background: white;
  width: 240px;
  border-collapse: separate;
  margin: 20px;
  height: 250px;
}

table td {
  background: black;
  color: white;
  padding: 20px;
  border: 10px solid white;
  /* default is vertical-align: middle; */
}

.center-table {
  display: table;
  height: 250px;
  background: white;
  width: 240px;
  margin: 20px;
}
.center-table p {
  display: table-cell;
  margin: 0;
  background: black;
  color: white;
  padding: 20px;
  border: 10px solid white;
  vertical-align: middle;
}

如果用不了table这样子的方式,或许可以试试用flexbox?flex内部的子元素可以轻松的居中。

.flex-center-vertically {
  display: flex;
  justify-content: center;
  flex-direction: colum;
  height: 400px;
}

注意这种情况只在父元素有指定的高度时才会生效。

如果上面的所有方法都不行,你还可以尝试“伪类”的黑科技,将一个全高的伪类元素放在容器中并且垂直居中。 具体实现原理是怎么样的?

.ghost-center {
  position: relative;
}
.ghost-center::before {
  content: " ";
  display: inline-block;
  height: 100%;
  width: 1%;
  vertical-align: middle;
}
.ghost-center p {
  display: inline-block;
  vertical-align: middle;
}

是否为块级元素

元素的高度是否确定

在web页面布局中,不知道元素的高度的情况是很常见的,有很多原因:如果宽度发生改变,文本流可能会改变高度。文本样式的变化也会改变高度。文本数量的变化也可以改变高度。具有固定宽高比的元素,比如图像,在调整大小时会改变高度。等等情况。

但是如果你可以确定高度,你可以用如下方式实现垂直居中:

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  height: 100px;
  margin-top: -50px; /* 需要计算padding和border如果不是box-sizing: boder-box */
}

不知道元素的高度

仍然可以把元素放到50%高度然后上升自身的50%以居中:

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

能不能使用flexbox

没啥大惊小怪,在flexbox里面很容易就可以实现。

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

水平垂直居中

你可以以任意方式结合上面的技巧来实现完美居中的元素。但是我发现大致可以分为以下几种情况:

元素的宽高是否确定

在绝对定位和设置50%/50%后设置宽高的一半的负margin可以获得兼容性极好的居中:

.parent {
  position: relative;
}

.child {
  width: 300px;
  height: 100px;
  padding: 20px;

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

  margin: -70px 0 0 -170px;
}

元素的宽高无法确定

如果不确定元素的宽高,可以使用transform属性和50%的负translate来设置居中:

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

flexbox

flexbox里要实现居中,只用同时使用两个居中属性

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

grid

这是一个小技巧对于单个元素比较有效:

body, html {
  height: 100%;
  display: grid;
}
span { /* 居中的元素 */
  margin: auto;
}

结论

你现在可以在任何情况下实现元素居中了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant