前言
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 boxcontaining 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 的默认值,其意思是指基线对齐
这里就涉及到了 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 底部部对齐。
例子如下:
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:任意一个块级元素,里面若有图片,则块级元素高度基本上都要比图片的高度高
产生这种现象的原因:空白节点、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:近似垂直居中
如图所示(为了更明显我使用了色块来标识),当子元素(图片)设置了 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,所以可以忽略这个问题啦。
总结
本文讲解了 vertical-align 的基本属性以及各种表现,同时对一些实际应用中 vertical-align 无效现象做了简单的分析阐述,并为解决此类问题提供了思路。
头图:Unsplash
作者:润瑞
原文:https://mp.weixin.qq.com/s/vk6qCqTf3B4PSIKQGQoMEA
原文:关于 vertical-align 你应该知道的一切
来源:政采云前端团队 - 微信公众号 [ID:Zoo-Team]
转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
评论 1 条评论