【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

关于 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:162448

评论 1 条评论

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

中国央行数字货币DCEP——有增值空间吗?

CECBC

linux之zgrep查找压缩包文件文本

入门小站

Linux

OCR+NLP 提取信息并分析,这个开源项目火了!

百度开发者中心

最佳实践 开源技术

第六届世界智能大会平行论坛提前揭晓

InfoQ 天津

网易云信 6 周年|以梦为马,谱写融合通信新篇章

网易云信

云通信 通信云

浅谈如何实现自定义的 iterator

hedzr

stl Iterator c++17

OCR+NLP信息抽取在金融、物流行业的应用

百度大脑

人工智能 百度

泛型原理解析(Review)

Puciu

泛型

优雅代码技巧

十二万伏特皮卡丘

如何成为一个更好的职业人?

石云升

学习笔记 职场经验 10月月更

北森CEO纪伟国:深耕HR SaaS,聚焦场景一体化

海比研究院

微信朋友圈的复杂度分析

胡颖

架构实战营

少吃肉也能减碳排?

脑极体

OpenSearch 文档如何进行编译

HoneyMoose

精益求精,零代码训练营第五期顺利结业

明道云

ES入门教程

阿强

elasticsearch elastic ES

带你了解3类预训练语音模型预测方法

华为云开发者联盟

语音 预训练 语音模型 前文 后文

作业:模块一

奔奔

使用 Spring Boot 和 @DataJpaTest 测试 JPA 查询

码语者

Java Spring Boot test

[ CloudWeGo 微服务实践 - 02 ] 上手

baiyutang

golang 微服务 10月月更

Vue进阶(幺伍肆):vue-resource 应用

No Silver Bullet

Vue vue-resource 10月月更

通过题目来讲一讲计算机系统概述相关知识 3 | 计算机组成与系统结构专题

Regan Yue

计算机组成原理 10月月更

永不落幕的世界智能盛会:天津市工业和信息化局与工商银行天津分行举行对接交流活动

InfoQ 天津

阿里大牛首次公布Java10W字八股文面经,Github访问量破百万

Java 编程 程序员 架构 面试

文本逆序翻转工具

入门小站

工具

CODING 助力江苏高速信息实现组织敏捷与研发敏捷,领跑智慧交通新基建

CODING DevOps

研发敏捷 组织敏捷 自动化发布流程 团队目标一致性 楼宇智能化

Android 音视频 - MediaCodec 编解码音视频

声网

android 音视频 编解码

Python代码阅读(第48篇):返回最大元素的索引

Felix

Python 编程 Code Programing 阅读代码

虚拟人“觉醒”年,见证一场万物的进化

脑极体

科技赋能乡村振兴,农林牧渔如何“拥抱”区块链技术?

CECBC

030云原生之交付部署

穿过生命散发芬芳

云原生 10月月更

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