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

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

 

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

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

甚至css2.1規(guī)范中也沒有明確這方面的規(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.

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

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

mac下webkit的按鈕不好控制

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

 

輸入框高度

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

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


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

然而, 經(jīng)測試發(fā)現(xiàn)這里面的細(xì)節(jié)問題還是還挺多, 由于資源有限, 這里只測試了主要的瀏覽器和平臺, 包括目前主要用到的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)

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

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

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


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

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

測試結(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, 看來即使是Firefox和Chrom在quirks模式下的input都沒有遵循盒模型, 所以線上的輸入框高度在各個瀏覽器下很完美地保持一致

然而如果是在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), 主要問題在Firefox上 它的border在win7下是1像素, xp下是2像素, mac下是3像素, 令人很頭疼, 于是打算換一種方案試試

padding的方式

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

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


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

這種寫法的測試結(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è)定輸入框高度的情況下, 瀏覽器會自行指定一個, 而且都有差距, mac上的Firefox更是高出了4像素, 但總的來說, 效果雖然不完美, 但還是可以接受, 大部分情況下都只差一個像素

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

然而由于IE6/7不支持這個屬性, 所以需要寫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屬性的支持情況如下表所示, 來自mozilla, 支持的訪問非常廣

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

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


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

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

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

于是在webkit源碼中尋找, 一開始以為它是在源碼中對quirks下的input做了特殊處理, 但沒看找到又什么特別的地方, 而在看到計算box高度的時候


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

忽然想到, 會不會是通過瀏覽器默認(rèn)樣式來實現(xiàn)的呢? 將這種特殊的邏輯直接寫在代碼中確實太惡心了, 既然支持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;
}

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

one more thing

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

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

結(jié)論

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

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