翻译自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;
}
结论
你现在可以在任何情况下实现元素居中了。
翻译自centering-css-complete-guide
居中是人们对css抱怨的最多的问题之一。它为什么这么难?要吃人。我认为问题并不在居中很难,而是在于在各种情况下要采取不同的方案去实现,合适的使用才是关键。
所以,让我们画一个决定树去尝试让居中变得容易一点。
我需要在这种情况下实现居中...
水平居中
是否为行内元素(inline 或者 inline-*)?
在块级父元素中对行内元素居中,可以使用下面的方法
这种方法对于inline,inline-block,inline-table,inline-flex等等都适用。
是否为块级元素(inline 或者 inline-*)?
要让块级元素居中,可以设置margin-left和margin-right为auto(而且必须设置width,不然这个元素就是全宽的,不需要居中)。看下面的代码:
这样无论在什么宽度的宽级元素或者父元素中都可以实现居中。
注意:你不能使用float让元素居中。但是有一个特殊方法
是否有多个块级元素?
如果存在多个块级元素在同一行居中,更好的选择可能是使用另外一种display类型。下面是将块级元素设置为inline-block和使用flexbox居中的案例:
垂直居中
垂直居中在css中有点棘手。
是否为行内元素
是否为单行的行内元素
有些情况下行内元素/文字能够垂直居中是因为它们的上面和下面填充了一样的padding
如果在某些情况下不能使用padding,那么对于不换行的元素,有个技巧就是设定line-height和height一样,内容就会居中。
是否为多行的行内元素
给元素的顶部和底部赋予相同的padding也能让多行文字居中,但是如果这样行不通的话,可能是文字所在的元素是table内,或者css设置的display:table内。在这种情况下,就要用到vertical-align属性了,这种方法和通常的垂直居中方式不太一样。
如果用不了table这样子的方式,或许可以试试用flexbox?flex内部的子元素可以轻松的居中。
注意这种情况只在父元素有指定的高度时才会生效。
如果上面的所有方法都不行,你还可以尝试“伪类”的黑科技,将一个全高的伪类元素放在容器中并且垂直居中。 具体实现原理是怎么样的?
是否为块级元素
元素的高度是否确定
在web页面布局中,不知道元素的高度的情况是很常见的,有很多原因:如果宽度发生改变,文本流可能会改变高度。文本样式的变化也会改变高度。文本数量的变化也可以改变高度。具有固定宽高比的元素,比如图像,在调整大小时会改变高度。等等情况。
但是如果你可以确定高度,你可以用如下方式实现垂直居中:
不知道元素的高度
仍然可以把元素放到50%高度然后上升自身的50%以居中:
能不能使用flexbox
没啥大惊小怪,在flexbox里面很容易就可以实现。
水平垂直居中
你可以以任意方式结合上面的技巧来实现完美居中的元素。但是我发现大致可以分为以下几种情况:
元素的宽高是否确定
在绝对定位和设置50%/50%后设置宽高的一半的负margin可以获得兼容性极好的居中:
元素的宽高无法确定
如果不确定元素的宽高,可以使用transform属性和50%的负translate来设置居中:
flexbox
flexbox里要实现居中,只用同时使用两个居中属性
grid
这是一个小技巧对于单个元素比较有效:
结论
你现在可以在任何情况下实现元素居中了。