定位居中方式应用场景速记
大纲链接 §
[toc]
居中方法简称 |
水平/垂直 |
行内/块级/* |
支持不固定宽高 |
触发*FC |
兼容性 |
vertical-align + inline-block |
垂直 |
行内文本 |
否 |
IFC |
全部 |
absolute + 负margin |
水平/垂直 |
块级 |
否 |
BFC |
全部 |
absolute + translate |
水平/垂直 |
块级 |
是 |
BFC |
全部 |
flex + margin |
水平/垂直 |
弹性 |
是 |
FFC |
全部 |
flex + jc + ai |
水平/垂直 |
弹性 |
是 |
FFC |
全部 |
grid + jc + ai |
水平/垂直 |
网格 |
否 |
GFC |
全部 |
flex /grid + place-item: center |
水平/垂直 |
弹性 /网格 |
否 |
IFC /GFC |
全部 |
FC CSS
格式化上下文(BFC,IFC,FFC和GFC)基本介绍
- Box 是 CSS 布局的对象和基本单位
- 元素类型和 display 属性,决定了这个 Box 的类型
- 不同类型的 Box, 会参与不同的
Formatting Context
(一个决定如何渲染文档的容器)
- Box 内的元素会以不同的方式渲染
- 格式化上下文(Formatting context)
- 是 W3C CSS2.1 规范中的一个概念
- 是页面中的一块渲染区域,并且有一套渲染规则
- 决定了其子元素将如何定位,以及和其他元素的关系和相互作用
- 格式化上下文主要包括四种类型:
Inline formatting context
(内联级格式上下文,简称IFC)
Block formatting context
(块级格式化上下文,简称BFC)
Flexible Formatting Context
(弹性盒格式化上下文,简称FFC)
Grids Formatting Context
(网格格式化上下文,简称GFC)
- 经过格式化上下的元素就是页面上的一个隔离的独立容器,一个独立的渲染区域,容器里面的子元素不会影响到外面的元素
一把梭 ⇧
日常只需看这里:
- 首先干掉浏览器默认样式(
margin:0;
)
- 使用居中判断 维度 与 流程
- 居中 一把梭
- 特殊问题处理
- 框架/库中的居中实现示例(
vue/react
)
关键字 ⇧
line-height
+ vertical-align: middle;
+ inline-block
文字
- 定位法
absolute
相关
absolute
+ margin
负值(推荐)
absolute
+ margin auto
(推荐)
absolute
+ translate
(推荐)
flex
相关
flex
+ align-items
(推荐)
flex
+ justify-content
(推荐)
flex
+ margin
(了解)
grid
相关
grid
+ align-items
(推荐)
grid
+ justify-content
(推荐)
- 超级居中
flex
或grid
+ place-items: center;
- 其他用法理解即可
line-height
文字居中
- 适用: 单行文字 的 垂直居中
- 设置在 行内元素 上
- 原理:将单行文字的行高设定后,文字会位于行高的垂直中间位置
- CSS语法:
normal | <number> | <length> | <percentage>
line-height: <*数字-倍数> | <长度-px> | <百分比> | normal
MDN line-height
推荐使用<*数字-倍数>
即无单位的值,以确保行高也会 等比例缩放
行内块line-height
+ vertical-align: middle;
+ inline-block
⇧
- 适用:多个行内元素 或 多行文字
- 设置在 单个包裹元素 上
- 原理:
- 将多个行内元素或多行文字当成 一个行元素 来看待
- 必须要将这些数据多包一层元素
div
,作为唯一子元素
- 并将显示属性设定为
display: inline-block;
行内盒
- 由于
inline-block
在不同浏览器会有空隙产生
- 还需要设定父元素
font-size:0;
来消除
vertical-align: middle;
,实现垂直居中
inline-block
形成BFC
,阻止默认父子元素margin
的合并,隔绝margin
inline-block
可改为 inline-*
,形成*FC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<div class="parent">
<div class="son">
超级好用
<a href="https://tinypng.com/" target="_blank">在线压缩图片</a>
<span>压缩完可以</span>
</div>
</div>
<style>
.parent {
width: 400px;
border: 10px solid rgba(50,50,50,.8);
line-height: 100px;
font-size: 0;
}
.parent .son {
display: inline-block;
border: 10px solid green;
line-height: 2;
vertical-align: middle;
width: 350px;
font-size: 16px;
background: #afddf3;
}
</style>
|
- 在文本节点外包一层 默认显示为行内元素的标签,配合使用
vertical-align: middle;
,就可以解决
1
2
3
4
5
6
7
|
<label class={cssCreateEdit.label} for="isShowAtIndex">
<span class={cssCreateEdit.labelText}>
是否展示到首页:
</span>
<Switch id="isShowAtIndex"
v-model:checked={this.atIndex}/>
</label>
|
1
2
3
4
5
6
7
8
|
.switch-box {
align-items: center;
display: flex;
margin: 15px 0;
}
.label .label-text {
vertical-align: middle;
}
|
伪元素::before + inline-block
脱裤子放屁的Hack
⇧
- 原理:
:before
伪元素搭配 inline-block
属性
- 父元素高度固定
- 子元素居中可以不需要特别设定高度
- 利用
:before
伪元素设定为 100%
高的 inline-block
- 将需要居中的子元素同样设置成
inline-block
- 使用
vertical-align: middle;
来达到垂直居中
- 设置父元素
font-size: 0;
,子元素font-size: 15px;
来理掉inline-block
元素之间的4-5px
空间这个小缺陷
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
.parent {
margin-top: 10px;
width: 400px;
height: 150px;
font-size: 0;
border: 1px solid #dcdcdc;
}
.parent::before {
content: '';
display: inline-block;
height: 100%;
width: 0;
vertical-align: middle;
}
.parent .son {
width: 300px;
font-size: 15px;
background: #afddf3;
display: inline-block;
vertical-align: middle;
}
|
table
相关使用较少
table + margin
使用较少 ⇧
- 适用情景:单对象(水平居中)
- 原理:将子元素设置块级表格,再设置水平居中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
.parent {
margin-top: 10px;
width: 400px;
height: 150px;
font-size: 0;
border: 1px solid #dcdcdc;
}
.parent .son {
display: table;
margin: 0 auto;
width: 300px;
font-size: 15px;
background: #afddf3;
}
|
变体 table + table-cell + vertical-align: middle;
使用较少 ⇧
1
2
3
4
5
6
7
8
9
10
|
<div class="example example5">
<div class="con">
超级好用超级放心
<a href="https://tinypng.com/" target="_blank">在线压缩图片</a>
<span>压缩完可以打包下载哦 </span>
</div>
<div class="con">
CSS-TRICKS
</div>
</div>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
.parent {
display: table;
margin-top: 10px;
width: 400px;
height: 150px;
font-size: 0;
border: 1px solid #dcdcdc;
}
.parent .son {
display: table-cell;
vertical-align: middle;
width: 300px;
font-size: 15px;
background: #afddf3;
}
|
定位法
absolute
+ margin
负值(了解即可) ⇧
- 原理:
- 设置子绝父相
- 子元素定位
top: 50%;
- 子元素再设置高度一半的
margin
负值
- 触发
BFC
- 缺陷:需要设置居中元素的高度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
.parent {
position: relative;
margin-top: 10px;
width: 400px;
height: 150px;
font-size: 0;
border: 1px solid #dcdcdc;
}
.parent .son {
position: absolute;
top: 50%;
height: 80px;
margin-top: -40px;
width: 300px;
font-size: 15px;
background: #afddf3;
}
|
absolute
+ margin: auto;
(了解即可) ⇧
-原理:
- 当元素设置为绝对定位后,脱离文档流,父元素不被撑起
- 子元素只设置
margin: auto;
会失效
- 还需要设置
top: 0; bottom: 0;
等,此时margin: auto;
就生效
- 缺陷:定位元素必须设定 固定宽高
- 上下左右四个方向定位属性要设置成一样的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
.parent {
position: relative;
margin-top: 10px;
width: 400px;
height: 150px;
font-size: 0;
border: 1px solid #dcdcdc;
}
.parent .son {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
height: 80px;
width: 300px;
font-size: 15px;
background: #afddf3;
}
|
absolute
+ translate
(推荐) ⇧
- 原理:
- 利用绝对定位时的
top
与 left
设置元素各为父元素尺寸的50%
- 再利用
transform: translate(-50%, -50%);
位移至该元素自身宽与高的50%
- 显著优势:无需指定 定位元素宽高
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
.parent {
position: relative;
width: 400px;
height: 150px;
font-size: 0;
border: 1px solid #dcdcdc;
margin-top: 10px;
}
.parent .son {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
font-size: 15px;
background: #afddf3;
}
|
flex
系列
flex
+ align-items
+ justify-content
(推荐) ⇧
- 适用情景:多行文字(垂直居中、 水平居中)
- 原理:弹性布局
justify-content
定义flex
子项在flex
容器在主轴(横轴)方向上的对齐方式
align-items
定义 flex
子项在flex
容器在侧轴(纵轴)方向上的对齐方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
.parent {
// 居中相关样式
display: flex;
justify-content: center;
align-items: center;
// 其他识别样式
margin-top: 10px;
width: 400px;
height: 150px;
font-size: 0;
border: 1px solid #dcdcdc;
}
.parent .son {
font-size: 15px;
background: #afddf3;
}
|
伪元素flex
+ ::before
+ flex-grow
(了解即可) ⇧
- 适用情景:多行文字(垂直居中)
- 原理:弹性布局
flex-direction:column;
将子项目垂直显示,如一个列一样
flex-grow: [number];
规定子项目将相对于其他灵活的项目进行扩展的量,撑满父元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
.parent {
display: flex;
flex-direction: column;
margin-top: 10px;
width: 400px;
height: 150px;
font-size: 0;
border: 1px solid #dcdcdc;
}
.parent::before {
content: '';
flex-grow: .5;
}
.parent .son {
font-size: 15px;
background: #afddf3;
}
|
flex + margin
(推荐) ⇧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
.parent {
display: flex;
margin-top: 10px;
width: 400px;
height: 150px;
font-size: 0;
border: 1px solid #dcdcdc;
}
.parent .son {
margin: auto;
width: 300px;
font-size: 15px;
background: #afddf3;
}
|
flex + align-self
⇧
- 原理:
align-self
定义flex
子项单独在侧轴(纵轴)方向上的对齐方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
.parent {
display: flex;
justify-content: center; // 水平
margin-top: 10px;
width: 400px;
height: 150px;
font-size: 0;
border: 1px solid #dcdcdc;
}
.parent .son {
align-self: center;
width: 300px;
font-size: 15px;
background: #afddf3;
}
|
flex + align-content
⇧
- 原理:
align-content
- 在弹性容器内的各项没有占用交叉轴上所有可用的空间时,对齐容器内的各项(垂直)
- 弹性项目有多项此属性才会发挥作用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
.parent {
display: flex;
align-content: center;
flex-wrap: wrap;
margin-top: 10px;
width: 400px;
height: 150px;
font-size: 0;
border: 1px solid #dcdcdc;
}
.parent::before, .parent::after {
content: "";
display: block;
width: 100%;
}
.parent .son {
height: 80px;
width: 300px;
font-size: 15px;
background: #afddf3;
}
|
不想让图片发生变形,并且不管尺寸大小均会显示在容器的正中央
- 实现宽度随着高度变动,锁定宽高比
aspect-ratio: 1/1;
1
2
3
4
5
6
7
8
9
10
11
|
<div class="img-box-container">
<div class="img-box">
<img src="imgs/avatar.jpeg" alt="">
</div>
<div class="img-box">
<img src="imgs/avatar.jpeg" alt="">
</div>
<div class="img-box">
<img src="imgs/avatar.jpeg" alt="">
</div>
</div>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
/* border-box */
.img-box-container {
display: flex;
justify-content: center;
}
.img-box {
position: relative;
width: 200px;
height: 200px;
background: #ebf8ed;
overflow: hidden;
}
.img-box img {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
max-width: 100%;
// max-height: 100%;
aspect-ratio: 1/1;
object-fit: contain;
}
|
适用于flex
和grid
的超级居中 ⇧
1
2
3
4
|
.parent {
display: grid;
place-items: center;
}
|
左右(水平)居中 ⇧
内联(行内)元素水平居中 ⇧
- 在父元素上设置
text-align: center;
实现 文本 / 链接 / 图片 水平居中
- 文字可用
<img>
标签代替,即 图片居中
- 文字折行
word-wrap: break-word;
- 常见的内联元素有:
span
, a
, img
, input
等等
1
2
3
4
5
6
7
8
9
10
11
12
|
/* 在父容器设置 */
.center-inline-parent{
text-align: center;
}
/* 在子容器块级元素需设置 */
.center-inline-child1{
display: inline;
}
.center-inline-child2{
display: inline-block;
}
|
- 利用
text-align: center;
可以实现在 块级元素内部 的 行内元素 水平居中
- 此方法对
inline
内联元素、inline-block
内联块、inline-table
内联表和inline-flex
元素 水平居中 都有效
- 如果 块级元素 内部包着也是一个块级元素,可以先将其由 块级元素 改变为 行内块元素,再通过设置 行内块元素 居中以达到水平居中
- 使用场景 文本的标题
- 原理:先将子元素由块级元素改变为行内块元素,再通过设置行内块元素居中以达到水平居中
- 用法:对父元素设置
text-align: center;
,对子元素设置display: inline-block;
1
2
3
4
5
6
7
8
9
10
11
12
|
<div class="parent">
<div class="child">Demo</div>
</div>
<style>
.parent{
text-align: center;
}
.child {
display: inline-block;
/* display: inline; */
}
</style>
|
- 优点:兼容性好,甚至可以兼容
ie6、ie7
- 缺点:
child
里的文字也会水平居中,可以在.child
添加text-align:left;
还原
块级元素水平居中 ⇧
- 常见的块元素:
div
、h1~h6
、 p
、 ul
、 li
、table
等等
图片元素的居中 ⇧
1
2
3
|
<div id='outer'>
<img src="xxx.png" >水平居中的图片</div>
</div>
|
1
2
3
4
5
6
|
img {
// 设置这三个属性,就可以居中
clear: both;
display: block;
margin: auto;
}
|
- 只能进行水平的居中,且对 浮动元素 或 绝对定位元素 无效
子元素定宽 margin
⇧
1
2
3
4
5
6
7
8
9
10
11
|
/* 上下顶格 */
.center-block {
margin: 0 auto;
}
/* 推荐 不带上下 margin */
.center-block {
width: 100px; // 确保该块级元素定宽
margin-left: auto;
margin-right: auto;
}
|
子元素定宽-display: table
布局 *使用较少 ⇧
使用 display: table + margin
1
2
3
|
<div class="parent">
<div class="child">Demo</div>
</div>
|
1
2
3
4
5
|
.child {
border: 1px solid red;
display: table;
margin: 0 auto;
}
|
- 将 子元素 设置为 块级表格 来显示,再将其设置水平居中
display: table + margin
在表现上类似 block
元素,但是宽度为内容宽
- 不定宽
子元素定宽-使用flex + justify-content
⇧
1
2
3
|
<div class="parent">
<div class="child">Demo</div>
</div>
|
1
2
3
4
|
.parent {
display: flex;
justify-content: center;
}
|
子元素定宽-使用flex + margin
⇧
1
2
3
|
<div class="parent">
<div class="child">Demo</div>
</div>
|
1
2
3
4
5
6
|
.parent {
display: flex;
}
.child {
margin: 0 auto;
}
|
+–
子元素不定宽使用flex
多个块级元素的水平居中,并列 ⇧
多元素水平排列 ⇧
display: inline-block;
布局
- 一行中有 两个或两个以上 的块级元素
- 通过设置块级元素的显示类型为
inline-block
- 设置父容器的
text-align: center;
属性从而使多块级元素水平居中
- 应用:横向导航菜单
1
2
3
4
5
6
|
.container {
text-align: center;
}
.container .center-children {
display: inline-block;
}
|
flex
布局 ⇧
1
2
3
4
|
.container {
display: flex;
justify-content: center;
}
|
justify-content: center;
用于设置 弹性盒子元素 在 主轴(默认横轴) 方向上的对齐方式
- 不定宽
多元素纵向排列 ⇧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
/* 限宽 */
.parent {
margin: 20px 0;
}
.parent div {
margin: 0 auto;
}
.parent div:nth-child(1) {
width: 200px;
}
.parent div:nth-child(2) {
width: 400px;
}
.parent div:nth-child(3) {
width: 125px;
}
|
表格元素水平居中 *较少使用 ⇧
table
标签法 ⇧
1
2
3
4
5
6
7
8
9
10
11
|
<table>
<thead>A Table Head</thead>
<tbody>
<tr>
<td>
I'm vertically centered multiple lines of text in a real table cell.
</td>
</tr>
</tbody>
<tfoot></tfoot>
</table>
|
1
2
3
4
5
6
7
8
9
|
table {
width: 240px;
height: 250px;
}
table td {
padding: 20px;
/* default is vertical-align: middle; */
}
|
浮动元素水平居中 *较少使用 ⇧
- 由于元素浮动之后,其本身就相当于设置了
display:inline-block;
也就是可以设置宽和高
- 浮动元素,没有 行内和块级之分,都是块级或
inline-block
的元素
- 只有 定宽 和 不定宽 之分
- 对于 定宽 的浮动元素,通过 子元素 设置
relative + 负margin
- 对于 不定宽 的浮动元素,父子容器 都用 相对定位
- 通用方法(不管是定宽还是不定宽):
flex
布局
- 必须在父级元素上清除浮动,即添加 清除浮动的类
1
2
3
4
5
6
|
/* 父元素上加 */
.clearfix::after {
content: '';
display: block;
clear: both;
}
|
定宽的浮动元素 ⇧
relative + margin-left + left
1
2
3
|
<div class="parent clearfix">
<span class="child">我是要居中的浮动元素</span>
</div>
|
1
2
3
4
5
6
7
|
.child {
width: 500px;
float: left;
position: relative;
left: 50%;
margin-left: -250px;
}
|
- 受到父元素的位置影响
- 注意:要清除浮动,给外部元素加上
float
- 这里的父元素就是外部元素
不定宽的浮动元素 ⇧
宽度由内容撑开
父float + 父relative + 子relative
1
2
3
4
5
6
7
8
|
<div class="box clearfix">
<p>我是浮动的</p>
<p>我也是居中的</p>
</div>
<br>
<div class="box clearfix">
<p>我是浮动的我也是居中的</p>
</div>
|
1
2
3
4
5
6
7
8
9
10
|
.box {
float: left;
position: relative;
left: 50%;
}
p {
// float: left;
position: relative;
right: 50%; // 或 right: 50%;
}
|
浮动元素,通用办法flex
布局 ⇧
不管是定宽还是不定宽,利用弹性布局(flex)的justify-content: center;
属性,实现水平居中
1
2
3
|
<div class="parent clearfix">
<span class="chlid">我是要弹性布局 居中的浮动元素;我是要弹性布局 居中的浮动元素;我是要弹性布局 居中的浮动元素</span>
</div>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
.parent {
display: flex;
justify-content: center;
}
.chlid{
float: left;
width: 200px; // 有无宽度不影响居中 但会影响文字排版
/* 三行属性单行溢出省略 */
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
|
绝对定位元素的水平居中 ⇧
非常独特,通过子元素绝对定位,外加margin: 0 auto;
来实现
- 由于元素绝对定位之后,其本身就相当于设置了(自动转变为)
display:inline-block
,即可设置有效宽和高了
- 绝对定位元素,没有 行内和块级之分,都是块级或
inline-block
的元素
- 只有定宽和不定宽之分
- 将 父元素 设置为 相对定位
- 将 子元素 设置为 绝对定位
- 即 子绝父相
- 向右移动子元素,移动距离为 父容器 的一半
margin-left: -100px;
- 最后通过向左移动 子元素 的一半 宽度 以达到 水平居中
定宽 position 负margin
1
2
3
|
<div class="parent">
<div class="child">让绝对定位的元素水平居中对齐。</div>
</div>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
.parent{
position: relative;
}
.child{
background: yellowgreen;
width: 200px;
height: 100px;
border: 1px solid red;
position: absolute; /* 绝对定位 */
/* margin-left: -100px; */ /* 可代替为以下 */
margin: 0 auto; /* 水平居中 */
left: 0; /* 此处不能省略,且为0 */
right: 0; /* 此处不能省略,且为0 */
}
|
- 注意如果有
padding
值也要计算在内
- 必须使用
box-sizing: border-box;
替代默认的content-box
不定宽 position + transform
- 原理:
- 将子元素设置为 绝对定位
- 定位子元素,使子元素 左侧距离 相对父元素左侧边框的距离为相对框宽度的一半
- 再通过向左移动子元素的一半宽度以达到水平居中。
- 需要设置父元素为 相对定位,使父元素成为子元素的相对元素
- 用法:
- 对父框设置
position: relative;
- 对子框设置
position: absolute; left: 50%; transform: translateX(-50%);
1
2
3
|
<div class="parent">
<div class="child">Demo</div>
</div>
|
1
2
3
4
5
6
7
8
|
.parent {
position: relative;
}
.child {
position: absolute;
left: 50%;
transform: translateX(-50%); // translateX 是相对自身来计算
}
|
- 绝对定位 使元素脱离文档流
- 该元素的父级元素的高度,注意不再被脱离文档流的子元素 撑起
其他
display:inline-block;
居中要靠父元素
width: fit-content;
直接margin: auto;
垂直居中 ⇧
内联元素垂直居中 ⇧
单行内联元素 ⇧
单行文字/图片 等元素在 高度固定 的容器内垂直居中
padding
填充法 ⇧
1
2
3
4
|
.container {
padding-top: 30px;
padding-bottom: 30px;
}
|
line-height
行高法 ⇧
- 适用于只有 一行文字 垂直居中的情况
- 将
line-height
值与外部标签盒子的 height
高度值设置成一致,即可
父元素加行高
1
2
3
4
5
6
7
|
.container {
height: 100px;
line-height: 100px;
white-space: nowrap;
border: 2px dashed #f69c55;
}
|
多行内联元素 ⇧
行数 不固定的文字/图片 等元素在 高度固定 的容器内垂直居中
flex
布局 ⇧
一把梭
1
2
3
4
5
6
7
8
|
<div class="container">
<p>
I'm vertically centered multiple lines of text in a flexbox container.
</p>
<p>
I'm vertically centered multiple lines of text in a flexbox container.
</p>
</div>
|
1
2
3
4
5
6
7
8
9
10
11
12
|
.container {
display: flex;
height: 200px;
/* 竖排 */
flex-direction: column;
justify-content: center;
/* 允许用户在垂直方向上调整元素的大小 */
resize: vertical;
overflow: auto;
}
|
flex-direction: column;
定义主轴方向为 纵向,默认为横向
伪元素法(不确定父类高度时使用)*奇技淫巧 ⇧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
.ghost-wrapper {
position: relative;
}
/* ::after 也可 选择器在内部插入伪元素 */
.ghost-wrapper::before {
content: " ";
display: inline-block;
height: 100%;
line-height:100%;
width: 1px;
margin-left: -1px; // fix 1px added
vertical-align: middle;
}
.ghost-wrapper .center {
display: inline-block;
vertical-align: middle;
}
|
- 引入一个伪元素,撑满父容器
- 使子元素
display: inline-block;
,基线和伪元素对齐
表布局(table) ⇧
父元素使用 table-cell
;子元素使用 inline-block
⇧
- 父容器高度固定
- 文字可能一行,两行或更多行的垂直居中对齐
- 把文字当图片处理
- 用一个
<span></span>
或<p></p>
标签将所有的文字封装起来
- 设置文字与图片相同的
display
属性值(inline-block属性)
- 用处理图片垂直居中的方式处理文字的垂直居中即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
.container{
width: 550px;
padding: 0 0.1em;
border: 4px solid #beceeb;
color: #069;
display: table-cell;
height: 1.14em;
font-size: 10em;
vertical-align: middle;
// text-align: center;
}
.child{
display: inline-block;
font-size: 0.1em;
vertical-align: middle;
}
|
- 外部
div
不能使用浮动
- 外部
div
高度和文字大小比例1.14
为宜
- 内部标签的
vertical-align:middle
可以省略,但是外部div
高度和文字大小比例要修改 高度比字体1.5
左右
- 给父元素设一个合适的 font-size 的值,这个值的取值为该父元素的高度除以 1.14 得到的值
- 并且子元素必须 是一个 inline 或 inline-block 元素
- 需要加上 vertical-align: middle 属性
- 使用这种方法,子元素的宽度或高度都不必知道。
子元素使用 table-cell
⇧
1
2
3
4
|
<div class="center-table">
<p>I'm vertically centered multiple lines of text in a CSS-created table layout.
</p>
</div>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/* 父元素display: table-cell; 子元素 display: table-cell; */
.center-table {
border: 1px solid cyan;
height: 300px;
width: 300px;
display: table;
}
.center-table p {
border: 1px solid yellow;
/* padding: 20px; */
display: table-cell;
text-align: center; /* 文字居中 但 content 内容没有收缩 撑满父元素 */
/* 要加 display: inline-block; 收缩至文字宽度 */
display: inline-block;
vertical-align: middle;
}
|
- 当做表格元素使用,其他不用
- 父元素设置固定宽高的话,加
vertical-align: middle;
实现垂直居中
- 固定宽高,不适用响应式
display: table;
的 vertical-align: middle;
⇧
- 实现子元素
display: table-cell;
的垂直居中
1
2
3
4
5
6
7
|
<div class="parent">
<p class="child">
he more technology you learn, the more you realize how little you know.
The more technology you learn, the more you realize how little you know.
The more technology you learn, the more you realize how little you know.
</p>
</div>
|
1
2
3
4
5
6
7
8
|
.parent {
display: table;
border: 2px dashed #f69c55;
}
.child {
display: table-cell;
vertical-align: middle;
}
|
table
标签法 ⇧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<table>
<thead>A Table Head</thead>
<tbody>
<tr>
<td>
I'm vertically centered multiple lines
</td>
<td>
of text in a real table cell.
</td>
</tr>
<tr>
<td>
I'm vertically centered multiple
</td>
<td>
lines of text in a real table cell.
</td>
</tr>
</tbody>
<tfoot></tfoot>
</table>
|
1
2
3
4
5
6
7
8
9
10
11
|
table {
width: 300px;
height: 300px;
}
table td {
border: 1px solid red;
/* default is vertical-align: middle; */
padding: 20px;
}
|
块级元素垂直居中 ⇧
子元素height
已知
使用absolute + 负margin
(已知宽高度) ⇧
- 通过绝对定位元素,定位属性设置距离顶部
50%
- 并设置负的
margin-top
,即向上偏移元素高度的一半,就可以实现了
- 子元素
height
已知
- 绝对定位脱离文档流,注意:父元素高度,不再被脱离文档流的子元素撑起
1
2
3
4
5
|
<div class="parent">
<div class="child">
固定高度的块级元素垂直居中
</div>
</div>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
.parent {
position: relative;
}
.child {
height: 100px;
line-height: 100px;
position: absolute;
/* 定位 */
// top: 0;
// bottom: 0;
// margin: auto;
/* 负margin */
top: 50%;
margin-top: -50px;
/* account for padding and border if not using box-sizing: border-box; */
}
|
子元素height
未知
- 垂直居中的子元素的高度和宽度未知时
transform
属性向 Y轴反向偏移50%
的方法实现垂直居中
- 父元素或祖先元素已知高度
- 子元素
height
未知
- 绝对定位元素相当于
inline-block
- 没有行和块之分,只有定高和不定高之分
- 原理:将子元素设置为 绝对定位
- 定位子元素:将子元素 上侧距离
top
相对元素下侧边框的距离设置为相对框宽度的一半
- 再通过向上移动子元素的一半宽度以达到水平居中。
- 需要设置父元素为相对定位,使父元素成为子元素的相对元素
- 用法:
- 对父框设置
position: relative;
- 对子框设置
position: absolute;top: 50%;transform: translateY(-50%);
1
2
3
4
5
6
7
8
|
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
|
- 居中元素不会对其他的产生影响,即 脱离文档流
- 但是,这个技术在基于
Chromium
的浏览器中引起了文本模糊的问题
- 可以使用
flex + margin: auto
代替
1
2
3
4
5
6
7
|
.parent {
display: flex;
}
.child {
margin: auto;
}
|
display: table-cell;
vertical-align: middle;
⇧
- 通过将父元素转化为一个表格单元格显示(类似 和 )
- 再通过设置
vertical-align: middle;
属性,使表格单元格内容垂直居中
- 父元素宽高固定
- 子元素高度无所谓
1
2
3
4
5
6
7
8
9
10
11
|
.wrapper {
height: 300px;
width: 300px;
position: relative;
display: table;
}
.wrapper div {
display: table-cell;
vertical-align: middle;
text-align: center;
}
|
inline-block
、vertical-align: middle;
和 伪元素 撑开 ⇧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
.parent {
height: 100px;
}
/* ::after 也可 选择器在内部插入伪元素 */
.parent::before {
content: "";
height: 100%;
width: 1px; // for some browsers
margin-left: -1px; // fix 1px added
}
.child {
text-align: center; // horizontal centered
word-break: break-word;
}
.child {
display: inline-block;
vertical-align: middle; // vertical centered
}
|
flex
布局 单个元素居中 ⇧
设置flex
布局中的属性align-items: center;
,使子元素垂直居中
1
2
3
4
|
.parent {
display: flex;
align-items: center;
}
|
或者设置flex
布局中的属性flex-direction
,设置子元素在 次轴 方向上的对齐方式
1
2
3
4
5
|
.parent {
display: flex;
flex-direction: column;
justify-content: center;
}
|
正中 超级居中:水平且垂直居中 ⇧
初始
1
2
3
4
5
6
7
|
<main class="wrapper">
<div class="container">
<div class="centerElement">
<span>Center of Universe</span>
</div>
</div>
</main>
|
1
2
3
4
5
6
7
8
9
10
|
/* default */
.centerElement {
width: 100px;
height: 100px;
background-color: #666;
text-align: center;
padding-top: 25px;
padding-bottom: 25px;
}
|
通用(一列或多列):table-cell
+ vertical-align
+ text-align
⇧
- 通用(不管行、块级元素、图片等通杀)
- 适用于子元素
display
为 inline-block
, inline
类型的元素
- 需要 已知 父元素的 宽高,且父元素的 宽高不能设为百分比数
1
2
3
4
5
6
7
8
9
10
11
|
.container {
width: 400px;
height: 500px;
display: table-cell;
text-align: center; // 水平居中
vertical-align: middle; // 垂直居中
}
.centerElement {
display: inline-block; // 适合多列
}
|
负margin
⇧
- 子元素有 固定宽高,父元素 没有固定宽高,子元素高度撑开父元素
- 需要知道被垂直居中元素的高和宽,才能计算出
margin
值
- 兼容所有浏览器
1
2
3
4
5
6
7
8
9
10
11
12
13
|
.container {
position: relative;
}
.centerElement {
width: 300px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
margin: -50px 0 0 -150px;
}
|
- 注意如果有
padding
值也要计算在内
- 最好使用
box-sizing: border-box
- 灵活性差,不能自适应,宽高不支持百分比尺寸和 min-/max- 属性
absolute
与margin: auto;
⇧
- 父元素有固定高;子元素没有固定宽高
- 绝对定位与
margin:auto
(已知父元素高度)
- 无需知道被垂直居中元素的高和宽
- 但不能兼容低版本的IE浏览器
- 绝对定位脱离文档流,父元素高度,注意不再被脱离文档流的子元素撑起,注意覆盖
- 元素的宽高支持百分比 % 属性值和 min-/max- 属性
1
2
3
4
5
6
7
8
9
10
11
12
|
.container {
position: relative;
height: 100px; // 必须有个高度
}
.centerElement {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto; // 注意此处的写法
}
|
1
2
3
4
5
6
7
8
9
|
.container {
position: relative;
}
.centerElement {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
|
- 但是,这个技术在基于
Chromium
的浏览器中引起了模糊的文本问题
- 使用
flex + margin: auto
代替
1
2
3
4
5
6
7
|
.parent {
display: flex;
}
.child {
margin: auto;
}
|
flex
布局 ⇧
justify-content
设置或检索弹性盒子元素在 主轴(横轴) 方向上的对齐方式
align-items
属性定义flex
子项在flex
容器的当前行的 侧轴(纵轴) 方向上的对齐方式
- 只在父元素上控制 子元素 居中的样式
- 内容可自适应
1
2
3
4
5
|
.container {
display: flex; /* 弹性布局 */
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}
|
其中display: flex;
换成display: grid;
就变成grid
布局居中,其他不变
grid
布局 ⇧
1
2
3
4
5
6
|
.container {
/* height: 50vh; */
display: grid;
justify-items: center; // 指定了网格元素的水平呈现方式
align-items: center; // 指定了网格元素的垂直呈现方式
}
|
flex/grid
与 margin: auto;
⇧
- 容器元素设为
flex
布局或是 grid
布局
- 子元素只要写
margin: auto
即可
1
2
3
4
5
6
7
8
9
10
11
12
13
|
.container1 {
height: 100vh; // 必须有高度
display: grid;
}
.container2 {
height: 100vh; // 必须有高度
display: flex;
}
.centerElement {
margin: auto;
/* 如果是flex */
flex: 0 0 auto;
}
|
float
、display:inline-block
、display:table-cell
、vertical-align
以及column-*
这些属性和声明对flex/grid
子项是没有任何作用的
简写实现超级居中 place-items: center;
(最简单写法) ⇧
1
2
3
4
|
.parent {
display: grid; /* display: flex; */
place-items: center;
}
|
- 是以下两个 CSS 属性的简写:
align-items
justify-items
居中使用判断维度与流程 ⇧
- 兼容性
- 组件用途(文本、标题、图片等)
- 宽高是否固定(父元素/子元素)
- 元素、布局类型(行内、块级等)
- 居中方向(上下、左右)
需要熟练运用一把梭的 ⇧
flex/grid
与 margin:auto
(最简单写法)
flex/grid
布局(水平 + 垂直)
absolute
+ margin: auto;
+ TRBL:0;
absolute
+ transform
(50%
)
- 子元素定宽高 + 负
margin
- 不要把父元素的高度写死,用内容和子元素撑到所需求的高度
- 无论是什么居中方式,只是粗略地定位;精确地设置位置,用定位
position
特殊问题处理 ⇧
参考文章
相关文章
- 作者: Joel
- 文章链接:
- 版权声明
- 非自由转载-非商用-非衍生-保持署名