CSS 垂直居中

🌙
手机阅读
本文目录结构
axihe

前沿

对元素进行垂直居中,虽然没有水平居中那么频繁,但也是很常用的操作,本章介绍垂直居中的方法。

如果你水平居中,能够完全理解,会发现这一节的原理和套路都是类似的,都是用一个类型的 CSS 属性,只是水平居中使用控制 X 轴的属性,而垂直居中使用控制 Y 轴的属性。

预储备知识

了解下面这些知识储备,可以更好的掌握本节的内容。

vertical-align 和 line-height 的关系

https://www.zhangxinxu.com/wordpress/2015/08/css-deep-understand-vertical-align-and-line-height/

z-index 属性

用来设置定位元素的层叠顺序(仅仅只对定位元素有效)

取值可为正负整数,0

比较原则

  • 如果是兄弟关系
    • z-index 越大,层叠在越上面
    • z-index 相等,写在后面的那个元素层叠在上面
  • 如果不是兄弟关系
    • 各自从元素自己以及祖先元素中,找出最邻近的 2 个定位元素进行比较
    • 而且这 2 个定位元素必须有设置 z-index 的具体数值

清浮动的目的

让父元素计算总高度的时候,把浮动子元素的高度算进去

而清浮动的方式有很多,但大多都有各式各样的不足,这里只介绍一种个人认为最为成熟的方式

.container::after {
    content: "";
    display: block;
    clear: both;
}

/* 为了适配以前的旧浏览器,还需要这么写 */
.container::after {
    content: "";
    display: block;
    clear: both;
    height: 0;
    visibility: hidden;
}

这样做的好处是不会改变父元素格式,并且能够纯 CSS 样式解决,遵循结构与样式分离~

最后,介绍下 clear 属性

clear 的常用取值

  • left:要求元素的顶部低于之前生成的所有左浮动元素的底部
  • right:要求元素的顶部低于之前生成的所有右浮动元素的底部
  • both:要求元素的顶部低于之前生成的所有浮动元素的底部
  • none:默认值,无特殊要求

一般就只用在非浮动元素上,可以让非浮动元素与浮动元素不层叠。

height 和 line-height

  • height
  • line-height

设置父元素的 heightline-height 相等, 是一个万金油的操作,可以解决很多场景;无论是inline 元素,inline-block 元素,block 元素都可以。

line-height的表现是通过 inline box 实现的,而无论 inline box 所占据的高度是多少(无论比文字大还是比文字小),其占据的空间都是与文字内容公用水平中垂线的。

操作 inline 元素

设置父元素的 heightline-height 相等。缺点是只能用于单行行内内容;要知道高度的值

例子如下:

<div style="
    border: 1px solid #666;
    height: 100px;
    line-height: 100px;
    ">
    <span>阿西河前端教程</span>
</div>

操作 inline-block 元素

设置父元素的 heightline-height 相等, 如:

<div style="
    border: 1px solid #666;
    height: 100px;
    line-height: 100px;
    ">
    <div style="border: 1px solid  green;display: inline-block;">
        阿西河
    </div>
</div>

inline-block 元素是可以设置宽度和高度的,所以如果你有需要给子元素设置高度的需求,或者设置小于父级的背景或者下边框等,那么你需要子元素也设置heightline-height

<div style="
    border: 1px solid #666;
    height: 100px;
    line-height: 100px;
">
    <div style="
        background-color:#d4d4d4;
        display: inline-block;
        height: 50px;
        line-height: 50px;
    ">
        阿西河
    </div>
</div>

利用“精灵元素”

利用精灵元素 (ghost element) 技术实现垂直居中,即在父容器内放一个 100% 高度的伪元素,让文本和伪元素垂直对齐,从而达到垂直居中的目的。

核心代码:

<div class="ghost-center">
    <p>阿西河前端教程</p>
</div>
.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: 20rem;
}

操作 block 元素(定高)

设置 position:absolute 定位

设置子元素 position:absolute 并设置 top、bottom 为 0,

父元素要设置定位为 static 以外的值(如 relative),margin:auto;

如:

<div style="
        border: 1px solid #666;
        height: 100px;
        position: relative;
    ">
    <div style="
            background-color:#d4d4d4;
            height: 50px;
            width: 150px;
            position: absolute;
            top: 0; bottom: 0;
            margin: auto;
        ">
        阿西河
    </div>
</div>

利用 position , top 和负 margin

  • 设置元素为 absolute/relative/fixed
  • margin= 负一半(可以是百分比的单位)

    <div style="
    border: 1px solid #666;
    position: relative;
    height: 100px;
    ">
    <div style="
    position: relative;
    background-color:#d4d4d4;
    height: 50px;
    top: 50%;
    margin-top: -25px;
    ">
        阿西河
    </div>
    </div>
    

优点是适用于所有浏览器。

缺点父元素空间不够时,子元素可能不可见(当浏览器窗口缩小时,滚动条不出现时). 如果子元素设置了 overflow:auto, 则高度不够时,会出现滚动条。

calc属性

介绍

这种方式原理和上面使用负margin-top的原理输类似的,虽然没有用到margin-top;

calc是 CSS3 的属性

核心代码

position: absolute;
height:高度;
top: calc(50% - 一半的高度);

例子

<div style="
  border: 1px solid #666;
  position: absolute;
  height:500px;
  top: calc(50% - 250px);
  ">
    阿西河前端教程
</div>

利用 positiontop/bottommargin: auto 0

  • 1、position:absolute/relative/fixed
  • 2、top/bottom:0
  • 3、margin:auto

原理:当 top、bottom 为 0 时,margin-top&bottom 设置 auto 的话会无限延伸占满空间并且平分;脱离文档流

缺点:没有足够空间时,子元素会被截断,但不会有滚动条。

<div style="
    border: 1px solid #666;
    position: relative;
    height: 100px;
    ">
    <div style="
    background-color:#d4d4d4;
    position: absolute;
    height: 50px;
    top: 0;
    bottom: 0;
    margin:  auto 0;

    ">
        阿西河
    </div>
</div>

操作 block 元素(不定高)

设置 padding-top 等于 padding-bottom

优点:兼容性非常好

缺点:如果父级的高度受到兄弟节点的影响,这样自己就不居中了

<div style="
    border: 1px solid #666;
    ">
    <div style="
    padding-top: 20px;
    padding-bottom: 20px;
    ">
        阿西河
    </div>
</div>

设置 display:table;vertical-align

通过设置父元素 table,子元素 table-cellvertical-align ;

vertical-align:middle 的意思是把元素放在父元素的中部

缺点:设置 tabl-cell 的元素,宽度和高度的值设置百分比无效,需要给它的父元素设置 display: table; 才生效;table-cell 不感知 margin,在父元素上设置 table-row 等属性,也会使其不感知 height;设置 float 或 position 会对默认布局造成破坏,可以考虑为之增加一个父 div 定义 float 等属性;内容溢出时会自动撑开父元素。

<div style="
    border: 1px solid #666;
    height: 100px;
    display: table;
    ">
    <div style="
    display: table-cell;
    vertical-align: middle;;
    ">
        阿西河
    </div>
</div>

设置 display:inline-block;vertical-align`

以前很流行的方法,也适应 IE7.

.parent::after, .son{
    display:inline-block;
    vertical-align:middle;
}
.parent::after{
    content:'';
    height:100%;
}

设置 flex 布局

在需要垂直居中的父元素上,设置 display:flexalign-items:center

要求:父元素必须显示设置 height 值

优点

  • 内容块的宽高任意,优雅的溢出。
  • 可用于更复杂高级的布局技术中。

    <div style="
    border: 1px solid #666;
    height: 100px;
    display: flex;
    align-items: center;
    ">
    <div>阿西河</div>
    </div>
    

其它写法

#parent{
    display: flex;
    align-items: center;
}

#parent{display: flex;}
#son{align-self: center;}

/*原理:这个尚未搞清楚,应该是flex使margin上下边界无限延伸至剩余空间并平分了*/
#parent{display: flex;}
#son{margin: auto 0;}

任意个元素的写法

# parent{
    display: flex;
    align-items: center;
}

# parent{display: flex;}
.son{align-self: center;}

# parent{
    display: flex;
    flex-direction: column;
    justify-content: center;
}

grid 属性

核心代码


display: grid;

例子


<div class="wp">
    <div class="box">123123</div>
</div>
.wp {
    display: grid;
}
.box {
    align-self: center;
    justify-self: center;
}

利用 positiontoptransform

transform 中 translate 偏移的百分比就是相对于元素自身的尺寸而言的。

translate(0 -50%)translateY(-50%);都可以。

<div style="
    border: 1px solid #666;
    height: 100px;
    position: relative;
    ">
    <div style="
    position: absolute;
    top: 50%;
    transform: translate(0 -50%);
    background-color:#d4d4d4;
    ">
        阿西河
    </div>
</div>

利用writing-mode

writing-mode 可以改变文字的显示方向,比如可以通过 writing-mode 让文字的显示变为垂直方向

<div class="wp">
    <div class="wp-inner">
        <div class="box">123123</div>
    </div>
</div>
.wp {
    writing-mode: vertical-lr;
    text-align: center;
}
.wp-inner {
    writing-mode: horizontal-tb;
    display: inline-block;
    text-align: center;
    width: 100%;
}
.box {
    display: inline-block;
    margin: auto;
    text-align: left;
}

使用 padding 实现子元素的垂直居中

这种实现方式非常简单,就是给父元素设置相等的上下内边距,则子元素自然是垂直居中的,当然这时候父元素是不能设置高度的,要让它自动被填充起来,除非设置了一个正好等于上内边距 + 子元素高度 + 下内边距的值,否则无法精确的垂直居中。

# box {
    width: 300px;
    background: #ddd;
    padding: 100px 0;
}
# child {
    width: 200px;
    height: 100px;
    background: #F7A750;
    line-height: 50px;
}

设置第三方基准

这种方式也非常简单,首先设置一个高度等于父元素高度一半的第三方基准元素,那么此时该基准元素的底边线自然就是父元素纵向上的中分线,做完这些之后再给要垂直居中的元素设置一个 margin-top,值的大小是它自身高度的一半取负,则实现垂直居中。

<div id="box">
    <div id="base"></div>
    <div id="child">
        Hello world,Hello world
    </div>
</div>
# box {
    width: 300px;
    height: 300px;
    background: #ddd;
}
# base {
    height: 50%;
    background: #AF9BD3;
}
# child {
    height: 100px;
    background: rgba(131, 224, 245, 0.6);
    line-height: 50px;
    margin-top: -50px;
}

使用 line-height 和 vertical-align 对图片进行垂直居中

<div id="box">
    <img src="img/user.png">
</div>
# box{
    width: 300px;
    height: 300px;
    background: #ddd;
    line-height: 300px;
}
# box img {
    vertical-align: middle;
}

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili 和抖音。

关注我: Github / 知乎

如果你加我的私人微信,麻烦写上您的 称呼,所在地区,职业,方便我备注,谢谢


本站的微信公众号

阿西河前端教程

Anbang

安邦的私人微信

微信号: yaolushan

Anbang

Bilibili(B站)

朱安邦

Anbang