【译】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项目的表单部分。

[下篇文章](),咱们会学习如何处理那些属于“比较糟糕的”和“丑陋的”类别的表单组件。

相关文章
相关标签/搜索