【ArchSummit】如何通过AIOps推动可量化的业务价值增长和效率提升?>>> 了解详情
写点什么

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

评论 1 条评论

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

一物一码需求,标签制作功能轻松解决

草料二维码

二维码 二维码生成 标签制作 一物一码

Mac 版截图工具链

Eric 老乌龟

macos 工具

销售易取得500强客户背后的实践与进化

B Impact

哪些行业发展需要用到代理IP?罗拉ROLA-IP告诉你什么是专业

Geek_bf375d

【Data & AI Con Shanghai 2023】嘉宾专访|西电王皓:认清边界 大胆创新

白玉兰开源

人工智能 白玉兰开源

inBuilder低代码平台新特性推荐-第5期

inBuilder低代码平台

低代码

喜报 | MIAOYUN通过2023年度四川省“专精特新”中小企业认定!

MIAOYUN

专精特新 MIAOYUN 高新技术企业 专精特新中小企业 专精特新企业

软件测试/测试开发丨性能测试体系学习笔记

测试人

软件测试

Python 机器学习入门:数据集、数据类型和统计学

小万哥

Python 程序员 软件 后端 开发

领跑同一阵营!百分点科技入选Forrester AI/ML权威报告

百分点科技技术团队

人工智能 数据科学 百分点科技

华为云开源 | 线下meetup · 电子科技大学站圆满收官

华为云开源

云原生 开源项目 开源社区

ROLA-IP海外IP代理为第四届全球跨境电子商务大会注入活力

Geek_bf375d

8款好用的笔记软件,让你的读书笔记独一无二!

彭宏豪95

读书笔记 效率 软件推荐 在线白板 笔记软件

Go类型嵌入介绍和使用类型嵌入模拟实现“继承”

快乐非自愿限量之名

Go 编程 教程 语言 教程分享

Unity中国全面支持OpenHarmony游戏开发,多款游戏率先完成适配

最新动态

荣誉 | 观测云登榜「2023 中国好 SaaS TOP 10 SaaS 企业 」

观测云

可观测性 SaaS

“箭在弦上”的边缘计算,更需要冷静和智慧

脑极体

服务器

海外IP代理rola-ip表现突出,全球覆盖面广,技术支持优秀

Geek_bf375d

IP代理哪家好用? 必看经典文

Geek_bf375d

Linux cat命令

智趣匠

聊聊低代码技术

互联网工科生

软件开发 低代码

分布式AI在LLM时代的技术深度探索

不在线第一只蜗牛

人工智能 AI lee

OpenAI 深夜炸场,更强更便宜;英特尔 CEO 分享三大失败原因;黄仁勋说成龙长得像他丨 RTE 开发者日报 Vol.79

声网

云电脑与5G网络的结合将会带来什么

青椒云云电脑

云电脑

投资机构Janus Capital Group为Rola-IP品牌融资700万美元

Geek_bf375d

剑指数据结构—实现动态数组

少年游侠客

数据结构 数组 ArrayList Java’

矢量图设计软件层出不穷,CorelDRAW为何无人能替?

淋雨

设计 矢量图 CorelDraw 绘画 设计软件

低代码工具的常见用例与受众市场

树上有只程序猿

低代码

瓴羊X阿里云上的Salesforce联合解决方案正式发布

ToB行业头条

macOS 14 Sonoma 14.1.1正式版(最新苹果系统) pkg完整安装包

Rose

苹果系统 macOS 14 Sonoma Mac14系统

海外HTTP代理哪家最好用?Rola-IP与StormProxies的全方位数据对比

Geek_bf375d

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