引言
说实话像垂直、水平居中问题这种问题有很多的方法,可能十几种都不止。但是从实际的角度出发,将这么多方法都记下来不现实。因此我在这里给大家分享一下,解决垂直、水平居中问题的三条思路:绝对定位,Flex 布局、table 布局。
初始代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>垂直水平居中问题</title>
<style>
.container{
width: 200px;
height: 200px;
background-color: green;
border: 1px solid #000;
}
.center{
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<div class="container">
<div class="center">子元素</div>
</div>
</body>
</html>
初始页面效果:
绝对定位
在绝对定位这条思路上分为:知道子元素宽高、不知道子元素宽高两种。
已知子元素宽高
margin 负值
首先给子元素添加相对于父元素的绝对定位,并设置top: 50%、left: 50% 使子元素左上顶点垂直水平居中。
/* 父元素 */
.container{
position: relative;
width: 200px;
height: 200px;
background-color: green;
border: 1px solid #000;
}
/* 子元素 */
.center{
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
background-color: red;
}
在子元素上添加margin-top: 负高度的一半距离、margin-left:负宽度的一半距离;
.center{
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
margin-top:-50px;
margin-left:-50px;
background-color: red;
}
注意
margin:负值; 不可以用百分比表示。
/* 子元素 */
.center{
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
margin-top:-50%;
margin-left:-50%;
background-color: red;
}
这也就是必须已知宽高的重要原因。
margin: auto
使用margin: auto,利用块状元素的流体特性解决垂直、水平居中问题。
块状元素的流体特性:
块状水平元素在默认情况下(非浮动、绝对定位等),内容区域会随着margin,padding,border的出现自动填满剩余空间。
我们可以给水平/垂直方向的对立定位(left、right、top、bottom)各设定一个值,然后将水平/垂直方向的 margin 均设为 auto,这样auto就会自动平分父元素的剩余空间。
恢复初始代码,给子元素添加相对于父元素的绝对定位,并设置top、bottom、left、right为 0; 结合 margin: auto; 实现子元素的垂直水平居中。
/* 子元素 */
.center{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
width: 100px;
height: 100px;
background-color: red;
}
注意
这里的 left、right、top、bottom 的值其实没有实际的大小描述意义。我们只要确认其存在性就行,不是 0也可以激发其流体特性。
未知子元素宽高
虽然这里说的是未知子元素宽高的垂直、水平居中方法,但在已知子元素宽高的情况下也可以使用。
transform
恢复初始代码,给子元素添加相对于父元素的绝对定位,并设置top: 50%、left: 50% 使子元素左上顶点垂直水平居中。
这一步和margin 负值方法相同。
/* 父元素 */
.container{
position: relative;
width: 200px;
height: 200px;
background-color: green;
border: 1px solid #000;
}
/* 子元素 */
.center{
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
background-color: red;
}
不同的是这一步,由于不知道子元素的宽高,所以使用transform: translate(-50%, -50%); 通过平移实现子元素的垂直、水平居中。
/* 子元素 */
.center{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 100px;
height: 100px;
background-color: red;
}
Flex 布局
使用 flex 布局,问题就简单多了。不论是否知道子元素宽高,Flex 布局都能搞定。
首先将代码恢复到初始状态,将父元素设置成Flex 布局,设置主轴的元素排列、设置交叉轴的元素排列为center(居中排列)。
/* 父元素 */
.container{
display: flex;
justify-content: center;
align-items: center;
width: 200px;
height: 200px;
background-color: green;
border: 1px solid #000;
}
table 布局
table 布局是一种历史悠久的布局方式。虽然现在大家都不怎么使用 table 布局了,但是 table 布局兼容性好,一部分团队仍然对它表示难舍难分。
display属性 | 描述 |
---|---|
table | 此元素会作为块级表格来显示 |
table-row-group | 此元素会作为一个或多个行的分组来显示 |
table-header-group | 此元素会作为一个或多个行的分组来显示 |
table-footer-group | 此元素会作为一个或多个行的分组来显示 |
table-row | 此元素会作为一个表格行显示 |
table-column-group | 此元素会作为一个或多个列的分组来显示 |
table-column | 此元素会作为一个单元格列显示 |
table-cell | 此元素会作为一个表格单元格显示 |
table-caption | 此元素会作为一个表格标题显示 |
首先恢复初始代码,将父元素设置为display: table-cell,然后使用vertical-align 垂直居中,text-align 水平居中。
然后将子元素的布局设为 inline-block( table-cell 只能处理具备行内特性的元素布局)。
/* 父元素 */
.container{
display: table-cell;
text-align: center;
vertical-align: middle;
width: 200px;
height: 200px;
background-color: green;
border: 1px solid #000;
}
/* 子元素 */
.center{
display: inline-block;
background-color: red;
}
总结
通过绝对定位、Flex 布局、table 布局三条思路解决垂直、水平居中问题的三条思路。
-
绝对定位
- 已知子元素宽高
- margin 负值:相对父元素绝对定位,设置top: 50%、left: 50%,结合margin 负值实现垂直、水平居中;
- margin: auto:相对父元素绝对定位,设置top、bottom、left、right为 0结合 margin: auto;*实现子元素的垂直水平居中;
- 未知子元素宽高
- transform:相对父元素绝对定位,设置top: 50%、left: 50%,结合transform: translate(-50%, -50%);** 实现子元素的垂直、水平居中;
- 已知子元素宽高
-
Flex 布局:父元素Flex 布局,设置主轴、交叉轴的元素排列为center(居中排列);
-
table 布局:父元素display: table-cell,使用vertical-align 垂直居中,text-align 水平居中,子元素布局设为 inline-block;
(完)