1. 程式人生 > >移動端h5 輸入框padding-left會導致放大

移動端h5 輸入框padding-left會導致放大

移動端html5 輸入框padding-left會導致放大

解決辦法:

input { width: calc(100% - 10px); padding-left: 10px; } 

目前而言,好的解決之道是widthpadding均採用百分比值,例如下面這樣:

firefox低版本可能存在問題
input { width: 92%; padding-left: 4%; padding-right: 4%; }
IE低版本可能會存在問題
input { width: 100%; text-indent: 4%; }


一、問題描述

我是流體佈局控,經常會遇到文字框以及文字域寬度100%自適應顯示的情況。

如下效果圖:
文字域寬度100%顯示 張鑫旭-鑫空間-鑫生活

在窄屏下,上面的文字框寬度也要跟著外部寬度變小。

難點
對於文字框或者文字域,游標最好距離左側邊緣有一定的間距。因此,我們基本上都有類似下面的設定:

input { padding-left: 10px; }

但是,如果只考慮文字框本身(父標籤無其他特殊處理),這一套在流體環境下是行不通的,因為固定的padding陣列無法讓文字框永遠100%自適應外部的寬度,至少非現代瀏覽器下是如此!//zxx: CSS3計算(calc())就是為了解決這類問題才誕生的!

input { width: calc(100% - 10px); padding-left: 10px; } 

目前而言,好的解決之道是width

padding均採用百分比值,例如下面這樣:

input { width: 92%; padding-left: 4%; padding-right: 4%; }

問題
上面這種寫法,IE6+, Opera, Chrome, Safari瀏覽器都是顯示很OK的;唯獨FireFox火狐瀏覽器,其雖然寬度渲染正常,但是,游標的位置確是頂頭的(與數值padding的顯示完全不同)。

如下截圖:
FireFox下面文字框百分比padding顯示的問題截圖

這個問題再FireFox瀏覽器下存在已經有3年之久了,到現在還沒有修復。您可以狠狠地點選這裡:FireFox下文字框百分比padding位置bug demo

如何修復這個問題呢?

//zxx: 可能有人會提議div模擬文字框(即div設定padding值), 文字框本身no border, no padding, 且width:100. 這種操蛋的方法我是一點都不喜歡的(純屬個人喜好,沒有攻擊的意思),一是囉嗦;二來文字框本身可能就有box-shadow, outline以及內聯的互動驗證UI(如驗證非法紅色外發光),難道你想把這些都抹殺掉??

更新2012-11-30

注意:FireFox 17+已經修復了該問題!

二、text-indent修復法

firefox瀏覽器下的問題其實只是文字的位置問題而已,其本身的寬度渲染都是準確的,因此,我們可以把解決問題的關鍵點放在解決文字不縮排的問題上——我們自然而然就會想到文字縮排屬性text-indent.

於是,在FireFox瀏覽器下,我們只要設定:

input { text-indent: 4%; }

就可以了!

現在的問題是,如何只讓FireFox瀏覽器設定這個屬性呢??FireFox瀏覽器有專屬的hack嗎?

我們開啟FireBug, 點選下圖所示的地方:
FireBug開啟瀏覽器預設的樣式設定 張鑫旭-鑫空間-鑫生活

於是,對於剛才的文字框,我們會看到FireFox瀏覽器預設對其的設定,其中有個這個:
文字框預設的一些屬性設定 張鑫旭-鑫空間-鑫生活

這正是我們需要的,因此,新增類似下面的補丁:

input:-moz-read-write{text-indent:4%;}

即可完美修復FireFox瀏覽器下游標以及文字頂頭顯示的bug.

修復之後的效果如下截圖:
FireFox瀏覽器下text-indent修復後截圖 張鑫旭-鑫空間-鑫生活

1024寬度下的截圖:
1024寬度下FireFox瀏覽器下修復截圖

可能的疑問
說到這裡,可能有比較靈光的同行會疑問,既然text-indent可以讓文字位置後移,那為何要使用padding呢,直接:

input { width: 100%; text-indent: 4%; }

不就可以了嗎?

這確實是個不錯的idea, 只可惜在IE6/IE7瀏覽器下,text-indent會偏移文字框的位置(連文字框自身一起縮進了!)。如下截圖示意:
IE6/IE7下文字框一起縮進了! 張鑫旭-鑫空間-鑫生活

如下測試程式碼:

.box{padding:40px 0; background-color:#B70D0D;}
.box input { width: 200px; text-indent: 20px; }
<p class="box"><input value="我是文字" /></p>

IE8+以及其他瀏覽器下都是OK的,縮排的只是文字框的文字,文字框不動,如下示意:

侷限
text-indent撐開文字邊距是有侷限性的,顯而易見,其只能讓第一行文字有邊距。於是,當面對多行文字域(textarea)的時候,text-indent就捉襟見肘,無能為力了!

因此,對於文字域,我們需要尋求其他完善方法。

三、box-sizing的修復策略

FireFox下文字框或文字域對百分比padding值的顯示有問題,但是對具體px的padding值顯示卻正常。因此,我們可以設定padding-left/padding-right為類似10px這樣的具體數值,而把問題解決的重心放在如何寬度100%顯示上。

在CSS3屬性中,有個叫做box-sizing的好東西,IE8+以及現代瀏覽器都支援,如果我們設定該屬性值為border-box,則padding值不會撐大元素的設定寬度,如width:100px; padding:10px;最後元素佔據的寬度還是100畫素而不是120畫素。

於是,這裡,我們可以如下設定CSS:

input:-moz-read-write{width:100%; height:40px; padding:10px; -moz-box-sizing:border-box;}

FireFox即問題修復,如下截圖:
box-sizing修復後的FireFox瀏覽器截圖 張鑫旭-鑫空間-鑫生活

四、CSS3 cacl()計算修復

上面的box-sizing方法影響到了原本OK的height設定,而使用CSS3 cacl()計算只針對目標屬性width進行處理,如下修復程式碼:

input:-moz-read-write{width:-moz-calc(100% - 20px); padding:10px;}

注意,減號(-)前後需要有空格,否則無法識別。

於是,有大致如下的修復效果圖(FireFox瀏覽器截圖):
CSS3 cacl()計算修復後的FireFox瀏覽器截圖 張鑫旭-鑫空間-鑫生活

五、文字框文字域含邊框時的處理

到目前為止所示的情況都是不含邊框的,基本上,全世界90%+的文字框或者是文字域都是有border的,或自身的或CSSer設定的,要知道,border是不支援百分比寬度的,只能是固定數值大小的單位。現在問題來了:含有border的文字域文字框如何實現寬度100%的自適應呢??

使用padding正值+margin負值補間技術
//zxx: 這裡的內容有些偏題,不過多展開。

固定數值與文字域100%寬度顯示截圖縮圖

demo中,上面一個例子是僅邊框是固定畫素值;下面一個是邊框以及左右padding都是固定數值。都實現了良好的100%自適應,相容IE6以及IE7瀏覽器。

原理(見下圖圈中,不言而喻):

然而,在實際的專案中,我並不經常使用上面的方法。一是牽扯父標籤;二是牽扯計算;三是無法大範圍重用(原因是父標籤的padding值設定受限)。