定位居中方式应用场景速记

大纲链接 §

[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(推荐)
  • 超级居中 flexgrid + 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
.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(推荐)

  • 原理:
    • 利用绝对定位时的 topleft 设置元素各为父元素尺寸的50%
    • 再利用 transform: translate(-50%, -50%); 位移至该元素自身宽与高的50%
  • 显著优势:无需指定 定位元素宽高
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
.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
.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
/* 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;
}

适用于flexgrid的超级居中

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;还原

块级元素水平居中

  • 常见的块元素:divh1~h6pullitable 等等

图片元素的居中

  • 将 行内元素 变为 块级元素
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; */
}
  • 使用table标签一般需要完整结构有些啰嗦,不用

浮动元素水平居中 *较少使用

  • 由于元素浮动之后,其本身就相当于设置了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的元素
  • 只有定宽和不定宽之分

绝对定位 + 移动-50% absolute + transform

  • 父元素 设置为 相对定位
  • 子元素 设置为 绝对定位
  • 子绝父相
    • 向右移动子元素,移动距离为 父容器 的一半 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 填充法
  • 父元素 高度固定
  • 父元素设置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未知

使用absolute + transform

  • 垂直居中的子元素的高度和宽度未知时
  • 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-blockvertical-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

  • 通用(不管行、块级元素、图片等通杀)
  • 适用于子元素 displayinline-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- 属性

absolutemargin: 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; // 注意此处的写法
}

absolute + transform

  • 父子元素没有固定宽高
  • 内容可自适应
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/gridmargin: 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;
}

floatdisplay:inline-blockdisplay:table-cellvertical-align以及column-*这些属性和声明对flex/grid子项是没有任何作用的

简写实现超级居中 place-items: center; (最简单写法)

1
2
3
4
.parent {
    display: grid; /* display: flex; */
    place-items: center;
  }
  • 是以下两个 CSS 属性的简写:
    • align-items
    • justify-items

Super Centered


居中使用判断维度与流程

  • 兼容性
  • 组件用途(文本、标题、图片等)
  • 宽高是否固定(父元素/子元素)
  • 元素、布局类型(行内、块级等)
  • 居中方向(上下、左右)

需要熟练运用一把梭的

  • flex/gridmargin:auto(最简单写法)
  • flex/grid 布局(水平 + 垂直)
  • absolute + margin: auto; + TRBL:0;
  • absolute + transform (50%)
  • 子元素定宽高 + 负margin
  • 不要把父元素的高度写死,用内容和子元素撑到所需求的高度
  • 无论是什么居中方式,只是粗略地定位;精确地设置位置,用定位position


特殊问题处理


参考文章

相关文章


  • 作者: Joel
  • 文章链接:
  • 版权声明
  • 非自由转载-非商用-非衍生-保持署名