[翻译]关于Vertical-Align你须要知道的事情

写在前面的话

开始学习前端以来,在CSS相关知识当中困扰我最多的就是Vertical-Align这个属性。在stackoverflow上查找相关问题的时候看到了这篇文章,因而将它翻译出来,做为本身的一次学习笔记吧。css

正文

在遇到将元素在垂直方向上对齐的需求时,CSS提供了多种方法,有时候我用float解决,有时候我使用position:absolute解决,还有时候采用的方法是手动调整marginpadding
其实我并不喜欢这些解决方法,float会让元素的顶端对齐并且须要手动清楚浮动。绝对定位让元素脱离了正常流,这样这些元素就不会再影响到周围的元素。在元素的paddingmargin固定的状况下,一点小的改变也颇有可能对布局形成影响。
接下来登场的就是本文的主角了:Vertical-align。一般来讲使用这个属性进行布局是一种hack行为,由于它原本并非被用于这个目的。它用在文本和与文本相邻元素的垂直方向上的对齐问题。然而,你也可使用Vertical-align在不一样的上下文中对元素进行灵活的,细粒度的排布。元素的尺寸无需知晓,元素任然处于正常流当中,所以元素的变化会影响到周围的元素,这使得Vertical-align是很是有价值的排布方案的选择。html

Vertical-align的奇特之处

Vertical-align有时候会变的面目狰狞。它彷佛有一些谜同样的规则。举例来讲,有时候你改变了Vertical-align的值,可是该元素垂直方向上没有发生改变反而别的元素改变了位置。
一些资料在谈到Vertical-align这个问题的时候深刻程度不够,特别是当人们想使用这个属性布局的时候。这些资料更多的将精力集中在了一个误区上,就是尝试将元素内的一切都垂直对齐。他们给出了一下在简单状况下的例子来解释Vertical-align这个属性而忽略了一些复杂奇怪的方面。前端

使用Vertical-align的要求

Vertical-align被用于垂直对齐inline元素,也就是display值为inlineinline-block的元素。inline-table的元素不在本文的讨论范围内。
inline元素基本上值得就是文本
inline-block元素就像它的名字同样,同时具有inline元素和block元素的特色,这样的元素有padding,margin,border,width,height。其中高度有多是由元素的内容决定的。
inline元素一个挨着一个的摆放在行内,当行内元素太多的状况下,一个新行会被建立出来,这些行也叫作line--box。它将行内的全部内容都包裹了起来。根据行内内容的不一样,line-box的尺寸也会不一样,在接下来的图里面,红线表明了line-box的上下边界图片描述
在这些line-box内,Vertical-align属性负责对齐一些独立的元素。那么,这些元素是要和谁对齐呢?ide

关于边界和baseline

对于垂直对齐这个知识点来讲最重要的就是涉及元素的baseline。有时候元素的盒模型的上下边界也会变的很重要。下面上图
图片描述
如图所示有三行文字。行高的上下边界是红线。文字的上下边界是绿色的线,蓝色的线就是baseline了,左边文字的高度与行高是一致的,所以绿线和红线重合了,中间的行高是文字大小的两倍,而在右边,行高是文字大小的二分之一。
行内元素的外边缘在行高的上边缘和下边缘这个范围内对齐,若是行高小于文字的高度也无所谓。关于baseline的定义仍是直接给出标准的连接布局

inline-block元素

图片描述
从左到右的三幅图片都是inline-block元素,不一样的是,左面包含着没有脱离正常流的内容c,中间的除了没有脱离正常流的内容之外还加了overflow:hidden,右面的没有内容可是内容区还有高度。红线表明了margin-box的边界。黄色表明的是border,绿色的是padding,蓝色的是content,蓝色的线表明的仍是baseline。
inline-block元素的外边缘就是margin-box的边缘。
inline-block元素的baseline的位置要看该元素有没有处于正常流以内的内容。
(1)在有处于正常流内容的状况下,inline-block元素的baseline就是最后一个做为内容存在的元素的baseline,这个元素的baseline的肯定就要根据他自身来肯定了。
(2)在overflow属性不为visible的状况下,baseline就是margin-box的下边界了。
(3)第三种状况下baseline仍是margin-box的下边界。学习

line-box

图片描述
关于line-box的图上面已经给过了,此次我将文字部分高亮显示。line-box的上边界与最高元素的上边界对齐,下边界与最低元素的下边界对齐。
W3C标准中并无定义line-box的baseline的位置。这一点很让人困惑,baseline的位置须要知足vertical-align属性的值以及让line-box的高度最小等条件,是一个很灵活的参数。
line-box的baseline是不可见的,可是能够很轻松的将它可视化出来,在行的开头添加一个字母,好比'x',这个字母的下边界默认就是baseline的位置。围绕着baseline在line-box中造成了文字盒。文字盒能够被认为是没有和任何元素对齐的line-box中的inline元素,它的告诉与它的父元素的font-size的值相同。所以,文字盒仅仅包含非格式化的line-box的文本,文字盒的边界由绿线来表示。由于文字盒是紧挨着baseline的,因此baseline的位置发生变化的话,文字盒的位置也会跟着改变(这里所说的文字盒在标准中被叫作strut)。
总结起来的话有如下两点:spa

  • 有一个区域叫作line-box,垂直方向上的对齐都是发生在这个区域里面,它有baseline,有文字盒,有上下边界。
  • inline元素也有baseline和上下边界,inline元素是须要对齐的对象。

Vertical-align属性的值

图片描述
有关Vertical-align各个取值的说明读者仍是上MDN看吧。也能够看看天镶大神的博客上的文章.net

Vertical这个属性究竟是怎么起做用的呢?

对齐一个Icon

我想将一个icon与文字对齐仅仅使icon的vertical-align属性的值设置为middle彷佛不能产生使人满意的结果,例子以下图
图片描述翻译

<!-- 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>

下面给出上图的辅助线版本
图片描述
缘由就是左面的文字根本就没有发生对齐行为,它仍是对齐于line-box的baseline。而vertical-align对齐的点是baseline加上半个x的距离(half of the x-height)。所以文字的最高点超过了icon的高度。
而右面的例子,文字与icon都对齐于一个中点,文字的baseline稍微下移,位于line-box的baseline的下方。结果是很好的达到了icon与文字对齐的效果。3d

line-box的baseline的移动问题

这是一个Vertical-align的坑,line-box中的全部元素都会影响到baseline的位置。假设,一个元素按某种方式垂直对齐了,可是这种对齐方式会引发baseline的移动,又由于大部分的垂直对齐方式(除了top和bottom)和baseline有关,所以这个元素的垂直方向对齐的行为会引发该line-box内其余元素位置的调整。
下面仍是一些例子

  • 一个很高的元素,其高度占满了整个line-box,那么vertical-align对其实没有影响的,在它的top和bottom以外没有空间让其移动。可是为了知足它的vertical-align的值,line-box的baseline会发生移动,左面的高元素的取值为text-bottom,矮元素的取值为baseline。右面的高元素的取值为text-top,你会看到baseline跳上去了
    图片描述
<!-- 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设置为bottom或者是top也会让baseline发生移动。这很奇怪,由于这时候应该就没baseline什么事儿了。
图片描述

<!-- 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里面,而且设置vertical-align的值让line-box的baseline移动。在知足vertical-align数值对齐的条件下,line-box的高度会自我调整,如左面的图。再增长第三个元素,第三个元素若是由于其vertical-align的设置不会超过line-box的边缘的话,它是不会影响到line-box的高度和baseline的位置的,若是它会超过line-box的边缘,那么line-box的高度和baseline的位置也会进行调整。在第二种状况下,另外两个元素的位置发生了下移。
图片描述

<!-- 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>

inline元素下方可能会有一点空隙

下面给出一个例子,若是尝试将li元素在垂直方向上进行对齐的话在,这个现象很是常见。
图片描述



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

正如你所见,li元素是对齐baseline的,baseline的下方会给字母的一部分留出空间,所以会产生一个空隙。解决方案就是改变line-box的baseline的位置,好比将这些li这是为vertical-align:middle



<ul> <li class="box middle"></li> <li class="box middle"></li> <li class="box middle"></li> </ul> <style type="text/css"> .box { display: inline-block; /* size, color, etc. */ } .middle { vertical-align: middle; } </style>

inline元素之间的空隙形成布局效果与理想状态发生误差
这主要是由于inline元素自己的缘由,可是由于若是要让vertical-align的值产生做用的话,inline元素是必备要求,所以了解一点也不错嘛
这个空隙来源于inline元素之间的空格,全部的inline元素之间的空白都会变成一个空格。若是你想让inline元素在水平上紧挨着,设置它们的宽度是不行的。由于之间存在空隙,因此行的宽度不够放下两个inline元素。一行会被破坏为两行。解决方案以下图的右侧
图片描述

<!-- left mark-up -->


<div class="half">50% wide</div>




<div class="half">50% wide... and in next line</div>


<!-- right mark-up -->


<div class="half">50% wide</div>

<!--
-->

<div class="half">50% wide</div>


<style type="text/css">
  .half { display: inline-block;
          width: 50%; }
</style>

注意

两个建议,若是vertical-align属性不起做用,那么问问本身:

  • line-box的上下边缘以及baseline的位置在哪里?
  • inline元素的上下边缘以及baseline的位置在哪里?
相关文章
相关标签/搜索