写点什么

关于 vertical-align 你应该知道的一切

  • 2021-03-18
  • 本文字数:4389 字

    阅读完需:约 14 分钟

关于 vertical-align 你应该知道的一切

前言


vertical-align,写过 CSS 的朋友们肯定都知道这个属性的作用,顾名思义,垂直对齐,主要目的用于将相邻的文本与元素对齐。MDN 中对它的定义如下:


一种简单的 CSS 属性,用来指定行内元素(inline)或表格单元格(table-cell)元素的垂直对齐方式。

我们对于它的直观定义是与 text-align:center 相类似,一个控制水平方向对齐方式,一个控制垂直方向对齐方式。但是在很多情况下,我们发现设置属性之后并没生效。接下来让我们步步深入学习,共同揭开 vertical-align 的神秘 “面纱” 吧。


首先我们先讲一下,要实现垂直居中,我们为什么选择 vertical-align 这样一个不起眼的 CSS 属性。

  • float:只能对齐它们的顶部,而且可能导致布局塌陷,需要手动清除

  • position:absolute:会使元素脱离文档流,以致于它们不能影响周围的元素

  • 手动添加内外边距的方法:需要父元素高度固定

  • transform:translateY:属于 CSS3 新特性,对 IE8、IE9 有一些兼容性的问题


使用 vertical-align 你能在不同场景下去进行灵活细微的元素对齐工作,并且它有很好的的兼容性,详情如下图所示:


前置准备


在认识 vertical-align 属性之前,首先要了解几个基本的概念。


  • 基线:书写英语字母时,字母 X 底部所在的位置,可以了解下《字母’x’在 CSS 世界中的角色和故事》(https://www.zhangxinxu.com/wordpress/2015/06/about-letter-x-of-css/)

  • 行高(line-height):两行文字基线之间的距离

  • 内联盒子,更深入的理解可以参考《CSS 盒子模型》(https://segmentfault.com/a/1190000014692461)


  • content area:围绕文字看不见的 Box,其大小与 font-size 有关

  • inline boxes:不会成块显示,而是并排显示在一行的 boxes ,如 span、 a、 em 等标签以及匿名 inline boxes(即不含把标签的裸露的文字)

  • line boxes:由一个一个的 inline boxes 组成,一行即为一个 line box

  • containing box:外层盒子模型,包含了其他的 boxes

  • 起作用的前提:元素为 inline 水平元素或  table-cell  元素,包括  span、 img、 input、 button、 td  以及通过 display 改变了显示水平为 inline 水平或者 table-cell 的元素。这也意味着,默认情况下,div 、p  等元素设置 vertical-align 无效


值得注意的是:例如 float 和 position: absolute,一旦设置了这两个属性之一,元素的 display 值被忽略,强制当成 block 方式处理,因此,vertical-align 也就失去了作用。


vertical-align 属性值


除 Inherit 继承 之外,vertical-align 的属性值可以归为以下 4 类


  • 线类,如  baseline、top、middle、bottom;

    我们可以把每一个行框盒子的后面想象有一个看不见的节点 x(该节点继承了 line-height ),因为默认对齐方式为基线对齐,所以 .text 就是和这个字母 x 的下边缘对齐。

    在实际应用中我们经常会遇到下图这种情况,你可能会容易的解决这种无法对齐的问题,但是你知道是什么原因导致他们这个样子吗?

  • baseline 为 vertical-align 的默认值,其意思是指基线对齐


<ul class="box">  <li>文本</li>  <li></li></ul><style>  .li {    font-size: 20px;    width: 160px;    height: 160px;    display: inline-block;    border: 1px solid #ccc;  }</style>
复制代码


这里就涉及到了 inline-block 基线的定义,inline-block  的基线是正常流中最后一个(行盒子) line box 的基线,但是,如果这个 line box 里面没有 inline boxes 或者其 overflow 属性值不是 visible,那么其基线就是 margin bottom 的边缘。


如上图所示,第一个元素基线是子元素”文本“的基线,而第二个是盒子的底边缘,默认基线对齐,两个元素基线位置不一致,所有会产生上图现象,知道了原因,我们只需设置元素的 vertical-align 属性为  top/bottom/middle  就可以轻松对齐了。


  • top 与 bottom

    对于内联元素,指的是元素的顶部(底部)和当前行框盒子的顶部(底部)对齐;即与 line-box 的顶部(底部)对齐。

    对于 table-cell 元素,指的是元素的顶 padding 边缘和表格行的顶部对齐。

    基本效果如下图:


  • middle 这个属性值用得比较多。

    对于内联元素指的是元素的垂直中心点与行框盒子基线往上 1/2x-height 处对齐,简单点说就是字母 X 的中心位置对齐;对于 table-cell 元素,指的是单元格填充盒子相对于外面的表格行居中对齐。

  • 文本类


text-top,指的是盒子的顶部和父级内容区域的顶部对齐,即与 content-area 顶部对齐。text-bottom,指的是盒子的底部和父级内容区域的底部对齐,即与 content-area 底部部对齐。


例子如下:


<div class="box">  <span class="f12">12px</span>  <span class="f16">16px</span>  <span class="f20">20px</span>  <img src="./panda.jpg"/></div><style>  .box {    font-size: 16px;  }  img {    vertical-align: text-top;    width: 100px;    height: 100px;  }  .f12 {    font-size: 12px;  }  .f16 {    font-size: 16px;  }  .f20 {    font-size: 20px;  }</style>
复制代码

content-area 即围绕文字看不见的 box,其大小与 font-size 有关,可以看成是鼠标选中文字后高亮的背景色区域,上面的例子中,由于父元素字体设置的是 16px ,所以图片的 vertical-align 设置 text-top 的时候,就可以看成是跟子元素为 16px 元素的内容区域顶部对齐,它与 line-height 无关


  • 上标下标类


如 sub、super;这两个属性用的比较少。


  • super 属性效果相当于 html 标签 <sup></sup> 的效果

  • sub 属性效果 相当于 html 标签 <sub></sub> 的效果

  • 数值百分比类,如 10px、1em、5%


之所以数值和百分比写在一起主要是他们有以下共性:都带数字、都支持负值、行为表现一致


  • vertical-align 支持数值的特性,兼容性也非常好,但大部分开发人员却不知道 vertical-align 支持数值。对于数值,我们要知道的是:1、正值表示由基线往上偏移,负值表示由基线往下偏移。2、百分比则是基于 line-height 来计算的


需要注意的是:除了 top 与 bottom 是使元素相对于整行垂直对齐外,其他属性值都是相对于父元素。所以,在开发时,我们只需要关注当前元素和父级,两元素前后并没有直接影响


vertical-align 与 line-height 之间的基友关系


说到 vertical-align 就要讲到它与 line-height 之间密切的关系,从上面我们都知道百分比类型是根据 line-height  来计算的。但事实是 对于内联元素,vertical-align 与 line-height 虽然看不见,但实际上「到处都是」。其实我们很多时候发现设置 vertical-align 属性无效,这很有可能就是 line-height 的原因了,下面我们来看两个典型的例子。


  • Demo 1:任意一个块级元素,里面若有图片,则块级元素高度基本上都要比图片的高度高

<div class="box">  <img  src="./panda.jpg" /></div><style>  .box {    width: 300px;    border: 1px solid #ddd;  }  img {    width: 100px;    height: 100px;  }</style>
复制代码


产生这种现象的原因:空白节点、line-height 和  vertical-align 属性;图片后放置空白节点 X,会发现图片的基线是元素底部,与“空白节点”的基线对齐,那解决这种问题有以下几个方法:


(1)将图片设置为 display:block (利用 vertical-align 的生效前提)

(2)将 vertical-align 设置为 top,bottom,或者 middle 等值(利用属性值的表现行为)

(3)将 line-height 设置为 0 (利用 line-height 为 0 时,基线上移)

(4)将 font-size 设置为 0  (如果 line-height 的值为相对值)

(5)将 img 设置浮动或者绝对定位 (如果布局允许的话)


  • Demo 2:近似垂直居中

<div class="box">  <span class="son"></span>  x</div><style>  .box {    width: 300px;    height: 150px;    line-height: 150px;    font-size: 20px;    border: 1px solid #ddd;    position: relative;  }  //  绘制父元素的垂直中心线  .box::after  {    content: "";    position: absolute;    display: block;    width: 100%;    height: 1px;    background-color: red;    top: 0;    bottom: 0;    margin: auto;    left: 0;  }  .son  {    display: inline-block;    width: 100px;    height: 100px;    vertical-align: middle;    background-color: purple;    position: relative;  }  .son::after {    content: "";    position: absolute;    display: block;    width: 100%;    height: 1px;    background-color: #317ffd;    top: 0;    bottom: 0;    margin: auto;    left: 0;  }</style>
复制代码



如图所示(为了更明显我使用了色块来标识),当子元素(图片)设置了 vertical-align:middle,并不是绝对居中,而只能说是近似居中。子元素的垂直中心线与父级元素基线的位置往上二分之一 X 高度(X 的中心) 所在线对齐,通俗一点讲,就是图中红线表示父元素的垂直中心线,蓝线表示子元素的垂直中心线,可以明显的看到 蓝线 与 X 的中心保持一致,但较红线偏低。如果绝对居中的话,两条线应该完全重合。


为什么会产生这种现象呢?主要原因在于文字具有下沉特性,从而导致蓝线无法绝对与红线对齐。当文字大小足够小时,我们可以忽略。从而近似的实现居中效果。但是文字越大,影响就越明显。


那对于这样的问题我们要怎么解决呢?以下提供几种思路:


1、设置后面的 “空白节点 X ” 的垂直对齐方式也是  vertical-align:middle,然而,既然称之为 “空白节点” 就表示不会受非继承特性的属性影响,所以,根本没法设置  vertical-align:middle,除非你自己创建一个显示的内联元素或者伪元素。

2、“空白节点” 可以受具有继承特性的 CSS 属性影响,于是,我们可以通过其他东西来做调整,让字符的中线和字符内容中心线在一起,或者说在一个位置上就可以了。设置父元素 font-size:0 , 因此此时 content area 高度是 0,各种乱七八糟的线都在高度为 0 的这条线上,绝对中心线和中线重合。效果如下:


这种通过 line-height 定高,元素 vertical-align:middle 垂直居中的方法不仅适用于现代浏览器,连 IE 浏览器也是支持的,但是这里只有在 IE7 中需要注意的是图片后面需要换行或者空格,经验证这个不是由于标签闭合引起的,可能只是一个 IE7 的 bug 吧。比较幸运的是,现在很多网站的兼容都是基于 IE9,所以可以忽略这个问题啦。


<div>  <img src="xxx.jpg">  <!-- 这里要折行或空格 --></div>
复制代码


总结


本文讲解了 vertical-align 的基本属性以及各种表现,同时对一些实际应用中 vertical-align 无效现象做了简单的分析阐述,并为解决此类问题提供了思路。



头图:Unsplash

作者:润瑞

原文:https://mp.weixin.qq.com/s/vk6qCqTf3B4PSIKQGQoMEA

原文:关于 vertical-align 你应该知道的一切

来源:政采云前端团队 - 微信公众号 [ID:Zoo-Team]

转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


2021-03-18 14:162615

评论 1 条评论

发布
用户头像
` .li { ` 应该没有那个点……
2021-04-06 11:42
回复
没有更多了
发现更多内容

如何做好技术选型和分析决策

Man

技术选型 CMMI

2021最新Spring Security知识梳理

北游学Java

Java spring

Data Mesh,数据网格的道与术

王知无

如何给岗位设计薪资结构?

石云升

股权 薪酬 职场经验 6月日更

zip解压缩

Hello

计算机网络概述

若尘

计算机网络 6月日更

谁也讲不明白的SQL注入攻击被我讲明白了(中)?

网络安全学海

程序员 网络安全 计算机 渗透测试 SQL注入

硬刚Hbase - 17道题你能秒我?我Hbase八股文反手就甩你一脸

王知无

架构师实战营 模块七作业(王者荣耀商城的异地多活架构设计)

代廉洁

架构实战营

kubelet分析-csi driver注册分析-Node Driver Registrar源码分析

良凯尔

源码 Kubernetes CSI Kubernetes Plugin

硬刚Hive | 4万字基础调优面试小总结

王知无

使用uni-admin搭建后台管理系统

代码哈士奇

uni-app uniapp unicloud uni-admin

使用uni-upgrade-center搭建APP更新系统(升级中心+应用升级)

代码哈士奇

uni-app uniapp unicloud uni-admin uni-upgrade-center

「SQL数据分析系列」11. 条件逻辑

Databri_AI

数据库 sql 逻辑 条件

嵌入方法在推荐系统中的应用(二十)

Databri_AI

推荐系统 嵌入

基于FPGA系统合成两条视频流实现3D视频效果

不脱发的程序猿

智能硬件 FPGA系统 视频流 合成3D视频

最佳的管理者-库克

卢卡多多

苹果 管理者 6月日更

企业级一站式大数据开发平台理论及实践

王知无

这样理解Mysql索引,阿里面试官也给你点赞

慕枫技术笔记

MySQL 后端 索引

硬刚数据仓库|SQL Boy的福音之数据仓库体系建模&实施&注意事项小总结

王知无

区块链引发了一场独特的社会运动

CECBC

大势已来,区块链的真正价值是什么?

CECBC

硬刚ClickHouse | 4万字长文ClickHouse基础&实践&调优全视角解析

王知无

为什么 Python 没有函数重载?如何用装饰器实现函数重载?

Python猫

Python

架构实战训练营 - 模块七课后作业

Johnny

架构实战营

硬刚Presto | Presto原理&调优&面试&实战全面升级版

王知无

元数据的管理

奔向架构师

数据库 大数据 数据资产

文件IO

Hello

硬刚Apache Iceberg | 技术调研&在各大公司的实践应用大总结

王知无

硬刚用户画像(一) | 标签体系下的用户画像建设小指南

王知无

让数字经济成滇中崛起增长极新引擎

CECBC

关于 vertical-align 你应该知道的一切_语言 & 开发_政采云前端团队_InfoQ精选文章