NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

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

评论 1 条评论

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

设计模式-策略模式

黑客不够黑

设计模式 策略模式

Go语言实现策略模式

黑客不够黑

策略模式

深圳.NET线下技术沙龙倒计时一天

MASA技术团队

.net MASA

Matlab常用图像处理命令108例(七)

timerring

图像处理

低代码四大典型使用场景,你都知道吗?

SoFlu软件机器人

使用 Athena (Presto) 分析本地 Oracle 数据库导出的数据

亚马逊云科技 (Amazon Web Services)

视频下载软件:MediaHuman YouTube Downloader 中文版

真大的脸盆

Mac 视频下载 Mac 软件 下载视频 视频下载工具

PyTorch深度学习实战 | 基于ResNet的人脸关键点检测

TiAmo

深度学习 人脸识别 PyTorch

内部开发者门户是什么?

SEAL安全

微服务 企业号 3 月 PK 榜 内部开发者门户 信息碎片化

Nacos心跳机制实现快速上下线

做梦都在改BUG

Java Spring Cloud nacos 心跳机制

Next.js 实践:从 SSR 到 CSR 的优雅降级

Crazy Urus

React nextjs SSR

NodeJS 实战系列:模块设计与文件分类

光毅

JavaScript node.js

vivo 短视频用户访问体验优化实践

vivo互联网技术

CDN HTTP 优化 DNS 实践

使用价值三角方法来全方位分析产品

产品海豚湾

产品 产品经理 产品设计 产品运营 商业洞察

想到哪说到哪的AI

FN0

AIGC

如何测试一个AI系统?

陈磊@Criss

AI 测试

"鸿蒙生态专家面对面"三月专场等你前来!

HarmonyOS开发者

优秀软件工程师必备的五大技能,快看你还差什么?

SoFlu软件机器人

百度生成式AI产品文心一言邀请测试,五大场景、五大能力革新生产力工具

飞桨PaddlePaddle

百度 飞桨 文心一言

如何应用BI系统运营提效,一起看看瓴羊Quick BI的表现

对不起该用户已成仙‖

Toast的基本使用

智趣匠

android Adapter toast

索信达再度打造智能营销标杆案例,这次是头部券商!

索信达控股

Capital

Echo_Wish

学习 进步 笔记 资源 本质

【微电平台】-高并发实战经验-奇葩问题解决之旅

京东科技开发者

架构 服务端 js 平台

MongoDB源码学习:执行创建Collection命令

云里有只猫

mongodb 源码解析

如何快速理解网络IO模型

Dinfan

Netty 事件循环 IO模型 Reactor多线程 网络io模型

Spring Boot中如何优雅地实现异步调用?

JAVA旭阳

Java springboot

在追求卓越的路上,面对压力时,推荐你这二个做法。

叶小鍵

在 windows 上连接 wsl 和直接打开 ubantu 有什么区别?

玄兴梦影

wsl window

聊聊「订单」业务的设计与实现

Java 架构 订单管理 订单系统 订单

100Wqps短链系统,怎么设计?

小小怪下士

Java 程序员 后端 QPS

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