如何更好地控制input輸入框的高度
發(fā)布時間:2011-01-04 11:12:13 作者:佚名
我要評論

很久以前 Roger Johansson 就在他的 blog 上做了一個 用樣式控制表單元素 的測試 , 告訴我們企圖用樣式控制表單元素是一件不可能的事情
很久以前 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.
甚至 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 type= "text" style= "height:28px" />
然而 , 經(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 type= "text" style= "font: 16px arial; height: 1.78em; padding-top:2px" />
從樣式上推導(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
|
就僅僅加了一句 <!DOCTYPE html> , 卻導(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 type= "text" style= "font: 16px arial; padding:3px" />
這種寫法的測試結(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.
相關(guān)文章
- CSS Grid 是一種二維布局系統(tǒng),可以同時控制行和列,相比 Flex(一維布局),更適合用在整體頁面布局或復(fù)雜模塊結(jié)構(gòu)中,這篇文章主要介紹了前端CSS Grid 布局詳解,需要的朋2025-04-16
CSS Padding 和 Margin 區(qū)別全解析
CSS 中的 padding 和 margin 是兩個非?;A(chǔ)且重要的屬性,它們用于控制元素周圍的空白區(qū)域,本文將詳細(xì)介紹 padding 和 margin 的概念、區(qū)別以及如何在實際項目中使用它們2025-04-07- will-change 是一個 CSS 屬性,用于告訴瀏覽器某個元素在未來可能會發(fā)生哪些變化,本文給大家介紹CSS will-change 屬性詳解,感興趣的朋友一起看看吧2025-04-07
- 本文給大家分享在 CSS 中,去除a標(biāo)簽(超鏈接)的下劃線的幾種方法,本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2025-04-07
- 在前端開發(fā)中,CSS(層疊樣式表)不僅是用來控制網(wǎng)頁的外觀和布局,更是實現(xiàn)復(fù)雜交互和動態(tài)效果的關(guān)鍵技術(shù)之一,隨著前端技術(shù)的不斷發(fā)展,CSS的用法也日益豐富和高級,本文將2025-04-07
css中的 vertical-align與line-height作用詳解
文章詳細(xì)介紹了CSS中的`vertical-align`和`line-height`屬性,包括它們的作用、適用元素、屬性值、常見使用場景、常見問題及解決方案,感興趣的朋友跟隨小編一起看看吧2025-03-26淺析CSS 中z - index屬性的作用及在什么情況下會失效
z-index屬性用于控制元素的堆疊順序,值越大,元素越顯示在上層,它需要元素具有定位屬性(如relative、absolute、fixed或sticky),本文給大家介紹CSS 中z - index屬性的作用2025-03-21- 文章詳細(xì)介紹了CSS中的打印媒體查詢@mediaprint包括基本語法、常見使用場景和代碼示例,如隱藏非必要元素、調(diào)整字體和顏色、處理鏈接的URL顯示、分頁控制、調(diào)整邊距和背景等2025-03-18
CSS模擬 html 的 title 屬性(鼠標(biāo)懸浮顯示提示文字效果)
本文介紹了如何使用CSS模擬HTML的title屬性,通過鼠標(biāo)懸浮顯示提示文字效果,通過設(shè)置`.tipBox`和`.tipBox.tipContent`的樣式,實現(xiàn)了提示內(nèi)容的隱藏和顯示,感興趣的朋友一起2025-03-10前端 CSS 動態(tài)設(shè)置樣式::class、:style 等技巧(推薦)
本文介紹了Vue.js中動態(tài)綁定類名和內(nèi)聯(lián)樣式的兩種方法:對象語法和數(shù)組語法,通過對象語法,可以根據(jù)條件動態(tài)切換類名或樣式;通過數(shù)組語法,可以同時綁定多個類名或樣式,此外2025-02-26