关于居中(一)

元素居中是css中人们经常抱怨的一个问题,为什么它如此困难?个人认为原因不是他难,而是不同情况有不同的实现方法,我们很难知道具体用哪种。所以,让我们做一个选择树希望能让他变简单一点。

我需要居中….

1.水平居中

1.1 它是内联元素(inline block,例如文本或链接)

你可以直接让它在块级父元素内居中,例如

1
2
3
.center-children {
text-aligin: center;
}

这可以用于 有inline,inline-block, inline-table, inline-flex,等属性的元素上.

1.2 它是块级元素(block)

你可以将该元素的margin-leftmargin-right属性设置为aoto(需要为其设置宽度,否则可能占满整行不需要居中),通常简单的记成

1
2
3
.center-me {
margin: 0 auto;
}

对于一个固定了宽度的块级元素或者其父元素这样使用都没什么问题。
对了,我们不能去居中一个浮动(float)的元素。这里也提供一片文章使用CSS伪元素模拟float:center效果

1.3 超过一个的块级元素

如果你有两个或者更多的块级元素需要被水平居中,那么你最好改变他们的display属性,这里有一个例子是将其设为inline-blockflex的:

除非你是多个块级元素层层叠加在一起的,在这种情况下使用margin:auto;的方法仍然行得通:


2.垂直居中

垂直居中在css中有一点点难办。

2.1 它是内联元素(inline或者inline-*)

2.1.1 只有一行

一些 内联/文本(inline/text) 元素能垂直居中仅仅是因为他们有相同的上下内边距(padding)

1
2
3
4
.link {
padding-top: 30px;
padding-bottom: 30px;
}

如果出于某些原因你不能去操作padding,并且你知道你将要操作的元素不会换行,这里有一个小小的技巧就是让他的line-heightheight相同,这样就可以达到你想要的效果了

1
2
3
4
5
.center-text-trick {
height: 100px;
line-height: 100px;
white-space: nowrap;
}

2.1.2多行

相同的padding-toppadding-bottom能够使它垂直居中,然而或许因为元素处于表格单元中(无论表面上或者用css属性),以上方法行不通。这时vertival-align就可以解决这个问题,它不会只像普通的元素垂直居中一行。 (更多)

如果不是表状的元素,或许你需要使用flexbox。一个单独的flex的子元素能很轻松的被flex的父元素居中。

1
2
3
4
5
6
.flex-center-vertically {
display: flex;
justify-content: center;
flex-direction: column;
height: 400px;
}


需要注意的是只有当元素的父容器的高度是固定的时候(px,%,等等)它才有效,这也是为什么以上案例有给定高度。

如果以上方法都行不通,你可以使用“幽灵元素”这个技术,放一个满高度的伪元素在容器里面从而使文本垂直居中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
.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;
}



2.2它是块级元素

2.2.1知道元素的高度

通常我们不知道网页布局的高度有几个原因:如果宽度改变,文本流的高度也会跟着改变;文本样式会改变高度;文本数量的差异会改变高度;具有固定长高比的元素会改变高度(例如图片)等等。
但是如果你知道元素的高度,你可以像以下方法居中它。

1
2
3
4
5
6
7
8
9
10
.parent {
position: relative;
}

.child {
position: absolute;
top: 50%;
height: 100px;
margin-top: -50px;
/* 高度除以2,如果没有使用box-sizing: border-box;要计算上border和padding */
}

2.2.2不知道元素的高度

我们仍然可能在它原始高度上将它向上拉一半的高度。

1
2
3
4
5
6
7
8
.parent {
position: relative;
}

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


这里我个人补充一些小问题:
1. 如果要考虑兼容,记得对transform加上浏览器引擎前缀。
2. 有人指出,使用这种方法,元素在沿translateY移动时会损失“半个像素”,导致元素模糊。解决的方法是对其父元素使用preserve-3d属性。
1
2
3
4
.parent {
position: relative;
-webkit-transform-style: preserve-3d;
}



#### 2.2.3能使用flexbox吗

没什么好惊奇,如果可以使用flexbox这会简单很多。
1
2
3
4
5
.parent {
display: flex;
flex-direction: column;
justify-content: center;
}




3.水平垂直居中

你可以随意结合以上的技术来完美居中你所想的元素。这里我们通常分为三种情况:

3.1 元素固定高度和宽度

在你使用绝对定位并向做和向下移动的50%之后,使用负的内边距(padding)使其数值等于一半的宽度和高度,这样的居中方式大多浏览器都兼容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.parent {
position: relative;
}


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

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

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

3.2 元素不确定高度和宽度

如果你不知道它的宽度或高度,您可以使用translate属性,对两个方向都设置负50%的translate属性(基于当前元素的宽度/高度为)从而让它居中:

1
2
3
4
5
6
7
8
9
.parent {
position: relative;
}

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

3.3 能使用flexbox

用flexbox要水平和垂直都居中的话,您需要用两个居中的属性。(justify-content, align-items)

1
2
3
4
5
.parent {
display: flex;
justify-content: center;
align-items: center;
}

4.总之

恭喜你看到了这里,你现在应该可以用css居中你想居中的东西了(撒花)

翻译自 https://css-tricks.com/centering-css-complete-guide/