Vertical-Align: 你需要知道的所有事【译】_html/css_WEB-ITnose
Vertical-Align: 你需要知道的所有事
原文地址: Vertical-Align: All You Need To Know
我经常需要垂直对齐元素。
CSS提供了一些可能的方法。有时我用 float 解决它,或使用 position: absolute; ,还有时甚至要恶心地手动添加 margin 和 padding 。
我不是真的喜欢这些解决方案。 float 只能对准在其顶部而且需要手动清除。绝对定位将元素从文档流中抽离出来,这样它们就不再能撑开(影响)其包含块。使用固定的 margin 和 padding 则很容易被微小的变化所破坏。
但这里有另一个方法: vertical-align ,我认为它值得得到更多的信赖。从技术上讲,使用 vertical-align 布局是一种hack方式,因为它不是为这个原因发明的。它的存在是为了对齐文本和文本旁的元素。尽管如此,你也可以在不同的上下文中使用 vertical-align 来非常灵活和精准地对齐元素。优点是元素的大小不需要知道,且留在文档流中,所以其他元素(包含块)可以响应布局尺寸的改变,这使它成为一个有价值的选择。
vertical-align的独特性
但是, vertical-align 有时会相当卑鄙,并使你感到沮丧。在工作中似乎有一些神秘的规则,例如,这种情况经常发生,被改变了 vertical-align 的元素并没有改变它的对齐方式,但同一行的其他元素却改变了!我有时仍然被 vertical-align 拖到黑暗的角落并撕扯头发。
不幸的是,大部分关于这个的教程都有点浅,特别是如果我们要使用 vertical-align 来布局。大多数人专注于尝试垂直对齐元素的一些误解,他们给出基本的介绍,并解释在非常简单的情况下如何对齐元素,但没有解释棘手的部分。
所以,我给自己定了个目标: 彻底弄清楚 vertical-align 的行为 ,不留下历史问题。我最终通过W3C的 CSS 规范 和试验一些例子得到了结果——这篇文章。
使用vertical-align的要求
vertical-align 用来调整 inline 级元素。这些元素的 display 属性为:
- inline
- inline-block
- inline-table(本文不涉及)
inline元素基本上是文本的包裹标签。
inline-block元素正如它们的名字:住在行内的块元素。他们可以有一个width和height(也可能由它内部内容撑开),以及padding、border和margin。
inline元素逐个从左到右地被放置在一行内。一旦有更多的元素加入,使当前行无法放下,一个新的行就会在下方产生。所有这些行有所谓的 line box ,其中包含所有的内容。不同尺寸的内容意味着不同高度的line box。在下图中,line box的顶部和底部是红色线表示的:
line box描绘出了我正在试验的区域。在这些line box中,属性 vertical-align 是负责调整单个元素的。 所以,元素对齐跟什么相关?
关于baseline和外边缘
垂直对齐最重要的关注点是要对其元素的baseline。在某些情况下,元素的包围盒的顶部和底部的边缘也变得很重要。让我们来看看每种类型的元素baseline和外边缘在哪里:
inline元素
在这里你看到三行的文本相邻排布。行高的顶部和底部是由红线表示的,字体的高度是由绿线来表示的,而baseline是由蓝线表示的。在左边,文本具有一个与字体大小相同的行高,绿色和红线在上下都重叠了。在中间,行高(line-height)是字体大小的两倍大。在右边,行高是字体大小(font-size)的一半。
inline元素的外边缘跟自己line-height的顶部和底部边缘对齐,如果line-height小于font-size的话也不会改变。所以,在上面的图中的行的外边界是红线。
inline元素的baseline字符底部所坐的线,就是图中的蓝线。粗略地说,baseline是在font-size中间下面的一个地方,看看W3C规范的 详细定义 。
inline-block元素
从左到右,你看到的是一个拥有 流 内容(一个“c”)的inline-block元素,一个拥有流内容且 overflow: hidden; 的inline-block元素和一个没有流内容的inline-block元素(但内容区域有一个高度)。margin的边界由红线表示,以及黄色的border,绿色的padding和蓝色的内容区域,蓝线是每个inline-block元素的baseline。
inline-block元素的外边缘是其 margin-box 的顶部和底部边缘,即图中的红线。
inline-block的baseline取决于元素是否具有流内容:
- 在流内容的情况下,inline-block元素的baseline是正常流的最后一个内容元素的baseline(左边的例子)。对于这最后一个元素,它的baseline位置由它自己的规则决定。
- 在流内容,但具有overflow:hidden的情况下,baseline是margin-box的底边缘(中间的例子),也相当于inline-block元素的底边缘。
- 如果没有流内容,则跟上一个一样,baseline位于margin-box的底边缘(右边的例子)。
line box
你已经看过了这张图上面的设置,这一次,我画出了line box的text box的顶部和底部边缘(绿线,下文也是)以及baseline(蓝线)。我还给该区域的文本元素添加了一个灰色的背景来强调他们。
该line box具有一个与该行最顶的元素的顶部边缘对齐的 顶部边缘 和一个与该行最底的元素的底部边缘对齐的 底部边缘 ,即是上面图中的红色线所表示的盒子。
line box的baseline是可变的:
CSS 2.1并没有定义line box的baseline. —- W3C规范
这可能是使用vertical-align时最令人困惑的部分。意思是,baseline的位置要在满足所有其他条件,如vertical-align设置和最小化line box的高度的前提下来决定,是方程中的一个*参数。
由于line box的baseline是不可见的,无法直观感知。但是,你可以很容易地让它变得可见。通过在行的开头加一个字符,比如上图中的字母“×”。如果这个字符没有以任何方式进行对齐,则默认情况下其底部将坐在baseline上。
在其baseline的基础上,line box有一个称为 text box 的东西。该text box可以简单地被认为是line box中一个没有任何对齐的inlne元素。它的高度等于它的父元素的font-size。因此,text box只包裹住line box中的无格式文本,由上图中的绿线表示。因为这个text box位置基于baseline,所以它会随baseline移动。(注:此text box在W3C规范中称为 strut )
唉,这是最难的部分。现在,我们拥有了分析原理的所有前提条件,让我们迅速总结最重要的事实:
- 有一个区域称为 line box ,这是要对齐的区域。它有一个 baseline ,一个 text box 和一个 顶部 和 底部边缘 。
- 有 inline级元素 。这些是要被对齐的对象。他们有一个 baseline 和一个 顶部 和 底部边缘 。
vertical-align的取值
从上面的列表总结出来的使用 vertical-align 的要点中,我设置了几种关系样例。
将元素的baseline与line box的baseline对齐
- baseline:该元素的baseline恰好与line box的baseline重合。
- sub:该元素的baseline偏移到line box的baseline下方。
- super:该元素的baseline偏移到line box的baseline上方。
- :该元素的baseline以line-height高度乘以百分比的距离相对于line box的baseline偏移。
- :该元素的baseline以绝对长度相对于line box的baseline偏移。
将元素的外边缘与line box的baseline对齐
- middle:元素的顶部和底部边缘的中点与line box的baseline加上1/2小写字母x高度的位置对齐。
将元素的外边缘与line box的text box对齐
这2种情况也可以以相对于line box的baseline对齐的方式展现出来,因为text box的位置是由baseline确定的。
- text-top:该元素的顶部边缘与line box的text box顶部边缘对齐。
- text-bottom:该元素的底部边缘与line box的text box的底部边缘对齐。
将元素的外边缘与line box的外边缘对齐
- top:元素的顶部边缘与line box的顶部边缘对齐。
- bottom:该元素的底部边缘与line box的底部边缘对齐。
正式的定义 可以在W3C规范中找到。
为什么vertical-align以这种规则表现
我们现在可以在特定情况下来研究一下垂直对齐,特别是有可能会出错的情况。
居中一个图标
下面这个问题曾经烦扰了我:我想把图标与旁边的一行文本垂直居中对齐,只是给图标设置 vertical-align: middle; 似乎并没有如设想的一样居中。看看底下这个例子:
推荐阅读
-
Web前端切图你需要知道的几件事情_html/css_WEB-ITnose
-
Vertical-Align: 你需要知道的所有事【译】_html/css_WEB-ITnose
-
Vertical-Align: 你需要知道的所有事【译】_html/css_WEB-ITnose
-
Web前端切图你需要知道的几件事情_html/css_WEB-ITnose
-
极简Node教程-七天从小白变大神(三:你所不知道的模板表单)_html/css_WEB-ITnose
-
极简Node教程-七天从小白变大神(三:你所不知道的模板表单)_html/css_WEB-ITnose
-
你需要知道的Sass插值_html/css_WEB-ITnose
-
【译】一些你不知道的CSS属性(已发布)_html/css_WEB-ITnose
-
你需要知道的Sass插值_html/css_WEB-ITnose
-
[译] 你所不了解的 querySelector_html/css_WEB-ITnose