CSS深入理解vertical-align和line-height的基友关系

来源:互联网 发布:java redis队列使用 编辑:程序博客网 时间:2024/05/14 13:48

本来以为今天又要到家十来点,蹲在我的小窗户前吭哧吭哧写笔记,没想到这会儿我负责的两个页面,接口都挂了,咩哈哈,不用回家顿小窗台了,咩哈哈哈~

俗话说,死宅腐女还有啥来着注定单身狗,反正这三样我确实是全占了的,非常愿意研究基腐问题,科科。

那么看看CSS届的vertical-align和line-height,就是典型的表面上看上去大相径庭,实际上是大进后庭的断背好基友!

表现明显的断背基情

众所周知,vertical-align支持很多属性值:

/* 关键字值 */vertical-align: baseline;vertical-align: sub;vertical-align: super;vertical-align: text-top;vertical-align: text-bottom;vertical-align: middle;vertical-align: top;vertical-align: bottom;/* <长度> 值 */vertical-align: 10em;vertical-align: 4px;/* <百分比> 值 */vertical-align: 10%;/* 全局值 */vertical-align: inherit;vertical-align: initial;vertical-align: unset;

其中,有个属性值暴露了vertical-align和line-height之间的基友关系~~~

没错,就是“百分比值”。

vertical-align的百分比值不是相对于字体大小或者其他什么属性计算的,而是相对于line-height计算的。举个简单的例子,如下CSS代码:

{  line-height: 30px;  vertical-align: -10%;}

实际上,等同于:

{  line-height: 30px;  vertical-align: -3px;    /* = 30px * -10% */  }

CSS属性何其多,偏偏跟line-height有一腿,这不是有基情那是什么?

背地里无处不在的基友关系

注意,vertical-align和line-height的地下基友关系从HTML5文档声明开始的,因此,以下探讨的现象,都是在页面为HTML5声明前提下,类似下面的doctype:

<!doctype html><html>

另外,下面很多效果直接就是真实演示,因此,请使用现代浏览器观摩下面的内容。如果发现某些行为与描述不匹配,且浏览器正常,那可能是因为你访问的并不是原出处。

① 基本现象
要八卦vertical-align和line-height之间的关系,我们不妨从一个极其简单的现象入手。假设,我们有一个<div>标签,然后,里面有一张<img>图片,我们的HTML代码就是这样子:

<div><img src="mm1.jpg"></div>

如图:
这里写图片描述
恩,看上去很正常,一切都是理所当然。然而,如果我们给这个<div>元素增加一个背景色,例如粉色:

<div style="background-color:pink;"><img src="mm1.jpg"></div>

则会是下面这样:

这里写图片描述

会发现图片下面有一段空白空间:
这里写图片描述

想必大家都遇到过类似问题,不知大家有没有思考过,为什么图片下面有留有一段间隙呢?

实际上,这段空白间隙就是vertical-align和line-height携手搞的鬼!

首先,大家一定要意识到这么一点:对于内联元素,vertical-align与line-height虽然看不见,但实际上「到处都是」!

因此,对于内联元素各种想得通或者想不通的行为表现,基本上都可以用vertical-align和line-height来解释,以及进行行为矫正,然而,要深入理解这些行为表现,还是需要狠花一番功夫的,因此,下面的内容,请确保你有半小时充足时间细细阅读,别的地方可是看不到的。

② 幽灵空白节点

「幽灵空白节点」这个概念是张鑫旭命名的,是我自己便于理解某些行为特征提出的概念。规范可能有类似的概念,但名称并非这个。 W3C规范虽然有很多行为的解释和说明,但是,毕竟官方的东西,要求严谨正式,但是,也会有太干太涩的感觉。如果快速掌握和理解这些行为表现呢?就个人而言,从两方面入手:1.情感化认知;2. 具象化思维。

例如,称vertical-align和line-height为好基友(包括以前称浮动和绝对定位是兄弟),就是“情感化认知”;而这里的「幽灵空白节点」就是“具象化思维”。

那「幽灵空白节点」是个什么意思呢?

在HTML5文档声明下,块状元素内部的内联元素的行为表现,就好像块状元素内部还有一个(更有可能两个-前后)看不见摸不着没有宽度没有实体的空白节点,这个假想又似乎存在的空白节点,我称之为“幽灵空白节点”。

抽象了这个概念,绝对定位与text-align的一些行为表现,以及这里的行为表现,就好理解了。

还是上面的图片下边缘留空隙的例子,实际上,这种行为表现,就跟图片前面或者后面有一个宽度为0的空格元素表现是一致的。但是,空格是透明的,为了便于大家理解,我就直接使用很明显的匿名inline box, 也就是字符代替。如下,大家会发现,图片下面的间隙,依旧是那个间隙。

这里写图片描述

啊 ,截图多了一条白色,大家就当看不见奥….

下面要解释这个间隙就好解释了。下面,我们让新增的文本inline-block化,然后弄个白色背景,显示其占据的高度。
这里写图片描述

会发现,图片下面的间隙,依旧是那个间隙。但是,我们的理解就好理解了。回答下面几个问题,我们就知道表现的原因了:

  1. vertical-align默认的对齐方式是?
  2. 后面zxx文字的高度从何而来?

上面2个问题就很简单了:

vertical-align默认值是baseline, 也就是基线对齐。而基线是什么,基线就是字母X的下边缘。所以,乌姆奇奥拉图片的下边缘就和后面ZEro中的字母x下边缘对齐(见下图)。而字符zxx本身是有高度的,于是,图片下面就留空了。

而ZEro文字的高度是由行高决定的。

因此,简单的图片下面留白行为表现,本质上,就是vertical-align和line-height背地里搞基造成的。

知道了问题的原因,我们就可以对症下药,准确搞定图片下面我们不希望看到的间隙。怎么搞呢?一对基友,vertical-align和line-height我们随便搞定一个就可以了。

比方说vertical-align.

1. 让vertical-align失效

图片默认是inline水平的,而vertical-align对块状水平的元素无感。因此,我们只要让图片display水平为block就可以了,我们可以直接设置display或者浮动、绝对定位等(如果布局允许)。例如:

img { display: block; }

则帅奇下面的空隙就会不见。

2. 使用其他vertical-align值

告别baseline, 取用其他属性值,比方说bottom/middle/top都是可以的。

vertical-align:bottomvertical-align:middlevertical-align:top

3. 直接修改line-height值

下面的空隙高度,实际上是文字计算后的行高值和字母x下边缘的距离。因此,只要行高足够小,实际文字占据的高度的底部就会在x的上面,下面没有了高度区域支撑,自然,图片就会有容器底边贴合在一起了。比方说,我们设置行高5像素:

div { line-height: 5px; }

这里写图片描述

4. line-height为相对单位,font-size间接控制

如果line-height是相对单位,例如line-height:1.6或者line-height:160%之类,也可以使用font-size间接控制,比方说来个狠的,font-size设为大鸡蛋0, 本质上还是改变line-height值.

div { font-size: 0; }

③ 基本现象衍生:垂直居中

由于「幽灵空白节点」的存在,因此,我们可以进一步衍生,实现其他更实用的效果,比方说任意尺寸的图片(或者内联块状化的多行文字)的垂直居中效果。就是借助本文的两位男主角,vertical-align和line-height。

你想啊,图片后面(前面)有个类似空格字符的节点,然后就能响应line-height形成高度,此时,图片再来个vertical-align:middle,当当当当,就可以和这个被行高撑高的「幽灵空白节点」(近似)垂直对齐了。

例如:

div { line-height: 240px; }img { vertical-align: middle; }

不过效果并不是完全的垂直居中,只是近似(稍微仔细看可以看出来)。为什么只是近似呢?那是因为「幽灵空白节点」高度行高撑开,其垂直中心是字符content area的中心,而对于字符x而言,都是比绝对中心位置要下沉的(不同字体下沉幅度不一样),换句更易懂的描述就是x的中心位置都是在字符内容区域高度中心点的下方,而这上下的偏差就是这里图片上下间距的偏差。

换句更简单的话说就是:middle中线位置(字符x的中心)并不是字符内容的绝对居中位置。两个位置的偏差就是图片近似居中的偏差。

因此,要想完全垂直居中,最先想到的方法就是让后面的“幽灵字符”也是vertical-align:middle,然而,呵呵,既然称之为“幽灵”就表示不会受非继承特性的属性影响,所以,根本没法设置vertical-align:middle,除非你自己创建一个显示的内联元素。

我们就没有办法了吗?当然不是,“幽灵字符”可以受具有继承特性的CSS属性影响,于是,我们可以通过其他东西来做调整,让字符的中线和字符内容中心线在一起,或者说在一个位置上就可以了。有人可能要疑问了,这能行吗?啊,是可以的。

怎么搞?很简单,font-size:0, 因此此时content area高度是0,各种乱七八糟的线都在高度为0的这条线上,绝对中心线和中线重合。自然全垂直居中:

div { line-height: 240px; font-size: 0; }img { vertical-align: middle; }

这种通过line-height定高,元素vertical-align:middle垂直居中的方法不仅适用于现代浏览器,连IE7浏览器也是支持的

不过和其他浏览器再使用上还是有些需要注意的地方,就是,HTML不能这样:

<div><img src="mm1.jpg"></div>

而是需要在图片标签结束处留下空格后者换行:

<div><img src="mm1.jpg"><!-- 这里要折行或空格 --></div>

还有一点,是他们这俩个断背山的复杂现象,我们明天再讲,今天就到这,困了…..

原创粉丝点击