文章目录
- 行内或类行内元素
- 单行
- 示例
- 示例2
- 多行
- 示例1
- 示例2
- 示例3
- 块级元素
- 已知元素的高度
- 示例
- 未知元素的高度
- 示例
- flexbox
- 示例
行内或类行内元素
例如:文本和链接等。
单行
- case1
对于单行行内或者文本元素,只需为它们添加等值的 padding-top
和 padding-bottom
(或者上下margin)就可以实现垂直居中:
.link {
padding-top: 30px;
padding-bottom: 30px;
}
上面的情况是父元素高度未设置的情况,使用margin或padding的目的就是使其高度撑开,让子元素位于中部。
- case2
如果已知文本不会换行,那么还可以让 line-height
和 center
相等,从而实现垂直居中。
.center-text-trick {
height: 100px;
line-height: 100px;
white-space: nowrap;
}
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
background: #f06d06;
font-size: 80%;
}
main {
background: white;
margin: 20px 0;
padding: 50px;
}
main a {
border: 2px solid black;
background: yellow;
color: black;
padding: 40px 40px;
/*margin: 40px 40px;*/
text-decoration: none;
}
</style>
</head>
<body>
<main>
<p>
<a href="#0">We're</a>
<a href="#0">Centered</a>
<a href="#0">Bits of</a>
<a href="#0">Text</a>
</p>
</main>
</body>
</html>
示例2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
background: #f06d06;
font-size: 80%;
}
main {
background: white;
margin: 20px 0;
padding: 40px;
}
main div {
border: 2px solid black;
background: yellowgreen;
color: white;
height: 100px;
line-height: 100px;
/*padding: 20px;*/
width: 50%;
white-space: nowrap;
}
</style>
</head>
<body>
<main>
<div>
测试测试测试测试测试测试测试测试测试
</div>
</main>
</body>
</html>
多行
-
对于多行文本,同样可以使用等值
padding-top
和padding-bottom
的方式实现垂直居中。 -
还可以通过 CSS 为文本设置一个类似
table-cell
的父级容器,然后使用vertical-align
属性实现垂直居中。即,使用table的vertical-align属性实现垂直居中。 -
值得注意的是,上述方法只适用于父级容器拥有确定高度的元素。
-
此外,还可以使用
flexbox
实现垂直居中,对于父级容器为display: flex
的元素来说,它的每一个子元素都是垂直居中的:.flex-center-vertically { display: flex; justify-content: center; flex-direction: column; height: 400px; }
-
还可使用被称为
幽灵元素(ghost element)
的非常规解决方式:在垂直居中的元素上添加伪元素,设置伪元素的高等于父级容器的高,然后为文本添加vertical-align: middle;
样式,即可实现垂直居中。
.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;
}
示例1
通过table的vertical-align实现。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
table {
width: 240px;
border-collapse: separate;
margin: 20px;
height: 250px;
}
table td {
background: yellow;
color: black;
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: yellow;
color: black;
/*padding: 20px;*/
border: 10px solid white;
vertical-align: middle;
}
</style>
</head>
<body>
<table>
<tr>
<td>
测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试
</td>
</tr>
</table>
<div class="center-table">
<p>测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试</p>
</div>
</body>
</html>
示例2
使用flex布局。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
main {
background: yellow;
width: 100%;
/*margin: 20px;*/
}
.flex-center {
width: 300px;
height: 200px;
background: yellow;
color: black;
border:2px solid black;
/*核心 flex */
display: flex;
flex-direction: column;
justify-content: center;
/*resize 属性规定是否可由用户调整元素尺寸。*/
resize: both;
overflow: auto;
}
.flex-center p {
margin: 0;
padding: 20px;
}
</style>
</head>
<body>
<main class="flex-center">
<p>测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试</p>
</main>
</body>
</html>
可以看到,无论是单行还是多行,width和height如何改变,文本都始终位于中部。
示例3
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div {
border: 2px solid black;
background: yellow;
width: 240px;
height: 200px;
margin: 20px;
color: black;
resize: vertical;
overflow: auto;
padding: 20px;
}
.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;
width: 190px;
margin: 0;
padding: 20px;
background: burlywood;
}
</style>
</head>
<body>
<div class="ghost-center">
<p>
测试测试测试测试测试测试测试测试测试测试测试测试测
</p>
</div>
</body>
</html>
块级元素
已知元素的高度
无法获知元素的具体高度是非常常见的一种状况,比如:视区宽度变化,会触发布局重绘,从而改变高度;对文本施加不同的样式会改变高度;文本的内容量不同会改变高度;当宽度变化时,对于宽高比例固定的元素(比如图片),也会自动调整高度……
如果我们知道元素的高度,可以这样来实现垂直居中:
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
height: 100px;
margin-top: -50px;
}
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
main {
background: yellow;
height: 400px;
width: 400px;
margin: 20px;
position: relative;
/* 可拖拽调整大小 */
resize: vertical;
overflow: auto;
}
main div {
position: absolute;
left: 0;
background: greenyellow;
color: black;
border: 2px solid black;
/* 核心 */
top: 50%;
height: 100px;
margin-top: -50px;
}
</style>
</head>
<body>
<main>
<div>
测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试
</div>
</main>
</body>
</html>
未知元素的高度
transform 属性是css3的特性,即向元素应用 2D 或 3D 转换。该属性允许我们对元素进行旋转、缩放、移动或倾斜。
如果不知道元素的高度,那么就需要先将元素定位到容器的中心位置,然后使用 transform
的 translate
属性,将元素的中心和父容器的中心重合,从而实现垂直居中。
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
main {
background: greenyellow;
height: 300px;
margin: 20px;
width: 300px;
position: relative;
border: 2px solid black;
resize: vertical;
overflow: auto;
}
main div {
position: absolute;
top: 50%;
left: 20px;
right: 20px;
background: black;
color: white;
padding: 20px;
transform: translateY(-50%);
resize: vertical;
overflow: auto;
}
</style>
</head>
<body>
<main>
<div>
测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试
</div>
</main>
</body>
</html>
无论如何拖拽改变父盒子高度,子盒子都始终处于中间。
使用 transform
有一个缺陷,就是当计算结果含有小数时(比如 0.5
),会让整个元素看起来是模糊的,一种解决方案就是为父级元素设置 transform-style: preserve-3d;
样式:
.parent-element {
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.element {
position: relative;
top: 50%;
transform: translateY(-50%);
}
flexbox
使用 flexbox 实现水平和垂直居中,只需使用两条居中属性即可:
.parent {
display: flex;
justify-content: center;
align-items: center;
}
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
main {
background: yellow;
height: 200px;
width: 60%;
border: 2px solid black;
margin: 0 auto;
/*核心*/
display: flex;
/*垂直居中,针对的是main的子元素,不包含“孙子”元素*/
align-items: center;
/*水平居中,针对的是main的子元素,不包含“孙子”元素*/
justify-content: center;
/*拖拽改变宽高*/
resize: both;
overflow: auto;
}
main div {
border: 2px solid black;
background: green;
color: black;
width: 30%;
margin-right: 20px ;
/*拖拽改变宽高*/
resize: both;
overflow: auto;
}
</style>
</head>
<body>
<main>
<div>
测试测试测试测试测试测试测试测试测
试测试测试测试测试测试测试测试测试测试测试测试测试测
试测试测试测试测试测试测试测试测试测试测试测试测试测试测试
测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试
</div>
<div>
测试测试测试测试测试测试测试测试测
试测试测试测试测试测试测试测试测试测试测试测试测试测
试测试测试测试测试测试测试测试测试测试测试测试测试测试测试
测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试
</div>
</main>
</body>
</html>
如图,无论如何拖拽,它们都是水平垂直居中的。关于flex更多详情,可点击这里查阅。