在实现居中之前我们肯定要先看一下当前元素的display属性,是块级元素还是内联元素,因为块级元素和内联元素的水平居中方式是不一样的,下面我们就按照这两类进行元素分类,按照水平居中和垂直居中来进行介绍。
-
水平居中
1)内联元素,也包括文本
- text-align: center;
2) 块级元素
- 设置margin: 0 auto;
- 绝对定位:position: absolute; left: 50%; 设置外边距margin-left回退
- 绝对定位:position: absolute; left: 50%; 设置transform回退
- 弹性布局:flex; align-items: center;
-
垂直居中
1)内联元素(display: inline-block):vertical-align: middle;
2)单行文本:line-height = height;
3)块级元素
- 父元素display: table; 子元素display: table-cell; verticle-align: middle;
- 绝对定位:position: absolute; top: 50%; 设置外边距margin-top回退
- 绝对定位:position: absolute; top: 50%; 设置transform回退
- 弹性布局:flex; justify-content: center;
水平居中
text-align
tetx-align属性指定块级元素中的内联元素(包括display: inline-block;)的对齐方式。只要设置了该属性值,那么里面的内联元素就会水平对齐,而且这个属性还可以级联,在父元素上使用text-align,其下的所有的块级子元素(包括:display: inline-block;)都具有该属性。
让内联元素水平居中
<div class='test-wrap'>
<!-- 居中布局 -->
<span class="inline-box">这是一行单行文本</span>
</div>
.test-wrap {
text-align: center;
.inline-box {
border: 1px solid lightgreen;
}
}
效果如下:
文本内容水平居中
<div class='test-wrap'>
这是一段很长很长的文本
</div>
.test-wrap {
text-align: center;
}
margin
margin这个主要是用来控制块级元素水平居中的。因为块级元素默认是占满一整行的,如果该块级元素不设置宽度的话,那么width: auto;但是在浏览器中的表现是占满一整行的,其实也就是100%。如果该元素有指定宽度。那么设置 margin:0 auto; 就意味着水平方向上的外边距都是auto, 浏览器上的表现就是左右外边距是一样的,也就是水平居中了。
<div class='test-wrap'>
<!-- 居中布局 -->
<div class="inline-box">
这是一段块级元素内的文本内容
</div>
</div>
.test-wrap {
.inline-box {
border: 1px solid lightgreen;
width: 100px;
height: 100px;
margin: 0 auto;
}
}
绝对定位
绝对定位实现水平居中的原理很简单,因为绝对定位是脱离文档流的,其实就是根据父元素,让子元素定位在那个水平居中的位置。 绝对定位实现水平居中的方式是一样的,只是最后回退的时候采用的方式不同
position + margin
<div class='test-wrap'>
<!-- 居中布局 -->
<div class="inline-box">
这是一段块级元素内的文本内容
</div>
</div>
.test-wrap {
position: relative;
.inline-box {
border: 1px solid lightgreen;
width: 100px;
height: 100px;
position: absolute;
left: 50%;
margin-left: -50px;
}
}
效果如下: 这种方式必须知道元素的宽度
position + transform
<div class='test-wrap'>
<!-- 居中布局 -->
<div class="inline-box">
这是一段块级元素内的文本内容
</div>
</div>
.test-wrap {
position: relative;
.inline-box {
border: 1px solid lightgreen;
width: 100px;
height: 100px;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
}
效果如下: 这种方式元素的宽度是不是固定值都不影响
弹性布局
弹性布局是最简单的实现水平居中的方式,也是最适合用来做居中的布局了,而且现在基本上主流浏览器都能支持flex属性了,如果项目对浏览器有特殊要求,不支持flex布局的,我们可以针对性地进行兼容处理。而且对于内联元素也可以使用flex布局进行水平居中(display: inline-flex;)
<div class='test-wrap'>
<!-- 居中布局 -->
<div class="inline-box">
这是一段块级元素内的文本内容
</div>
</div>
.test-wrap {
display: flex;
justify-content: center;
.inline-box {
border: 1px solid lightgreen;
width: 100px;
height: 100px;
}
}
效果如下:
垂直居中
vertical-align
vertical-align属性定义行内元素的基线相对于该元素所在行的基线的垂直对齐。
其中行内元素的基线并不是固定不变的。主要分为以下几种情况:
- 在文本类的内联元素中,基线就是字符x的下边缘位置
- 在img元素中基线就是下边缘
- 在inline-block元素中,也分为两种情况:
- 如果该元素中有内联元素,基线就是最后一行内联元素的基线
- 如果该元素内没有内联元素或者overflow不是visible,其基线就是margin的下边缘
vertical-align是针对行内元素的基线相对于该元素所在行的基线的垂直对齐,因此要想实现元素在父元素中垂直对齐,该元素必须是行内元素,否则就不生效。具体实现过程如下: 在父元素中添加一个文本x, 方便看出父元素的基线
<div class='test-wrap'>
<!-- 居中布局 -->
x<span class="inline-box">我是内联元素文本内容</span>
</div>
.test-wrap {
width: 400px;
height: 500px;
background-color: aliceblue;
.inline-box {
border: 1px solid lightgreen;
vertical-align: middle;
display: inline-block;
width: 200px;
height: 100px;
line-height: 100px;
}
}
效果如下:
此时行内元素确实是和x(基线)垂直对齐,但是我们想要的效果是行内元素在父元素中垂直对齐,因此需要在父元素中设置一个line-height = height。这样x就是在父元素中垂直对齐,行内元素也就在父元素中垂直居中啦。
<div class='test-wrap'>
<!-- 居中布局 -->
x<span class="inline-box">我是内联元素文本内容</span>
</div>
.test-wrap {
width: 400px;
height: 500px;
background-color: aliceblue;
line-height: 500px;
.inline-box {
border: 1px solid lightgreen;
vertical-align: middle;
display: inline-block;
width: 200px;
height: 100px;
line-height: 100px;
}
}
效果如下:
line-height
line-height设置垂直居中只针对单行文本垂直居中于父容器,其他的情况都不使用。这个属性我们用的很多,但是从来都没有去考虑它的原理。之所以单行文本可以这样使用是因为line-height: 表示两个文本基线之间的距离,也等于文本的高度+上间距+下间距。行高-字体的大小得到的差值就是被平均分成两部分作为文本的间距。当行高和容器的高度相等就能实现垂直居中了
<span class="inline-box">我是内联元素文本内容</span>
.inline-box {
border: 1px solid lightgreen;
display: inline-block;
width: 200px;
height: 100px;
line-height: 100px;
}
效果如下
table布局
display:table-cell;会使元素表现的类似一个表格中的单元格td,利用这个特性可以实现文字的垂直居中效果。
<div class='test-wrap'>
<!-- 居中布局 -->
<span class="inline-box">我是内联元素文本内容</span>
</div>
.test-wrap {
width: 400px;
height: 500px;
background-color: aliceblue;
display: table;
.inline-box {
border: 1px solid lightgreen;
display: table-cell;
}
}
效果如下:
只要设置了display: table-cell属性它的vertical-align舒心默认就是middle, 所以这个属性设不设置都无所谓。
让行内元素或块级元素在父容器中垂直居中
<div class='test-wrap'>
<!-- 居中布局 -->
<span class="inline-box">我是内联元素文本内容</span>
</div>
.test-wrap {
width: 400px;
height: 500px;
background-color: aliceblue;
display: table-cell;
.inline-box {
border: 1px solid lightgreen;
}
}
效果如下:
这种方式可以实现垂直居中,但是有个问题就是容器元素必须是display: table-cell;否则就不生效。但是很多时候我们的容器元素就是一个块级元素,必须单独占一行,那么这种方式就不行了。
绝对定位
绝对定位实现垂直居中的方式和实现水平居中的原理是一样的,只是最后定位的时候位置不一样而已。
position + margin
<div class='test-wrap'>
<!-- 居中布局 -->
<div class="inline-box">我是内联元素文本内容</div>
</div>
.test-wrap {
width: 400px;
height: 500px;
background-color: aliceblue;
position: relative;
.inline-box {
height: 100px;
border: 1px solid lightgreen;
position: absolute;
top: 50%;
margin-top: -50px;
}
}
position + transform
<div class='test-wrap'>
<!-- 居中布局 -->
<div class="inline-box">我是内联元素文本内容</div>
</div>
.test-wrap {
width: 400px;
height: 500px;
background-color: aliceblue;
position: relative;
.inline-box {
height: 100px;
border: 1px solid lightgreen;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
}
弹性布局
弹性布局用来实现这种居中布局非常简单。
<div class='test-wrap'>
<!-- 居中布局 -->
<div class="inline-box">我是内联元素文本内容</div>
</div>
.test-wrap {
width: 400px;
height: 500px;
background-color: aliceblue;
display: flex;
align-items: center;
.inline-box {
height: 100px;
border: 1px solid lightgreen;
}
}
小结
在实现这种居中布局的时候,还是首选弹性布局的方式,因为弹性布局的诞生就是用来实现布局的。其他的布局方式或多或少地在某些场景都会存在些问题。