这篇文章发布于 2010年06月12日,星期六,23:32,归类于 CSS相关。 阅读 160513 次, 今日 5 次 36 条评论
by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=861
补充于2018-01-01:当时写这篇文章也是变研究变整理的,因此,有不少想法其实是不成熟的。要想更准确深入了解vertical-align相关知识,可以去我的著作《CSS世界》中寻找答案。
一、上集内容简单提要
上集内容“我对CSS vertical-align的一些理解与认识(一)”要追溯到差不多一个月以前了,主要是了解了下vertical-align
的一些属性,并简单讲述了自己对vertical-align
属性的一些理解。vertical-align
是个相当复杂与精深的属性,所理解的一些内容多少会有不准确之处,例如之前我认为inline
属性的元素对vertical-align属性是不感冒的,但是在同行的提醒下,我自己一测试,发现完全不是之前自己所想的,就算是很单纯的inline
水平的元素都支持vertical-align
属性的。所以自己有必要对vertical-align
的认识重新梳理,整理成文。本集内容主要讲讲我对在一般情况下vertical-align
其作用的理解,以及vertical-align
相关的对齐问题,以及浮动为何可以破坏vertical-align
属性。
二、我对不同浏览器解析vertical-align属性的理解
在上集中,在最后提供的实例中,vertical-align:middle
实际上应该是与后面的文字是独立的,毫无关联,就是说vertical-align
无论是什么,都不影响文字在box中的位置(IE6/7对vertical-align
理解与现代浏览器有差异)。但是在实际情况下,行高可能会小于inline-block
或是类似于inline-block
属性的元素的content area的高度,此时vertical-align
对文字的影响似乎是显而易见的,那么这种影响是如果实现的呢?这就是本段的重点。
1. 我对vertical-align文字对齐相关属性的理解
vertical-align
属性可以说是CSS中兼容性最糟糕的属性之一了。比如说与文字相关的vertical-align
属性,vertical-align:text-top
和vertical-align:text-bottom
属性,这两个属性的解释IE浏览器(IE6-8)和现代浏览器是不一样的两个派别。到底哪种表现是正确的,这是不能随便做定论的。无论实现的机制如何,若能实现类似的效果表现,其实都可以说是正确的。在一般的使用条件下,例如小图标+文字,vertical-align:text-top
这类文字对齐类属性在不同浏览器下的差异是较小的,这很难让我们去思考与理解这些差异在什么地方。但是,如果我们将测试的元素进行简化与放大,那么差异显而易见,也更利于我们思考其中的原因所在。
text
相关vertical-align
的差异表现:<div style="line-height:200px; border:1px solid #34538b;"> <span style="font-size:60px; border:1px solid #a0b3d6; vertical-align:text-top;">大大的文字</span>后面是静止的文字。 </div>
当line-height
作为唯一的高度来源,且远远大于content area高度的时候(只与字体大小相关),此时我们可以喝直观的看到不同浏览器下的表现。上面代码很简单,一个行高200
像素的div
,里面有一个带有vertical-align:top
属性的字体大60
像素的inline
水平的行内元素,边框只是便于观看识别留下的。
在展示不同浏览器下的表现之前,您可以先按照自己的理解想想会是什么样的表现。
说实话,以我之前纯粹的所谓想象经验式的理解,应该是后面的文字与大号文字的顶部对齐,事实是如何呢?看下面的IE阵营和现代浏览器阵营下的表现截图:
对比IE7浏览器和IE8浏览器下的表现我们可以看到,就文字的垂直对齐方面,两者是一样的,这也很符合自己以往对vertical-align:text-top
的形象化的了解,也就是文字顶部对齐,看IE浏览器下就是文字顶部对齐的,后面的文字的顶部就与前面大号文字的顶部的文字对齐。所不同的就是IE8浏览器的外部div
的高度被撑开了27
像素,差不多是1/2
个文字大小的高度。下面看看两个代表性的现代浏览器下的样式表现(Firefox3.6&Chrome5):
经过我的仔细对比,Firefox3.6下的页面表现欲Chrome5浏览器下的是一模一样的,不仅如此,还与Opera浏览器也是表现一致。于是,就单纯从页面表现上来看,出现了两个阵营,不太和谐的IE阵营以及高度一致的现代浏览器阵营。但是究竟孰是孰非呢?这需要慢慢说来!
就表象而言
vertical-align:text-top
似是而非的理解,文字顶部对齐。看那,IE浏览器下,无论是IE6还是IE7或是IE8都是这样子的。相比之下,现代浏览器下的样式表现有些令人费解。OK,要追寻问题的解决最好的方法就是寻找他的根源,去需找它的定义,而不要根据一些表象而去臆测。text-top aligns the top of the box with the top of the parent element’s font
翻译过来就是:让当前box的顶部与父元素的文字的顶部对齐
所以我们只要恰准了box的顶部以及父元素文字的顶部,就可以知道这类表现是怎么回事,哪种表现更加符合其本身的定义。
当前box的顶部
在本实例中,当前box是包裹着“大大的文字”的这5个文字的span标签,那么这个标签的顶部在哪里呢?按照我对inline box模型的理解,这个标签的顶部应该是在——见下图标注:
上图中蓝色的参考线就是这个span
box的顶部。如果您了解line box模型,这个不难理解。line box中重要的几个概念是:content area,inline box(以及匿名inline box),以及由inline boxes组成的line box。
- 其中content area可以理解为内容实体,也就是图片中的文字,我们设置
span
标签的border属性或是background属性,所看到的围绕文字的边框以及背景色的区域就是指的content area,这个东西仅仅与文字的大小相关,其作用仅仅是显示内容而已,很多重要的工作都不是content area来执行的。 - 每个inline属性的标签外部都有一个inline box,这个inline box是看不见的,这个看不见的inline box扮演者重要的角色,此box与CSS中的line-height属性相互配合构成了元素高度堆叠的基础。以我的理解,inline box的高度纯粹就是有元素的
line-height
或是继承的line-height
值决定的。例如本实例中,父div
的line-height
为200
像素,自然,含“大大的文字”的span
标签所在的inline box的高度就是200像素,换句话说,这个含有vertical-align:text-top属性的span标签的实际高度是200像素。 - 本实例中有一段文字“后面是静止的文字”外部并未直接包裹任何标签,但是这段连续的文字外部也包裹了一个看不见的inline box(称之为匿名inline box),其本质以及一些表现与inline box几乎无异。也能占据200像素的高度。
- span标签外部不可见的inline box以及文字所在的匿名inline box共同组成了line box,line box也是不可见的,每行文字有且仅一个line box,line box的高度有其内部的一系列的inline boxes高度共同决定,由内部的inline boxes的上下最大绝对差值决定的。例如本实例红,在现代浏览器下,外部div的高度之所以会被撑开,是内部两个inline boxes共同作用的结果。
所以结合上面的简单分析,本实例中含有vertical-align:tetx-top
属性的span
标签实际的box区域应该如下图半透明绿色区域:
父标签的文字顶部
具体什么是“父元素的字体”我也不是很清楚,这是个很虚的概念,我甚至怀疑这本身就是个抽象出来的概念,例如一个div
中两个inline水平的标签,一个vertical-align:text-top
另外一个vertical-align:text-bottom
,那么哪个才是这里的“父元素的字体”呢?我更加倾向于将这个“父元素的字体”解释为,假设父标签中有个很单纯的文字,指无标签,无嵌套的文字,所有属性纯粹继承的文字(即使这个文字根本不存在),那么这个文字就是这里所指的“父元素的字体”。
zxx://难以搜到相关资料,上述观点都是自己推测的,仅供参考
在本实例中,正好“后面是静止的文字。”这段文字字符是纯粹的文字,属性完全继承的文字,则“父元素字体的顶部”就可以认为是这段文字的顶部了。
所以,综上所述,实际占据200像素的span
标签要与后面的“纯粹文字”顶部对齐,没有办法,这个span
标签只好下移,下移的距离为92像素,这个92像素时如何来的呢?很简单:后面的文字实际也占据200像素的高度,其中本身文字大小16像素,也就是文字的content area占据16像素的高度,如果span标签与文字垂直中线对齐,则下移为100像素,但是由于是顶线对齐,于是要少掉1/2个文字高度,也就是8像素,于是span标签下移了92像素。
具体实现参见下面的Flash动画演示,点击“下一步”按钮查看演示与说明,如果无法显示可以点击这里直接浏览:
IE浏览器的解释
像Firefox,Chrome,Opera浏览器被称为modern browser(现代浏览器),也被称为标准浏览器。这类浏览器对于CSS的渲染都是比较符合W3C标准的,但是IE浏览器,有点孤芳自赏之感,走了很多自己的路,于是在CSS的解释与渲染上,很多与标准浏览器之间是有差异的。其中对vertical-align的解释就是其中之一。本文之前所有的讲解都是针对的现代浏览器。
虽然IE8对不少vertical-align
属性的解释与现代浏览器一致,但是有些还是走的其老套路。例如这里的vertical-align:text-top
属性。由于IE浏览器对vertical-align:text-top
的解释与标准有差异,所以我也无法准确说出其样式表现的机制是什么。按照我自己未经证实的一些推测,IE浏览器(IE6-IE8)似乎将当前元素的顶部理解为了当前元素文字的顶部(也就是inline box模型中的content area的顶部,而不是inline box的顶部),于是vertical-align:text-top
就是两段文字之间的对齐,span
文字的顶部与后面裸文字的顶部对齐。如果我们不仔细思考vertical-align
的定义,可能就会觉得IE浏览器的实现似乎更合理,更容易理解。
IE8浏览器的UI表现欲IE6/7还是有一点差异的,差异在于父元素的高度。IE8浏览器的父元素高度被撑开了,而IE6/7这里反而不撑开了(⊙﹏⊙b汗),IE8下高度为227像素,这多出来的27像素是60像素的文字下移与后面文字顶部对齐的距离。这与现代浏览器下的父标签撑开表现是有些类似的,IE8浏览器可以说是有改进的,但是在理解父元素的顶部上似乎与现代浏览器有偏差,不知在IE9浏览器下会是怎样的一个表现。一起拭目以待。
附上本文的这个很简单的demo:狠狠地点击我
内容真多,已经连续写了好几个晚上了,不得已,还得分篇叙述……资质尚浅,理解上可能有错误,欢迎指正,不甚感谢!
未完,待续……
本文为原创文章,转载请注明来自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]
本文地址:http://www.zhangxinxu.com/wordpress/?p=861
(本篇完)
- css行高line-height的一些深入理解及应用 (0.674)
- CSS line-height-step属性简介 (0.309)
- 我对CSS vertical-align的一些理解与认识(一) (0.266)
- CSS深入理解vertical-align和line-height的基友关系 (0.247)
- checkbox复选框的一些深入研究与理解 (0.225)
- CSS float浮动的深入研究、详解及拓展(一) (0.191)
- 翻译-IE7/8@font-face嵌入字体与文字平滑 (0.190)
- 好消息,align-content垂直居中也适用普通元素啦 (0.186)
- 区分IE8/IE7/IE6及其他浏览器-CSS "\9"hack (0.159)
- letter-spacing+first-letter实现按钮文字隐藏 (0.157)
- jQuery-很酷的弹出层效果js插件 (RANDOM - 0.005)
愚以为,ie6-78对vertical-algin:text-top的解析更准确也更合理,对于一个inline来说,它是不支持宽高的(也就是给设置宽高是不起作用的),所以这时候的span就应该是和content area的顶部对齐,而标准浏览器在上述例子中是把后面 的文字这样的inline看成是支持宽高的inline block,所在才会使得左边的文件下移
不,主要是虽然它不支持宽高,但是inline元素形成的行内框的高度又是由line-height决定的,你说的和这个不是一回事,说的是“让当前box的顶部与父元素的文字的顶部对齐”,而不是当前box的内容区域顶部与父元素的文字的顶部对齐
赞同+1
float浮动会破坏vertical-align的属性,详见https://developer.mozilla.org/zh-CN/docs/CSS/float 里边有详细说明,float以后,及时display为行内元素,计算值仍为block元素,所以是不会起作用的
分析的很好,之前第一遍看书没怎么理解,尤其是一些像行内框、内容区、em框、行框、行高之间的关系,现在结合博主的例子再看看书感觉茅塞顿开
看了楼主自编自画的个人介绍 哈哈 有意思,楼主是个性情中人啊,可惜离上海太远,没机会一起钓鱼
文章写的很好,条理清晰,简单易懂,w3c讲是父元素字体的顶端对齐,就是父元素字体的顶端真是个百感交集的位置。不知道从何找起啊。
float会破坏vertical-align的文章是哪个呀
因为元素浮动之后就会变为块元素,即 display 属性为 block ,所以 vertical-align 属性就会不起作用。
茅塞顿开!多谢
首先感谢博主,精彩的博文。以下我关于line-height的观点(不一定正确)
1.line-height并似乎不是由line内最高的inline元素决定的,行高的定义似乎也不是两条baseline的距离,
而是四条线中间夹着的三个距离之和。因为topline到middleline和baseline到bottomline的距离可能不一样。
比如两个inline-block元素,一个撑高了topline到middleline的距离,另一个撑高了baseline到bottomline的距离。
2.图片撑高了line-height图片的边界会碰到top或bottom。但是文本的inline或inline-block撑高的line-height却不会碰到top或bottom。意思top和bottom对文本敬而远之。
3.两条相邻的line,上一条的bottom与下一条的top重合,火狐浏览器和IE浏览器的到了第三行,的三行的topline和第二行的bottomline却并不重合。(我不确定,这是bug还是我观点错误)
博主,就是这个浮动如何影响该属性啊?怎么没有后文了?
大神,flash三大浏览器都看不了啦。
顶!
怎么没有讲浮动对vertical-align的影响呢
vertical-align是按照行高对齐的。
根本原因line-height具有继承性
完美的解释,下移92似乎还不是很理解,是否说是其他空白文字撑开了呢
赞下flash,vertical-align:bottom似乎也是一样的
给前边的标签加上display:inline-block;这样ie和现代标准浏览器就一样了
赞!flash里表达的理论很赞
你的文章写得都很不错,我都是咬文嚼字的看的,虽然有些官方术语没看懂,但是还是能理解很大一部分,我都了得都转载了啊,留了你的链接,以后我要看的时候可以再仔细看,也想把你的想法推广给更多的同行!
很详细的解释,flash动画很赞
刚刚遇到vertical-align的问题,折腾半天,细看博主的文章之后,终于解决了,膜拜楼主,
不过vertical-align还是理解有些模糊,但其实这些不仅仅单纯是这个属性的问题,而是涉及到其他东西
比如 line-height 、inline-box的概念等等,这些东西没搞清、或者说那些巨头没统一,我们这些百姓是永远搞不清楚的,要实际应用是必须死很多脑细胞的
博主说的很对,我认真学习了css权威指南第四版(最新版本貌似还没有)Basic Visual Formatting一章后,也觉得你说的和规范很一致,能把父容器div的高度算的如此准确,钻的很深啊。
不过自己做实验还有点问题解决不了,如下的代码中div的高度是怎么精确算出来的呢(在标准浏览器中如火狐中为65px,根据我的经验,火狐中line-height值貌似是字体的1.14倍):
There is a em and a spanf
如果有时间,请帮忙解惑,谢谢。
那应该 IE 的才是对的啊。。。目前截至 IE 10 Consumer Preview 对该属性的处理一直和 IE 8 的几乎一样哦。。。
博主太有才了,不过这个属性真的很啃爹。。
well, render, not s…
As I know, IE 9 and 10 also renders the vertical-align attribute like the IE 8 mentioned above…
而如果我们知道 基线和文字底线的距离是 1/7 文字高度,在谷歌浏览器下,checkbox的大小是 13*13像素,所以对于缺省checkbox 按照基线对齐的情况,
对于大小17px的字体,基线以下2px,基线以上15px,13px的复选框底线和文字基线对齐,是刚好可以对齐的字体大小,其他更小的字体,文字就会偏下,更大的字体,文字会偏上。
对于vertical-align:middle的情况,是按照checkbox中线和小写字母x的中线对齐,
对于英文字母来说吗,是比较理想的情况,但对于汉字的中线,和英文字母x的中线有2/7个文字高度的偏离,所以不管多大的字体,都会显得中文文字偏上。
你好!最近被vertical-align属性弄得头昏脑胀,看了你的博文,豁然开朗。
另外,关于文字基线、中线的准确位置,经过反复的试验和计算,在谷歌浏览器下
文字基线距离文字底部 1/7 的字体高度,
文字中线距离文字基线 1.5/7 的字体高度,
也就是说,小写字母x的高度是 3/7 字体高度, 小写字母x的中部(文字的中线)距离文字底部2.5/7 高度。
按照这个比例,在谷歌浏览器下, 各种vertical-align时 就可以把理论计算的高度和 父元素被撑开的高度进行验证了。
华丽的动画.
还是看动画直观。
呵呵。看文字让人直接晕。
冒昧的问一下,那个 “后面是静止的文字” 这些文字是16px的定义么?好像没有看到body之类的定义。。。
16px的文字大小事浏览器默认的字体大小。
很详细的文章,留个言以后慢慢看。