本文中,咱们将学习如何使用CSS来让HTML表单看起来更漂亮,这可能须要窍门才能作到。因为历史及技术上的缘由,表单组件并不太适合使用CSS;而也正由于有这些困难,许多的开发者会选择[建立定制表单组件]()来得到对外观和体验的控制。然而,在现代浏览器中,网页设计师能够拥有更多对表单元素的控制权了。让咱们来深刻了解下吧。git
在web发展的早期,大约1995年,表单控件就已经在the HTML 2 specification中给添加到HTML了。因为表单组件的复杂性,浏览器开发商们就选择了依靠操做系统来管理和渲染它们。github
几年以后,CSS诞生了,这就在技术上使得用原生组件来实现表单的作法也有了样式需求。然而在CSS的早期,给表单控件添加样式并未被优先考虑。web
因为用户们习惯了在交互平台上的视觉体验,浏览器开发商不得不让表单控件能够被添加样式;而说实话,在今天也依然难以重构全部表单控件让它们可被样式化。chrome
即便到了如今,也依然没有一个单独的浏览器实现了全部CSS 2.1规范。然而随着时间推移,浏览器开发商们已经改进了表单元素的CSS支持,虽然其可用性仍受诟病,但如今你已经可使用CSS来给HTML表单添加样式了。segmentfault
现在在表单使用CSS时依然有一些困难;这些问题可归为三类:浏览器
若存在跨平台问题,一些元素能够只添加少量的样式,有以下几个结构元素:app
此外,还有全部的文本框组件(单行或多行),以及按钮。
一些元素只能使用不多的样式,并且得依赖一些复杂的技巧,偶尔还得用到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-family和font-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>
元素都位于其父<fieldset>
元素的上边框以上,根本没办法在HTML文档流中改变其定位、让其远离那个上边框。你只能使用position属性来让其绝对或相对定位,不然它就只能视做是fieldset边框的一部分。
觉得无障碍技术的缘由,使得<legend>
成为很重要的元素(它做为fieldset中各个表单组件的label,并以此被无障碍设备读出),一般他会和一个标题作搭配,并以无障碍技术可识别的形式隐藏起来,就像这样:
<fieldset> <legend>Hi!</legend> <h1>Hello</h1> </fieldset>
legend { width: 1px; height: 1px; overflow: hidden; }
全部浏览器都默认将textarea元素看成内联元素,并让它与文本的底线对齐。而这种设定一般并非咱们想要的,使用display属性能够很容易就将其从inline-block
改成block
。但若你还想把它当内联元素使用,那一般得改变其垂直对齐方式:
textarea { vertical-align: top; }
来看一个给表单以样式的例子吧,经过例子,许多相关的知识点会更容易理解些。而咱们要构建的,是以下图所示的contact表单:
相比[本指南第一篇文章](),这里的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>
有趣的部分开始了,但在咱们编码以前,还须要三个额外的资源:
明信片背景
一套手写字体: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>
元素应被预设置为块级元素进行渲染。这里还有两个重要的属性,resize和overflow。因为咱们采用固定大小的设计,因此得使用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项目的表单部分。
[下篇文章](),咱们会学习如何处理那些属于“比较糟糕的”和“丑陋的”类别的表单组件。