[译]关于vertical-align:你须要知道的一切

原文:Vertical-Align: All You Need To Knowcss

一般我都有须要垂直对齐在一排上一个接着一个的元素。
CSS提供了不少种可能性。有时,我听过float来解决问题,有时使用position:absolute,有时甚至会经过添加margin或者padding属性这种使代码变得比较脏的方式来达到目的。html

我一点也不喜欢上面这些解决方案。浮动仅仅是顶部对齐而且须要手动清除浮动。绝对定位让元素脱离文档流,因此他们再也不影响他们的周边元素。而使用固定值的外边距和内边距会出现细微的差异。安全

可是这里还有另一种玩法:vertical-align。我认为他值得更多的赞誉。OK,技术上来讲使用vertical-align布局是一种hack的手段,由于他并非由于实现咱们上面那种需求发明的。尽管如此,你也能够在不一样的上下文中使用vertical-align来灵活细致的摆放元素。不须要知道元素的大小。元素在文档流中,也能感知其余元素尺寸的改变。这些都让vertical-align变成了更有价值的选项。布局

独特的vertical-align

可是,vertical-align有时也是个卑鄙小人。使用它工做也会令人有点沮丧。在使用它工做时,这里会有一些使人难以理解的规则。例如,它可能会发生这样的状况,一个元素改变了他本身的vertical-align的值,而他的位置却一点都没有改变,改变的倒是同行的其余元素。我仍然会一次一次被拉入这种奇怪的现象,使我苦恼。字体

不幸的是,大多数资料都讲述的比较浅显。特别是,当咱们想使用vertical-align布局时。他们对最基本的属性进行了介绍而且在简单的例子中解释元素是如何在一行中进行摆放的。可是,他们并无去解释它使人感到奇怪的部分。spa

因此,个人目标是使本身完全弄清楚vertical-align究竟是怎么回事。最后消解我疑问的是W3C's的CSS specifications和标准中演示的一些例子。答案就在文章中。.net

因此,让咱们来解决掉这场关于规则的游戏吧。code

使用vertical-align的要求

vertical-align被用于inline-level elements。这些元素的display属性以下orm

  • inlinehtm

  • inline-block

  • inline-table(这篇文章中,并不考虑这种状况)

基本的inline元素都是标签裹着文字。

inline-block元素:是在行内中的块级元素。他们能够有宽度和高度(一般状况下,这取决于他们的内容)。一样也有padding,margin,border。

行内级元素在一行中一个挨着一个。一旦,这些元素超出了他们的所在行,一个新行便会创建在它下方。这里的每一行就叫作line box。每一行不一样尺寸的元素意味着line box不一样的高度。在下面的例子中红线表明line box的顶部和底部。

line box寻找咱们放置元素的轨迹。在这些line boxes里面vertical-align属性负责摆放单独的元素。因此什么样的元素被用来对齐了呢?

关于基线和边界线

在一行中垂直摆放元素,最关键的参考点是参与的元素的基线。在一些例子中,被关闭盒子的顶部和底部也变得很是重要。让咱们一块儿看看基线和外边缘是如何参与到不一样类型的元素中的。

Inline Element

clipboard.png

这里有三行挨着的文字。顶部和底部的边缘线是行高的边缘线,它们都是红线。字体的高度被绿线包裹着。蓝色的线表明基线。在最左边,文字的行高和字体自己的高度同样高。绿线和红线发生了重叠。在中间,行高是字体大小的2倍高。在最右边,行高是字体大小的一半高。

inline element的外边缘的位置,取决于他们的行高的顶部与底部边缘。若是行高的高度比字体的高度小。那么,红色的外边缘的位置就如上面提到的同样。

inline element的基线,在字符放置的位置。在图中,用蓝线表示。初略的讲,基线的位置通常是在字体高度一半如下的位置。能够看看W3C的标准对它的定义,detailed definition

Inline-Block Element

clipboard.png

从左边到右边的图你能够看到:最左,一个在in-flow内的行内块级元素。中间,一个在文档流中的inline-block元素而且带有overflow: hidden属性的元素。最右,不在文档流中的inline-block元素(可是内容区域有高度)。margin的边界线指向红线,border是黄色的部分,padding是绿色的部分,内容区域是蓝色的部分。每个inline-block元素的基线都用蓝线表示。

inline-block元素的外边缘 是它的margin-box的顶部和底部。在图上,用红线来表示。

inline-block元素的基线 依赖于元素是不是文档流中的元素。

  • 假设内容在文档流中,inline-block元素的基线是普通流中的最后一个内容元素的基线(最左的例子)。对于最后一个元素的基线根据它本身的规则来找寻。

  • 假设内容在文档流中,可是元素有overflow属性除了属性值为visible这种状况,基线在margin-box的底部(最中间的例子)。因此,这等同于在inline-block元素的底部边缘。

  • 假设内容不在文档流中,一样的,margin-box的底部边缘也是基线的位置所在。(例子在最右边)

Line Box

clipboard.png

你已经看到了上面元素的放置。此次,我画了line box的text box顶部和底部的线(如图中的绿线,更多内容看下文),基线如图中蓝色的线。我在文字元素上加了灰色的背景进行强调。

line box的顶部边缘与最顶部元素的顶线对齐,底部边缘与最底部元素的底线对齐。图中红线表明的就是line box。

line box的基线是多种多样的

“CSS2.1 并无对line box基线的位置有明确的定义。-W3C Specs

当使用vertical-align工做时,这多是最使人迷惑的部分。这意味着,基线的位置改变是为了知足像垂直对齐和下降line box的高度这样的需求的。也就是说,在方程中,这是一个自由的参数。

由于line box的基线是不可见的,所以它的位置并不会那么明显。可是,你能够容易的使它变得可见。只须要在一行的开头加上一个字母,就像我在图中添加的字母"x"。若是这个字母并没排在一条直线上,那么x坐落的位置就是基线的位置。

在line box基线的周围有text box。text box能够简单的被认为是在line box中的行内元素。它的高度等同于它的父元素的文字大小。所以,text box仅仅只是围绕着line box的非格式化文字。这个盒子在上图中是指向绿线的位置。text box与基线的位置相关联,它随着基线而移动。

哦,如今是最难的部分。如今,咱们把知道的全部事,都表如今了上图中。让咱们快速的总结最重要的部分:

  • 这里有一个区域被叫作line box。这是元素垂直对齐的区域。它有一个基线和一个text box以及顶部与底部边缘。

  • 这里有inline-level元素。他们是被对齐的对象。他们有基线以及顶部与底部边缘。

Vertical-Align的值

经过使用vertical-align的参考点,也就是上文提到的基线和边界线,将元素放置在合适的位置。

相对于line box的基线放置元素的基线

clipboard.png

  • baseline: 元素的基线恰好放置在line box基线的上。

  • sub: 元素的基线放置在line box基线的下面。

  • super: 元素的基线放置在line box的基线的上面。

  • <percentage> 元素的基线移动相对于line box的基线经过相对于line-height的百分比的值来移动。

  • <length>: 元素的基线相对于line box的基线经过绝对值的大小进行移动。

相对于line box的基线放置元素的外边缘

clipboard.png

  • middle: 元素的顶部与底部边缘的中点相对于line box的基线移动x-height的一半的位置对齐。

相对于line box的text box放置元素的外边缘

clipboard.png

  • text-top: 元素的顶部边缘被放置在line box的text box的顶部边缘

  • text-bottom: 元素的底部边缘被放置在line box的text box的底部边缘

相对于line box的外边缘放置元素的外边缘

clipboard.png

  • top: 元素的顶部边缘被放置在line box的顶部边缘

  • bottom: 元素的底部边缘被放置在line box的底部边缘

在W3C标准中的定义

Vertical-Align的行为就如它的表现同样

如今,咱们能够在具体的例子中看垂直对齐。特别是,处理一些比较容易出现差错的状况。

放置icon在中间

这是一个一直以来都令我烦恼的事情:我有一个icon我想将它放置在一行文字的中间。只只仅仅将icon设置vertical-align: middle,看起来彷佛不是一个安全的方法。看下面的例子。

clipboard.png

<!-- left mark-up -->
<span class="icon middle"></span>
Centered?

<!-- right mark-up -->
<span class="icon middle"></span>
<span class="middle">Centered!</span>

<style type="text/css">
  .icon   { display: inline-block;
            /* size, color, etc. */ }

  .middle { vertical-align: middle; }
</style>

这里也是上面这个例子,不过,此次我加了一些你从上文了解到的辅助线,

clipboard.png

这有助于帮咱们理解。由于在左边的文字并无对齐元素,而是被放置在基线所处的位置。经过使用vertical-align:middle来对齐盒子,咱们将只是将盒子放置在了小写字母的中间。因此,出头部分的字母出如今顶部。

在右边,咱们将所有文字区域放置在垂直方向的中点。经过移动text的基线到line box的基线的下方来实现。结果是文字完美的居中于紧挨着的icon。

移动line box的基线

当咱们使用vertical-align工做时,容易遇到的一个共同的问题:line box的基线会被在同一行中全部元素影响。让咱们猜一猜,一个元素有可能在这样被对齐的,经过移动line box的基线。由于大多数垂直对齐(除了顶部和底部)都是相对于基线,这也会致使在同一行的的全部元素的位置都会被调整。

一些例子:

  • 若是在一行中,有一个高的元素占据了整行的高度,vertical-align对它不会有任何影响。在它的顶部上面与底部下面没有任何多余的空间能够移动它。为了实现它相对于line box基线的对齐,line box的基线必须移动。矮一点的盒子设置了vertical-align: baseline。在左边,高盒子根据text-bottom对齐。在右边,根据text-top对齐。你能够看到矮盒子的随着基线位置的改变而改变。

clipboard.png

<!-- left mark-up -->
<span class="tall-box text-bottom"></span>
<span class="short-box"></span>

<!-- right mark-up -->
<span class="tall-box text-top"></span>
<span class="short-box"></span>

<style type="text/css">
  .tall-box,
  .short-box   { display: inline-block;
                /* size, color, etc. */ }

  .text-bottom { vertical-align: text-bottom; }
  .text-top    { vertical-align: text-top; }
</style>

经过其余vertical-align的值对齐高的元素,也会出现和上面的例子相同的行为。

  • 一样的给它设置vertical-align的值分别设为leftbottom移动基线。而这很奇怪,由于基线本不该该参与。

<!-- left mark-up -->
<span class="tall-box bottom"></span>
<span class="short-box"></span>

<!-- right mark-up -->
<span class="tall-box top"></span>
<span class="short-box"></span>

<style type="text/css">
  .tall-box,
  .short-box { display: inline-block;
               /* size, color, etc. */ }

  .bottom    { vertical-align: bottom; }
  .top       { vertical-align: top; }
</style>

clipboard.png

<!-- left mark-up -->
<span class="tall-box bottom"></span>
<span class="short-box"></span>

<!-- right mark-up -->
<span class="tall-box top"></span>
<span class="short-box"></span>

<style type="text/css">
  .tall-box,
  .short-box { display: inline-block;
               /* size, color, etc. */ }

  .bottom    { vertical-align: bottom; }
  .top       { vertical-align: top; }
</style>
  • 在一行中,放置两个大致积元素而且移动基线垂直对齐他们以此知足同时对齐。line box的高度被调整(左边的例子)。添加第三个元素,它并有跑到line box的边缘由于它的对齐属性,既没有影响line box的高度,也没有影响line box基线的位置(中间的例子)。若是它真的跑到了line box的边缘,咱们的前两个盒子会被往下推(最右的例子)。

clipboard.png

<!-- left mark-up -->
<span class="tall-box text-bottom"></span>
<span class="tall-box text-top"></span>

<!-- mark-up in the middle -->
<span class="tall-box text-bottom"></span>
<span class="tall-box text-top"></span>
<span class="tall-box middle"></span>

<!-- right mark-up -->
<span class="tall-box text-bottom"></span>
<span class="tall-box text-top"></span>
<span class="tall-box text-100up"></span>

<style type="text/css">
  .tall-box    { display: inline-block;
                 /* size, color, etc. */ }

  .middle      { vertical-align: middle; }
  .text-top    { vertical-align: text-top; }
  .text-bottom { vertical-align: text-bottom; }
  .text-100up  { vertical-align: 100%; }
</style>

解开Vertical-Align的神秘面纱

当你知道了规则,这就没那么复杂了。若是vertical-align并无按照你想的那样行动,问本身两个问题:

  • line box的顶部与底部边缘和基线在哪里?

  • inline-level元素的顶部与底部边缘和基线在哪里?

这将解决你的问题。

相关文章
相关标签/搜索