您當(dāng)前位置:圖趣網(wǎng)(Tuquu) >> 網(wǎng)頁(yè)設(shè)計(jì)教程 >> 移動(dòng)前端 >> 瀏覽設(shè)計(jì)教程

網(wǎng)頁(yè)前端開(kāi)發(fā)-控制input輸入框的高度

 

很久以前Roger Johansson就在他的blog上做了一個(gè)用樣式控制表單元素的測(cè)試, 告訴我們企圖用樣式控制表單元素是一件不可能的事情

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

甚至css2.1規(guī)范中也沒(méi)有明確這方面的規(guī)定, 而是打算將它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.

所以如果想要讓表單元素在各個(gè)瀏覽器下完全一致, 最好的解決方法莫過(guò)于完全不理會(huì)操作系統(tǒng)的樣式, 用自定義的ui風(fēng)格, 就像bing或Google的Jazz UI那樣

然而, 這會(huì)導(dǎo)致界面和用戶的系統(tǒng)格格不入, 目前google主要還是針對(duì)瀏覽器做了些特殊處理, 如webkit下用gradient使得按鈕看上去好些

mac下webkit的按鈕不好控制

本文將就輸入框高度的問(wèn)題進(jìn)行調(diào)研, 尋找更好的解決方法

 

輸入框高度

首先, 這個(gè)調(diào)研的一個(gè)主要原因是, 搜索結(jié)果頁(yè)打算進(jìn)入標(biāo)準(zhǔn)模式, 這會(huì)導(dǎo)致盒模型的變化, 造成輸入框高度和原來(lái)不一樣, 所以為了和線上效果保持一致, 我們需要找到一個(gè)最佳的解決方案

有同學(xué)可能會(huì)不解, 有那么難么? 設(shè)置一個(gè)height不就解決了么?


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

然而, 經(jīng)測(cè)試發(fā)現(xiàn)這里面的細(xì)節(jié)問(wèn)題還是還挺多, 由于資源有限, 這里只測(cè)試了主要的瀏覽器和平臺(tái), 包括目前主要用到的5個(gè)瀏覽器

  • 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)

通過(guò)設(shè)定height的方式

我們的目標(biāo)是和目前搜索框大小保持一致, 既28px

首先測(cè)試的是最簡(jiǎn)單的height, 先看目前線上的方案(簡(jiǎn)單起見(jiàn)就直接寫到style中了)


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

從樣式上推導(dǎo), 由于盒模型問(wèn)題, 在IE下的大小將是1.78 * 16 = 28px, 而Firefox等瀏覽器應(yīng)該是1.78 * 16 + 2px + border-width * 2 = 30 + ? px

測(cè)試結(jié)果是

瀏覽器 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

效果相當(dāng)理想, 所有瀏覽器都是28px, 看來(lái)即使是Firefox和Chrom在quirks模式下的input都沒(méi)有遵循盒模型, 所以線上的輸入框高度在各個(gè)瀏覽器下很完美地保持一致

然而如果是在standards模式下, 結(jié)果則是

瀏覽器 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

就僅僅加了一句, 卻導(dǎo)致瀏覽器差距變得如此大, 仔細(xì)觀察發(fā)現(xiàn), 主要問(wèn)題在Firefox上 它的border在win7下是1像素, xp下是2像素, mac下是3像素, 令人很頭疼, 于是打算換一種方案試試

padding的方式

由于Firefox的border問(wèn)題, 設(shè)定height是不可能保證高度一致的, 除非判斷再去判斷操作系統(tǒng)類型, 但那樣做太麻煩了, 而且說(shuō)不定mobile版又不一樣

那是否可以不通過(guò)設(shè)置height來(lái)控制? 在目前的大搜索首頁(yè)也是standards模式, 它是采用padding的方式來(lái)實(shí)現(xiàn)28px的高度的


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

這種寫法的測(cè)試結(jié)果是

瀏覽器 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

在不設(shè)定輸入框高度的情況下, 瀏覽器會(huì)自行指定一個(gè), 而且都有差距, mac上的Firefox更是高出了4像素, 但總的來(lái)說(shuō), 效果雖然不完美, 但還是可以接受, 大部分情況下都只差一個(gè)像素

然而這種方法帶來(lái)了很多不確定性, 內(nèi)容區(qū)的高度是隨著字體大小而變的, 假設(shè)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都無(wú)法完美控制輸入框高度, 而border的大小又不能改, 難道就真的沒(méi)辦法了么? 不禁懷念quirks模式下的方便, 設(shè)定一個(gè)高度就完美了, 要是能既進(jìn)standards模式, 又能用到舊盒模型就好了, 很自然地就想到了一個(gè)從來(lái)沒(méi)用過(guò)的css屬性box-sizing, 以前一直沒(méi)想好這屬性到底能用在哪里, 終于這下派上用場(chǎng)了, 使用它我們就可以解決Firefox下3種border的區(qū)別, 讓Firefox自己去算內(nèi)容區(qū)的高度

然而由于IE6/7不支持這個(gè)屬性, 所以需要寫hack, 由于IE下的默認(rèn)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屬性的支持情況如下表所示, 來(lái)自mozilla, 支持的訪問(wèn)非常廣

Browser Lowest Version Support 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

不過(guò), 事情還沒(méi)有結(jié)束, 剛才假定了IE下默認(rèn)padding是1像素, 然而目前很多css reset都會(huì)將input的padding設(shè)為0, 于是, IE下的差別將不是6像素, 而是4像素, 所以為了避免受到影響, 建議將padding設(shè)為0


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

瀏覽器在quirks下的實(shí)現(xiàn)方法

回過(guò)頭來(lái)看Firefox和Chrome在quirks模式下使用了非標(biāo)準(zhǔn)的盒模型, 看樣子是有意去做的, 它是如何實(shí)現(xiàn)的呢?

于是在webkit源碼中尋找, 一開(kāi)始以為它是在源碼中對(duì)quirks下的input做了特殊處理, 但沒(méi)看找到又什么特別的地方, 而在看到計(jì)算box高度的時(shí)候


		int RenderBox::calcContentBoxHeight(int height) const
{
    if (style()->boxSizing() == BORDER_BOX)
        height -= (borderTop() + borderBottom() + paddingTop() + paddingBottom());
    return max(0, height);
}

忽然想到, 會(huì)不會(huì)是通過(guò)瀏覽器默認(rèn)樣式來(lái)實(shí)現(xiàn)的呢? 將這種特殊的邏輯直接寫在代碼中確實(shí)太惡心了, 既然支持box-sizing屬性, 直接將它寫在quirks的默認(rèn)樣式不就完美解決了么

果然, 在Firefox的res/quirk.css中發(fā)現(xiàn)了這句


		/*
* Quirk: Use border-box box sizing for text inputs, password inputs, and
* textareas.  (b=184478 on why we use content-box sizing in standards mode)
*/

/* Note that all other
<input />s already use border-box
sizing, so we're ok with this selector */
input:not([type=image]), textarea {
  -moz-box-sizing: border-box;
}

在webkit源碼中的WebCore/css/quirks.css發(fā)現(xiàn)了這句


		/* This will apply only to text fields, since all other inputs already use border box sizing */
input:not([type=image]), textarea {
    -webkit-box-sizing: border-box;
}

原來(lái)瀏覽器就是這么解決的, 那么在標(biāo)準(zhǔn)模式下用它將是一種比較好的方案

one more thing

不過(guò)這種寫法在Firefox 3.5以下的版本會(huì)有個(gè)問(wèn)題, 那就是輸入框內(nèi)容將無(wú)法垂直居中, 以英文為例, 3.5中和頂部的差距是5像素, 而3.6是7像素, 目前還沒(méi)想到解決方案

幸好在Firefox 3.6中解決了這個(gè)問(wèn)題, 而且3.5會(huì)默認(rèn)升級(jí)到3.6, 所以這個(gè)問(wèn)題也就不需要考慮了

結(jié)論

從這個(gè)例子可以痛苦地體驗(yàn), 如果沒(méi)有統(tǒng)一的規(guī)范, 要兼容不同瀏覽器是如此的困難, 而且這還僅僅是一個(gè)很不完全的測(cè)試, 好在瀏覽器還是盡可能做到了最大兼容, 比如, 假設(shè)windows下默認(rèn)主題和經(jīng)典主題有區(qū)別, 就意味著所有windows下的測(cè)試都要乘2。。。

[教程作者:admin]
免責(zé)聲明:本站文章系圖趣網(wǎng)整理發(fā)布,如需轉(zhuǎn)載,請(qǐng)注明出處,素材資料僅供個(gè)人學(xué)習(xí)與參考,請(qǐng)勿用于商業(yè)用途!
本文地址:http://m.pkvc.cn/tutorial/wd1384.html
網(wǎng)頁(yè)前端開(kāi)發(fā)IE BUG系列之雙邊距BUG
更加有效的進(jìn)行網(wǎng)頁(yè)交互評(píng)審
圖趣網(wǎng)微信
建議反饋
×