【譯】HTML表單樣式

本文中,咱們將學習如何使用CSS來讓HTML表單看起來更漂亮,這可能須要竅門才能作到。因爲歷史及技術上的緣由,表單組件並不太適合使用CSS;而也正由於有這些困難,許多的開發者會選擇[建立定製表單組件]()來得到對外觀和體驗的控制。然而,在現代瀏覽器中,網頁設計師能夠擁有更多對錶單元素的控制權了。讓咱們來深刻了解下吧。git

爲什麼難以使用CSS給表單組件添加樣式?

在web發展的早期,大約1995年,表單控件就已經在the HTML 2 specification中給添加到HTML了。因爲表單組件的複雜性,瀏覽器開發商們就選擇了依靠操做系統來管理和渲染它們。github

幾年以後,CSS誕生了,這就在技術上使得用原生組件來實現表單的作法也有了樣式需求。然而在CSS的早期,給表單控件添加樣式並未被優先考慮。web

因爲用戶們習慣了在交互平臺上的視覺體驗,瀏覽器開發商不得不讓表單控件能夠被添加樣式;而說實話,在今天也依然難以重構全部表單控件讓它們可被樣式化。chrome

即便到了如今,也依然沒有一個單獨的瀏覽器實現了全部CSS 2.1規範。然而隨着時間推移,瀏覽器開發商們已經改進了表單元素的CSS支持,雖然其可用性仍受詬病,但如今你已經可使用CSS來給HTML表單添加樣式了。segmentfault

並不是全部組件受CSS的影響都是平等的

現在在表單使用CSS時依然有一些困難;這些問題可歸爲三類:瀏覽器

還好的

若存在跨平臺問題,一些元素能夠只添加少量的樣式,有以下幾個結構元素:app

  1. <form>ide

  2. <fieldset>

  3. <label>

  4. <output>

此外,還有全部的文本框組件(單行或多行),以及按鈕。

比較糟糕的

一些元素只能使用不多的樣式,並且得依賴一些複雜的技巧,偶爾還得用到CSS3的高級知識。

這其中包括了<legend>元素;該元素不能在跨平臺時被恰當地定位。此外,複選框及單選框不能直接添加樣式;然而有了CSS3以後你就能夠作到這點了。placeholder的內容是不能經過標準方法來添加樣式的,但全部實現了它的瀏覽器都會以私有的CSS僞元素或僞類的形式讓你能給它添加樣式。

至於要具體如何處理這些特殊狀況,咱們會在[HTML表單高級樣式]()一文中討論。

醜陋的

某些元素是不能用CSS添加樣式的。它們包括全部的高級UI組件好比範圍滑塊、顏色、日期控件,以及下拉組件(包括<select>, <option>, <optgroup>, <datalist> 等元素)。文件選擇器組件也被認爲是不能添加樣式的,而新的<progress><meter>元素也在此之列。

這些組件的主要問題在於,它們擁有很是複雜的結構,而CSS沒有足夠的表現力來給這些組件的各個細節添加樣式。若你非得定製這些組件,就只能依靠Javascript來構建一棵能讓你添加樣式的DOM樹。咱們將在如何建立定製表單組件一文中學習如何作到這一點。

基本樣式

在用CSS給那些易於添加樣式的元素的元素以樣式時,你沒必要面對任何困難,由於它們多數表現得和其它HTML元素同樣。然而,每一個瀏覽器的用戶代理樣式表會致使一些不一致的狀況,因此,這裏會有幾個技巧來幫你輕鬆地給它們添加樣式。

搜索框

搜索框是文本框中惟一一種須要點技巧來添加樣式的。在基於webkit的瀏覽器(chrome, safari等)中,你得用-webkit-appearance屬性來做下調整。咱們將會在[HTML表單高級樣式]()一文更深刻地探討該屬性。

例子

<form>
  <input type="search">
</form>
input[type=search] {
  border: 1px dotted #999;
  border-radius: 0;

  -webkit-appearance: none;
}

在上面這張Chrome的搜索框截圖中,連個文本框都設置了邊框,但第一個文本框沒有使用-webkit-appearance屬性進行渲染,而第二個賊使用了-webkit-appearance:none。它們間的差異值得注意。

字體和文本

CSS字體和文本特性在任何組件中均可以被輕易使用(固然,你也能夠在表單組件上使用@font-face)。然而,不一樣瀏覽器的行爲表現一般是不同的。某些組件默認不會從父元素那繼承font-familyfont-size,同時許多瀏覽器會使用系統的默認樣式來做爲替代。要讓你的表單的外觀與其餘內容保持一致,你能夠在樣式表中添加以下規則:

button, input, select, textarea {
  font-family : inherit;
  font-size   : 100%;
}

下面的截圖體現了設置以後的不一樣;左邊是MAC OSX的Firefox中元素的默認渲染效果,其使用了系統的默認字體樣式。而右邊則是使用了上面的字體協調樣式後的相同元素。

要使用系統默認樣式仍是自定義樣式以適應頁面內容,仍存在不少爭議。這個決定權在於身爲網頁或web應用設計師的你身上。

盒模型

全部的文本框都徹底支持CSS盒模型相關的屬性(width, height, padding, margin, border)。然而之前要呈現這些組件時,瀏覽器都得依賴系統的默認樣式。至於如何把這些樣式混用到你的頁面中,這得取決於你。

若你想保持這些原生組件的樣子和體驗,你會在給它們實現一致的樣式時遇到點困難。這是由於每一個組件都有它們獨有的邊框、內邊距和外邊距的規定。因此,若是你但願在幾個不一樣的組件間保持相同的大小,你就得使用box-sizing屬性:

input, textarea, select, button {
  width : 150px;
  margin: 0;

  -webkit-box-sizing: border-box; /* 兼容基於Webkit的舊版瀏覽器 */
     -moz-box-sizing: border-box; /* 兼容基於Gecko的舊版瀏覽器(Firefox < 29) */
          box-sizing: border-box;
}

上面的截圖中,左邊一列是不使用box-sizing構建的,而右邊一列則使用了該屬性並賦予其值border-box。可見設置該屬性讓全部的元素都佔據了相同的空間大小,而覆蓋了系統給各類組件的默認規則。

定位

定位HTML表單元素一般不是什麼大問題,然而有兩個特殊元素值得你關注一下:

legend

<legend>元素能夠很好地支持樣式,除了定位。在每種瀏覽器中,<legend>元素都位於其父<fieldset>元素的上邊框以上,根本沒辦法在HTML文檔流中改變其定位、讓其遠離那個上邊框。你只能使用position屬性來讓其絕對或相對定位,不然它就只能視做是fieldset邊框的一部分。

覺得無障礙技術的緣由,使得<legend>成爲很重要的元素(它做爲fieldset中各個表單組件的label,並以此被無障礙設備讀出),一般他會和一個標題作搭配,並以無障礙技術可識別的形式隱藏起來,就像這樣:

<fieldset>
  <legend>Hi!</legend>
  <h1>Hello</h1>
</fieldset>
legend {
  width: 1px;
  height: 1px;
  overflow: hidden;
}

textarea

全部瀏覽器都默認將textarea元素看成內聯元素,並讓它與文本的底線對齊。而這種設定一般並非咱們想要的,使用display屬性能夠很容易就將其從inline-block改成block。但若你還想把它當內聯元素使用,那一般得改變其垂直對齊方式:

textarea {
  vertical-align: top;
}

實例

來看一個給表單以樣式的例子吧,經過例子,許多相關的知識點會更容易理解些。而咱們要構建的,是以下圖所示的contact表單:

HTML

相比[本指南第一篇文章](),這裏的HTML稍微多了點內容;只有幾個額外的字段和一個標題而已。

<form>
  <h1>to: Mozilla</h1>

  <div id="from">
    <label for="name">from:</label>
    <input type="text" id="name" name="user_name">
  </div>

  <div id="reply">
    <label for="mail">reply:</label>
    <input type="email" id="mail" name="user_email">
  </div>

  <div id="message">
    <label for="msg">Your message:</label>
    <textarea id="msg" name="user_message"></textarea>
  </div>
 
  <div class="button">
    <button type="submit">Send your message</button>
  </div>
</form>

CSS

有趣的部分開始了,但在咱們編碼以前,還須要三個額外的資源:

  1. 明信片背景

  2. 一套打字機字體:fontsquirrel.com上的"Secret Typewriter"

  3. 一套手寫字體:fontsquirrel.com上的"Journal"

如今咱們能夠投入寫代碼了。首先,咱們要準備好@font-face的定義以及<body><form>元素的基本樣式:

@font-face{
  font-family : "handwriting";

  src : url('journal.eot');
  src : url('journal.eot?') format('eot'),
        url('journal.woff') format('woff'),
        url('journal.ttf') format('truetype');
}

@font-face{
  font-family : "typewriter";

  src : url('veteran_typewriter.eot');
  src : url('veteran_typewriter.eot?') format('eot'),
        url('veteran_typewriter.woff') format('woff'),
        url('veteran_typewriter.ttf') format('truetype');
}

body {
  font  : 21px sans-serif;

  padding : 2em;
  margin  : 0;

  background : #222;
}

form {
  position: relative;

  width  : 740px;
  height : 498px;
  margin : 0 auto;

  background: #FFF url(background.jpg);
}

而後咱們來定位標題和全部表單元素:

h1 {
  position : absolute;
  left : 415px;
  top  : 185px;
 
  font : 1em "typewriter", sans-serif;
}

#from {
  position: absolute;
  left : 398px;
  top  : 235px;
}

#reply {
  position: absolute;
  left : 390px;
  top  : 285px;
}

#message {
  position: absolute;
  left : 20px;
  top  : 70px;
}

接下來,咱們得開始對錶單元素自身作配置了。首先,確保<label>使用了正確的字體:

label {
  font : .8em "typewriter", sans-serif;
}

文本框須要使用一些公共樣式。簡單起見,能夠移除它們的邊框和背景,而後從新定義其內外邊距:

input, textarea {
  font    : .9em/1.5em "handwriting", sans-serif;

  border  : none;
  padding : 0 10px;
  margin  : 0;
  width   : 240px;

  background: none;
}

而當這些輸入框得到焦點時,還得讓它們用一個淺灰色、半透明背景作高亮。注意爲了移除一些瀏覽器自帶默認的高亮,還須要配置outline屬性:

input:focus, textarea:focus {
  background   : rgba(0,0,0,.1);
  border-radius: 5px;
  outline      : none;
}

如今咱們的文本框已經整好了,但咱們還得調整單行和多行文本框以做適配,由於一般它們看起來是一點都不相同的。

對單行文本框須要一些微調以讓其在IE下看起來漂亮點。IE不是基於字體的天然高度來定義文本框高度的(但其它全部瀏覽器都這麼作),要修復這點,咱們得給文本框指定一個明確的高度,以下所示:

input {
    height: 2.5em; /* 針對IE */
    vertical-align: middle; /* 可選配置,能在舊版IE中看起來漂亮點 */
}

<textarea>元素應被預設置爲塊級元素進行渲染。這裏還有兩個重要的屬性,resizeoverflow。因爲咱們採用固定大小的設計,因此得使用resize屬性來防止用戶改變多行文本框的大小。而overflow屬性則讓文本框在不一樣瀏覽器下的效果趨於一致;由於有的瀏覽器默認使用值auto而另外一些使用值scroll。本例中,最好得保證各個瀏覽器下都使用auto

textarea {
  display : block;

  padding : 10px;
  margin  : 10px 0 0 -10px;
  width   : 340px;
  height  : 360px;

  resize  : none;
  overflow: auto;
}

<button>元素能夠很方便地使用CSS;這樣你就能夠盡情發揮了,即便用上僞元素也沒問題!

button {
  position     : absolute;
  left         : 440px;
  top          : 360px;

  padding      : 5px;

  font         : bold .6em sans-serif;
  border       : 2px solid #333;
  border-radius: 5px;
  background   : none;

  cursor       : pointer;

-webkit-transform: rotate(-1.5deg);
   -moz-transform: rotate(-1.5deg);
    -ms-transform: rotate(-1.5deg);
     -o-transform: rotate(-1.5deg);
        transform: rotate(-1.5deg);
}

button:after {
  content: " >>>";
}

button:hover,
button:focus {
  outline   : none;
  background: #000;
  color   : #FFF;
}

隨意嘗試下吧,試了你才知道你能夠作到!

結論

如你所見,若是咱們想構建只含文本框和按鈕的表單,那麼用CSS來提供樣式是件很容易的事。若你還想了解多些能讓你更輕鬆地處理表單組件的CSS技巧,能夠參見normalize.css項目的表單部分。

[下篇文章](),咱們會學習如何處理那些屬於「比較糟糕的」和「醜陋的」類別的表單組件。

相關文章
相關標籤/搜索