控制input输入框的高度

很久以前Roger Johansson就在他的blog上做了一个用样式控制表单元素的测试, 告诉我们企图用样式控制表单元素是一件不可能的事情

using CSS to style form controls to look exactly the same across browsers and platforms is impossible

甚至css2.1规范中也没有明确这方面的规定, 而是打算将它fix in future

CSS 2.1 does not define which properties apply to form controls and frames, or how CSS can be used to style them. User agents may apply CSS properties to these elements. Authors are recommended to treat such support as experimental. A future level of CSS may specify this further.

所以如果想要让表单元素在各个浏览器下完全一致, 最好的解决方法莫过于完全不理会操作系统的样式, 用自定义的ui风格, 就像bing或Google的Jazz UI那样

然而, 这会导致界面和用户的系统格格不入, 目前google主要还是针对浏览器做了些特殊处理, 如webkit下用gradient使得按钮看上去好些

mac下webkit的按钮不好控制

本文将就输入框高度的问题进行调研, 寻找更好的解决方法

 

输入框高度

首先, 这个调研的一个主要原因是, 搜索结果页打算进入标准模式, 这会导致盒模型的变化, 造成输入框高度和原来不一样, 所以为了和线上效果保持一致, 我们需要找到一个最佳的解决方案

有同学可能会不解, 有那么难么? 设置一个height不就解决了么?

<input style="height: 28px;" type="text" />

然而, 经测试发现这里面的细节问题还是还挺多, 由于资源有限, 这里只测试了主要的浏览器和平台, 包括目前主要用到的5个浏览器

  • IE6(xp)
  • IE7(xp)
  • IE8(win7)
  • Firefox 3.5(xp)
  • Firefox 3.5(win7)
  • Firefox 3.5(mac 10.6.2)
  • Firefox 3.5(ubuntu 10.4)
  • Chrome 5(xp)
  • Chrome 5(win7)
  • Chrome 5(mac 10.6.2)
  • Chrome 5(ubuntu 10.4)

通过设定height的方式

我们的目标是和目前搜索框大小保持一致, 既28px

首先测试的是最简单的height, 先看目前线上的方案(简单起见就直接写到style中了)

<input style="font: 16px arial; height: 1.78em; padding-top: 2px;" type="text" />

从样式上推导, 由于盒模型问题, 在IE下的大小将是1.78 * 16 = 28px, 而Firefox等浏览器应该是1.78 * 16 + 2px + border-width * 2 = 30 + ? px

测试结果是

浏览器height + padding-top + padding-bottom + border-top-width + border-bottom-width
IE6(xp) 21 + 2 + 1 + 2 + 2 = 28
IE7(xp) 21 + 2 + 1 + 2 + 2 = 28
IE8(win7) 21 + 2 + 1 + 2 + 2 = 28
Firefox 3.5(xp) 21 + 2 + 1 + 2 + 2 = 28
Firefox 3.5(win7) 23 + 2 + 1 + 1 + 1 = 28
Firefox 3.5(mac 10.6.2) 19 + 2 + 1 + 3 + 3 = 28
Firefox 3.5(ubuntu 10.04) 19 + 2 + 1 + 3 + 3 = 28
Chrome 5(xp) 21 + 2 + 1 + 2 + 2 = 28
Chrome 5(win7) 21 + 2 + 1 + 2 + 2 = 28
Chrome 5(mac 10.6.2) 21 + 2 + 1 + 2 + 2 = 28
Chrome 5(ubuntu 10.04) 21 + 2 + 1 + 2 + 2 = 28

效果相当理想, 所有浏览器都是28px, 看来即使是Firefox和Chrom在quirks模式下的input都没有遵循盒模型, 所以线上的输入框高度在各个浏览器下很完美地保持一致

然而如果是在standards模式下, 结果则是

浏览器height + padding-top + padding-bottom + border-top-width + border-bottom-width
IE6(xp) 28 + 2 + 1 + 2 + 2 = 35
IE7(xp) 28 + 2 + 1 + 2 + 2 = 35
IE8(win7) 28 + 2 + 1 + 2 + 2 = 35
Firefox 3.5(xp) 28 + 2 + 1 + 2 + 2 = 35
Firefox 3.5(win7) 28 + 2 + 1 + 1 + 1 = 32
Firefox 3.5(mac 10.6.2) 28 + 2 + 1 + 3 + 3 = 37
Firefox 3.5(ubuntu 10.04) 28 + 2 + 1 + 3 + 3 = 37
Chrome 5(xp) 28 + 2 + 1 + 2 + 2 = 35
Chrome 5(win7) 28 + 2 + 1 + 2 + 2 = 35
Chrome 5(mac 10.6.2) 28 + 2 + 1 + 2 + 2 = 35
Chrome 5(ubuntu 10.04) 28 + 2 + 1 + 2 + 2 = 35

就仅仅加了一句, 却导致浏览器差距变得如此大, 仔细观察发现, 主要问题在Firefox上 它的border在win7下是1像素, xp下是2像素, mac下是3像素, 令人很头疼, 于是打算换一种方案试试

padding的方式

由于Firefox的border问题, 设定height是不可能保证高度一致的, 除非判断再去判断操作系统类型, 但那样做太麻烦了, 而且说不定mobile版又不一样

那是否可以不通过设置height来控制? 在目前的大搜索首页也是standards模式, 它是采用padding的方式来实现28px的高度的

<input style="font: 16px arial; padding: 3px;" type="text" />

这种写法的测试结果是

浏览器 height + padding-top + padding-bottom + border-top-width + border-bottom-width
IE6(xp) 18 + 3 + 3 + 2 + 2 = 28
IE7(xp) 18 + 3 + 3 + 2 + 2 = 28
IE8(win7) 18 + 3 + 3 + 2 + 2 = 28
Firefox 3.5(xp) 19 + 3 + 3 + 2 + 2 = 29
Firefox 3.5(win7) 19 + 3 + 3 + 1 + 1 = 27
Firefox 3.5(mac 10.6.2) 20 + 3 + 3 + 3 + 3 = 32
Firefox 3.5(ubuntu 10.04) 19 + 3 + 3 + 3 + 3 = 31
Chrome 5(xp) 19 + 3 + 3 + 2 + 2 = 29
Chrome 5(win7) 19 + 3 + 3 + 2 + 2 = 29
Chrome 5(mac 10.6.2) 18 + 3 + 3 + 2 + 2 = 28
Chrome 5(ubuntu 10.04) 19 + 3 + 3 + 2 + 2 = 29

在不设定输入框高度的情况下, 浏览器会自行指定一个, 而且都有差距, mac上的Firefox更是高出了4像素, 但总的来说, 效果虽然不完美, 但还是可以接受, 大部分情况下都只差一个像素

然而这种方法带来了很多不确定性, 内容区的高度是随着字体大小而变的, 假设font-size是14px, 浏览器的高度又保持一致了

浏览器height
IE6(xp) 16
IE7(xp) 16
IE8(win7) 16
Firefox 3.5(xp) 16
Firefox 3.5(win7) 16
Firefox 3.5(mac 10.6.2) 16
Firefox 3.5(ubuntu 10.04) 16
Chrome 5(xp) 16
Chrome 5(win7) 16
Chrome 5(mac 10.6.2) 16
Chrome 5(ubuntu 10.04) 16

是否还有更好的方案呢?

box-sizing

height和padding都无法完美控制输入框高度, 而border的大小又不能改, 难道就真的没办法了么? 不禁怀念quirks模式下的方便, 设定一个高度就完美了, 要是能既进standards模式, 又能用到旧盒模型就好了, 很自然地就想到了一个从来没用过的css属性box-sizing, 以前一直没想好这属性到底能用在哪里, 终于这下派上用场了, 使用它我们就可以解决Firefox下3种border的区别, 让Firefox自己去算内容区的高度

然而由于IE6/7不支持这个属性, 所以需要写hack, 由于IE下的默认border值是2, padding是1, 所以height需要减6像素, 也就是

-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
height: 28px;
*height: 22px;

这样, 就能保证绝大部分的浏览器下效果一致了, box-sizing属性的支持情况如下表所示, 来自mozilla, 支持的访问非常广

BrowserLowest VersionSupport of
Internet Explorer 8.0 box-sizing
Firefox (Gecko) 1.0 (1.0) -moz-box-sizing
Opera 7.0 box-sizing
Safari (WebKit) 3.0 (522) -webkit-box-sizing

不过, 事情还没有结束, 刚才假定了IE下默认padding是1像素, 然而目前很多css reset都会将input的padding设为0, 于是, IE下的差别将不是6像素, 而是4像素, 所以为了避免受到影响, 建议将padding设为0

padding-top: 0;
padding-bottom: 0;
height: 28px;
*height: 24px;

 

posted @ 2012-05-07 11:40  青春无敌小宇宙  阅读(1342)  评论(0编辑  收藏  举报