找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11896|回复: 31

[教程] [原创]基于vertical-align的表单元素垂直对齐方式研究

[复制链接]
发表于 2009-7-24 18:54:34 | 显示全部楼层 |阅读模式
(本文的标题叫做“方式研究”,是因为,我最终也没有想通原理,只猜出了方法,但是,的确是实现了效果。)

最近的项目涉及到很多表单的制作,特别是复选框(checkbox)和单选框(radio)。但是在前端开发过程中发现,单(复)选框和它们后面的提示文字在不进行任何设置的情况下,是无法对齐的,而且在Firefox和IE中相差甚大。即使设置了vertical-align:middle,也依然不能完美对齐。如下图所示:

01.jpg

于是上网查看了一些网站,发现这个问题是普遍存在的,如下图(FF3.5):

error.jpg

在很多网站涉及到表单的页面中,都存在这种表单元素与提示文字无法对齐的问题。于是打算研究一下这个问题。首先,搜索到了wheatlee前辈的文章大家都对vertical-align的各说各话。wheatlee在他的文章中关于垂直居中提到了这样几个关键点:

1、vertical-align:middle的时候,是该元素的中心对齐周围元素的中心。

2、这里“中心”的定义是:图片当然就是height的一半的位置,而文字应该是基于baseline往上移动0.5ex,亦即小写字母“x”的正中心。但是很多浏览器往往把ex这个单位定义为0.5em,以至于其实不一定是x的正中心

(baseline等名词如果不懂,请先阅读wheatlee的文章)

按照这个思路,对照我遇到的问题,首先想到的是先验证一下浏览器对于“复选框”和图片是不是使用同样的规则来渲染(是不是把复选框当成一个正方形图片来对待)。于是写出下面的代码:


<style>
body{font-size:12px;}
</style>
<input style="vertical-align:middle;" name="test" type="checkbox">
<img style="vertical-align:middle;"  src="testpic.gif" />
测试文字


代码中的testpic.gif是一个尺寸与复选框完全一样的黑色图片。FF3.5下显示如下:

02.jpg

事实证明,FF3.5对于复选框和图片的垂直对齐方式是采用同样的规则进行渲染的,即将复选框当作一个正方形的图片(IE不是)。按照wheatlee“middle的时候,是该元素的中心对齐周围元素的中心”的观点,如果我在复选框后面输入英文字符,那么复选框的中心将与英文中小写字母x的中心对齐。经测试,FF3.5下面基本上是这样的(在一些字号的时候会有一定的误差,比如,如果字体高度是偶数,那么这个中心点有时在一般偏上1px,有时在一半偏下1px)。如图:

03.jpg

但是这对于中文来说,并不是一个好的结果。因为中文是方块字,并且相同字号的情况下,高度会比小写的x高出很多。所以,按照浏览器内置的方式,只用 vertical-align:middle是无论如何也无法对齐中文的(无论是只写中文,中文在前,英文在前,FF3.5都是按照小写x中心那种方法来对齐的)。但是回头再看看wheatlee的文章,他说这个小写x中心对齐的渲染方式,是对于“文字”来说的。那么,如果不是文字呢…?如果复选框后面跟的是一个行内元素,如label,而文字是写在它内部的,会是什么样呢?浏览器会不会将这个内联元素整体看作一个“块”,然后依照类似图片的规则进行渲染呢?如果那样,我们就达到目的了。

但是经过测试,很遗憾,事实并不是这样,加上label后跟没加没有任何区别。FF3.5/IE6/IE7均是如此。在FF3.5中用firebug看一下,证明浏览器并没有按照label的高度值来去对齐中心点。如图:

04.jpg

如果按照之前的设想,红蓝两线应该是重合的。但现在的情况是,它们相差了1px。并且这1px是没有规律的,随着字号的放大,并不恒定,貌似轻易也无法提炼出对应关系来。于是想到,再试一下将label也加上vertical-align:middle。结果如图:

05.jpg

在FF3.5和IE7下面已经很接近于我们希望的状态了,只差1px。IE6下… 无语了。

经过以上折腾,我得出了跟wheatlee相同的结论,就是,各种浏览器之间对这个问题的处理貌似没有任何规律。并且,似乎每一种浏览器对于 vertical-align:middle的渲染都不是完全遵从W3C所说的“Align the vertical midpoint of the box with the baseline of the parent box plus half the x-height of the parent.”

但是经过仔细总结和分析,发现好像最终对齐的结果跟label的高度和当前字体中小写x的中心点都有关系,两者同时影响着渲染结果(虽然不明白为什么会这样)。那么,既然现在的情况以及非常接近于希望的状态了,是否可以通过设置字体的方式来改变小写x的中心点的位置,进而对垂直对齐的结果进行“微调”呢?

最终,在不断的测试中发现,如果将font-family中的第一个字体设置为Tahoma,则可以完美的实现对齐(Verdana等字体也可以)。而且在FF3.5/IE6/IE7/IE8和Chrome中均显示正常。最终代码如下:

 提示:您可以先修改部分代码再运行



最终效果:

06.jpg

至此,多选框(checkbox)和提示文字对齐的问题已经解决,那么其他表单元素呢?试验了一下单选框(radio),发现,还是有问题。提示文字依然是偏上。用firebug看了一下,发现radio元素默认有5px的左边距和3px的上、右边距,却没有下边距。如图:

08.jpg

于是,尝试去掉radio的外边距,刷新后显示正常。(其实多选框checkbox也是有外边距的,只是它的外边距四个方向都有,并且相等,所以对于垂直对齐没有影响。)下图是一些常用表单元素的最终显示效果以及最终代码,大家可以用不同浏览器看一下实际的效果(注:由于演示使用的12px的中文实际只有11px高,而 IE下文本框等元素的高度是22px,一个是奇数,一个是偶数,所以这些部分在IE中是无论如何也对不齐的,差1px。如果手动控制文本框高度为奇数,或者将文字设置成为偶数的高度,则显示正常):

09.jpg

 提示:您可以先修改部分代码再运行



而且我发现,不但解决了中文的问题,如果提示信息换成其他语言,基本上也能够对齐,至少不会像开始那样偏移太多。下面是截图、代码和一些例子:

07.jpg

 提示:您可以先修改部分代码再运行



至此,我的研究过程告于段落。

但是,还是想不通各浏览器为什么最后会显示出这样的效果,其中的原理是什么。牛人们有空可以解释一下吗?

永久链接 http://www.henryl.net/blog/2009/07/143

[[i] 本帖最后由 xidea 于 2010-3-30 11:44 编辑 ]

评分

参与人数 1威望 +2 收起 理由
14px + 2 谢谢分享

查看全部评分

 楼主| 发表于 2009-7-24 19:05:47 | 显示全部楼层
不好意思,刚才发上来的时候代码部分有点儿问题,现在已经解决。如果各位朋友运行代码后得到了莫名其妙的效果,请刷新。
回复 支持 反对

使用道具 举报

发表于 2009-7-24 20:58:29 | 显示全部楼层
好文章
回复 支持 反对

使用道具 举报

发表于 2009-7-25 09:54:59 | 显示全部楼层
一直遇到这个对齐问题,没仔细去研究。  学习了。
回复 支持 反对

使用道具 举报

发表于 2009-7-25 11:00:02 | 显示全部楼层

 提示:您可以先修改部分代码再运行


都没没问题,呵呵
不过原封不动的代码存到本地ie8浏览变成下图。
11.jpg

[[i] 本帖最后由 dededesign 于 2009-7-25 11:05 编辑 ]
回复 支持 反对

使用道具 举报

发表于 2009-7-25 17:52:50 | 显示全部楼层
这也一直是令我头痛的问题,我也来讨论一下。

首先有个问题,很显然,我们不可能在只表单中使用某种特定的“安全”字体,所以我们只能去发掘真相。然而这恰恰是最令人痛苦的。我故弄玄虚地说一句,那些“奇怪的表现”涉及到行内元素的布局,而这又涉及到浏览器的文字渲染引擎,甚至还可能涉及到文件的字符编码对文字渲染的影响。

不仅仅是浏览器差异,行内元素的布局模型本身就很难捉摸。这个真的太难懂了,《CSS权威指南》第 7 章里面《行内元素》一节我觉得不是给人看的,更不要说相关的 CSS 规范了。另外,我们对字体的了解实在是太贫乏了。从某种程度上看,我们完全是在做黑盒测试。

所以,我至今仍然回避这个问题。只要遇到要求精确布局的表单,我肯定不厌其烦地使用浮动布局,目的就是回避行内元素布局的复杂性和不可预测性,块级元素显然更容易操作并且在不同浏览器下更统一。

[[i] 本帖最后由 birdstudio 于 2009-7-25 18:15 编辑 ]
回复 支持 反对

使用道具 举报

发表于 2009-7-26 08:32:34 | 显示全部楼层
学习中。。。。 vertical-align对齐方式一直让我很头痛
回复 支持 反对

使用道具 举报

发表于 2009-7-27 15:47:21 | 显示全部楼层

 提示:您可以先修改部分代码再运行



vertical-align:-3px;  我每次都这样做。很实用

[[i] 本帖最后由 firhome 于 2009-7-27 15:48 编辑 ]
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-7-27 17:24:10 | 显示全部楼层

回复 9# firhome 的帖子

呵呵,这样确实很快捷。我怎么没想到呢。但是对待不同浏览器需要写hack吧。

[[i] 本帖最后由 xidea 于 2009-7-27 17:25 编辑 ]
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-7-27 17:27:14 | 显示全部楼层

回复 7# birdstudio 的帖子

恩,其实我倒觉得浮动起来会更晕。这之前我一般都是用内边距来撑,勉强对其,然后每个浏览器写一个hack.
回复 支持 反对

使用道具 举报

发表于 2009-7-27 18:04:27 | 显示全部楼层
虽然比较完美的解决了这个问题,但很多时候不一定会选择这种字体。。。
回复 支持 反对

使用道具 举报

发表于 2009-7-28 09:35:55 | 显示全部楼层
楼主的方法不错,不过很多时候不能用这个字体

特别是13px的时候

[[i] 本帖最后由 ltj0532 于 2009-7-28 09:57 编辑 ]
回复 支持 反对

使用道具 举报

发表于 2009-7-28 14:13:03 | 显示全部楼层
这个垂直居中的问题是比较难办,不过很佩服楼主的分析能力!
回复 支持 反对

使用道具 举报

发表于 2009-7-29 16:03:47 | 显示全部楼层
用Verdana字体发现差别很大,并且用LZ那种字体在IE6下面还是错位明显,感到很奇怪。

另外谁研究过让button在各个浏览器下面保持垂直居中的办法没有,FF支持padding而不支持line-height很难办。

[[i] 本帖最后由 mycggo 于 2009-7-29 16:38 编辑 ]
回复 支持 反对

使用道具 举报

发表于 2009-7-29 21:33:37 | 显示全部楼层
学习了...
回复 支持 反对

使用道具 举报

发表于 2009-7-30 09:43:05 | 显示全部楼层
这段时间正为这个问题烦恼呢,谢谢楼主的分享。
回复 支持 反对

使用道具 举报

发表于 2009-7-30 10:14:20 | 显示全部楼层
非常感谢LZ的研究结果,这个一直使我们制作时候棘手的问题,如果碰到像素级的制作,通常我们是通过给单选复选设置margin值,并且做不同的hack实现的,因为常常设计稿中<label>标签中的字体不是tahoma,而我们又不能随意设置字体,所以这个我觉得值得向设计部门推广普及一下,他们只需要妥协一点点,我们就能省很多力气了。
回复 支持 反对

使用道具 举报

发表于 2009-7-30 10:53:49 | 显示全部楼层
首先这个问题是中文才有的~lz查阅的一些网站也应该都是中文站。
我觉得吧~浏览器都是老外开发的~css规则也是老外定的~
而他们普遍使用英文~不会了解中文~或其他国家的文字~当然也不会细致的去测试这些细节问题了

另外使用tahoma的话在ie6中链接的下划线与文字没有间隙。
回复 支持 反对

使用道具 举报

发表于 2009-7-30 22:53:02 | 显示全部楼层
谢谢楼主的分享
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-7-30 23:58:13 | 显示全部楼层

回复 12# xfcmamb 的帖子

对于中文来讲,基本上网页上面的都是用宋体。所以,如果只涉及到中文的话,选择何种英文字体排在前面或许是无关紧要的。另外,其他字体我没有试验,应该有很多也可以达到目的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-7-30 23:58:59 | 显示全部楼层

回复 13# ltj0532 的帖子

恩,我也希望能够找到更加通用的方法,期待牛人解答。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-7-30 23:59:54 | 显示全部楼层

回复 15# mycggo 的帖子

我回头再仔细测一下。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-7-31 00:01:50 | 显示全部楼层

回复 18# chx71 的帖子

我们可以尝试多种字体,然后列出一个可用于此方法的字体列表。应该不仅仅是tahoma字体可以做到。我觉得应该是一类字体。关于字体的知识我了解不多,但是以前也看过一些,印象中好像是遵循一定规律的。

有待于更深入的研究。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-7-31 00:05:40 | 显示全部楼层

回复 19# W3CSS 的帖子

恩,说的是。只有中文这样的方块字,这样的问题才明显。
回复 支持 反对

使用道具 举报

发表于 2009-8-9 12:36:31 | 显示全部楼层
很感谢楼主让我理解了vertical-align的用法~
既然表单元素可以对齐,那是不是小ico也可以呢~调试了一下,文字小于12px,高度小于14px就不能对其~
原因也是图片的高度小于文字的高度了...
回复 支持 反对

使用道具 举报

发表于 2009-8-10 20:53:53 | 显示全部楼层
tahoma字体表现良好是因为它是windows的控件界面字体。

关键问题在于各个字体的行高和ex问题。对齐算法是固定的,最多在舍入时偏差1px。
回复 支持 反对

使用道具 举报

发表于 2009-8-10 21:47:40 | 显示全部楼层
不错 楼主挺用心的
回复 支持 反对

使用道具 举报

发表于 2009-9-4 10:09:51 | 显示全部楼层
楼主干得不错,希望再看到精彩的文章。
回复 支持 反对

使用道具 举报

发表于 2010-10-9 09:49:12 | 显示全部楼层
是的,Tahoma字体虽然美观、安全,但不能一直用下去,hack是少不了的啊~
还有最头疼的是当中英文混排的文本也会出现问题
回复 支持 反对

使用道具 举报

发表于 2010-10-9 10:45:45 | 显示全部楼层
楼主的文章真的很精彩,观察很细致。以前遇到这类问题,觉得差不多就行了,没有深入研究过。 Tahoma刚好是我们一直在用的英文字体,这篇文章真的让人受益匪浅。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|Archiver|手机版|blueidea.com ( 湘ICP备19000417号-2 )

GMT+8, 2021-11-29 08:21 , Processed in 0.086294 second(s), 14 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表