这篇翻译不完整。请帮忙从英语翻译这篇文章

在这篇文章中,用户将学习如何使用HTML表单和CSS以使页面更加美观。令人惊讶的是,这可能有点棘手。由于历史和技术的原因,表单部件不能很好地与CSS配合工作。 由于这些困难,许多开发人员选择构建自己的HTML小部件以获得更好的控制和视觉观感。 然而,在现代浏览器中,web设计者越来越多地控制表单元素的设计。让我们深入研究。

为什么使用CSS美化表单组件这么困难?

在1995年左右的Web早期,表单组件(或控件)在 HTML 2规范中被添加到HTML。由于表单组件的复杂性,实现者选择依靠底层操作系统来管理和渲染它们。

若干年后,CSS被创建出来了,那么技术上的必要性,就是使用原生组件来实现表单控制,这是因为风格的要求。在CSS的早期,表单样式控制不是优先事项。

由于用户习惯于各自平台的视觉外观,浏览器厂商不愿意对表单控件样式进行调整;到目前为止,要重建所有控件以使它们可美化仍然是非常困难的。

即使在今天,仍然没有一个浏览器完全实现了CSS 2.1。然而,随着时间的推移,浏览器厂商已经改进了对表单元素的CSS支持,尽管可用性的声誉不好,但现在已经可以使用CSS来设计HTML表单

涉及到CSS,并非所有组件都是平等的

目前,在使用表单时使用CSS仍然有一些困难。这些问题可以分为三类: 

好的

有些元素在跨平台上时很少出现问题。包括以下结构元素:

  1. <form>
  2. <fieldset>
  3. <label>
  4. <output>

这还包括所有文本字段小部件(单行和多行)和按钮。

不好的

一些元素难以被美化,并且可能需要一些复杂的技巧,偶尔需要高级的CSS3知识。

这些包括<legend>元素,但不能在所有平台上正确定位。 Checkbox和radio按钮也不能直接应用样式,但是,感谢CSS3,你可以解决这个问题。placeholder 的内容不能以任何标准方式应用样式,但是实现它的所有浏览器也都实现了私有的CSS伪元素或伪类,让你可以对其定义样式。

We describe how to handle these more specific cases in the article Advanced styling for HTML forms.

丑陋的

有些元素根本不能用应用CSS样式。 这些包括:所有高级用户界面小部件,如范围,颜色或日期控件; 和所有下拉小部件,包括<select>, <option>, <optgroup><datalist> 元素。 文件选择器小部件也被称为不可风化。 新的<progress><meter> 元素也属于这个类别。

所有这些小部件的主要问题来自于它们具有非常复杂的结构,而CSS目前还不足以表达这些小部件的所有细微部分。 如果你想定制这些小部件,你必须依靠JavaScript来构建一个你能够应用样式的DOM树。 We explore how to do this in the article How to build custom form widgets.

基本样式美化

为了使用CSS美化容易被美化的元素,你并不会碰到任何困难,因为它们的大部分行为同其他HTML元素差不都。但是,每个浏览器的用户代理样式表可能会有点不一致,所以有一些技巧可以帮助您更轻松地设计它们。

Search字段

搜索框是唯一一种应用CSS样式有点棘手的文本字段。 在基于WebKit的浏览器(Chrome,Safari等)上,您必须使用-webkit-appearance专有属性来调整它。 我们在文章中进一步讨论这个属性:HTML表单的高级样式

Example

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

  -webkit-appearance: none;
}

This is a screenshot of a search filed on Chrome, with and without the use of -webkit-appearance

正如你在截图中所见,Chrome浏览器中的搜索字段两个字段在我们的例子中被设置为有边框。第一个字段没有使用-webkit-appearance渲染,而第二个使用 -webkit-appearance:none. 两者的不同显而易见。

字体和文本

CSS font和text功能能被很容易的应用到任何组件上(当然你可以在form组件上使用@font-face )。然而,浏览器的行为经常不一致。默认情况下,一些组件不不会从它们的父元素继承 font-familyfont-size 。相反,许多浏览器使用系统默认的字体和文本。为了让form表单的外观和其他内容保持一致,你可以在你的样式表中增加以下内容:

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

下面的截图显示了不同之处; 左边是Mac OS X上Firefox中元素的默认渲染,其中使用了平台的默认字体样式。 在右边是相同的元素,应用了我们的字体统一样式规则。

This is a screenshot of the main form widgets on Firefox on Mac OSX, with and without font harmonization

关于使用系统默认样式的表单还是使用设计用于匹配内容的自定义样式表单,有很多争议。 作为网站或Web应用程序的设计者,您可以自己做出决定。

盒子模型

所有文本字段都完全支持与CSS盒模型相关的每个属性(width, height, padding, margin, 和 border)。 但是,像以前一样,浏览器在显示这些小部件时依赖于系统默认的样式。 您需要定义如何将其融入到您的内容中。 如果你既想保持小部件的原生外观和感觉,又想给他们一个一致的尺寸,那么你会遇到一些困难(If you want to keep the native look and feel of the widgets, you'll face a little difficulty if you want to give them a consistent size)。

这是因为每个小部件都有自己的边框,填充和边距的规则。 所以如果你想给几个不同的小部件相同的大小,你必须使用box-sizing 属性:

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

  -webkit-box-sizing: border-box; /* For legacy WebKit based browsers */
     -moz-box-sizing: border-box; /* For legacy (Firefox <29) Gecko based browsers */
          box-sizing: border-box;
}

This is a screenshot of the main form widgets on Chrome on Windows 7, with and without the use of box-sizing.

在上面的屏幕截图中,左侧的列没有box-sizing,而右侧的列使用了这个属性和border-box。 请注意我们是怎样确保所有元素都占用相同的空间量,尽管平台对每种窗口小部件都有默认规则。

定位(Positioning)

HTML表单部件的定位通常不是问题; 但是,您应该特别注意两点:

legend

<legend>元素易于应用CSS,除了定位。在所有浏览器中, <legend> 元素定位是其 <fieldset> 父元素的上边框的最顶端。在HTML流中无法改变它的绝对位置,无法让其远离顶部边框。然而,你可以使用 position 属性将其位置设置为绝对或相对。除此之外,它近几年是fieldset边框的一部分。

由于<legend>元素对可访问性非常重要,因为它能被无障碍技术作为每个fieldset中的表单元素的标签读出来,它通常与标题配对,并且在无障碍中被隐藏 。例如:

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

textarea

默认情况下,所有浏览器都认为<textarea> 元素是inline block,与文本底线对齐。 这很少是我们真正想看到的。 要将内联(inline-block)块更改为块(block),使用display属性非常简单。 但是如果你想以inline方式使用它,通常改变垂直对齐方式:

textarea {
  vertical-align: top;
}

Example

Let's look at a concrete example of how to style an HTML form. This will help make a lot of these ideas clearer. We will build the following "postcard" contact form:

This is what we want to achieve with HTML and CSS

If you want to follow along with this example, make a local copy of our postcard-start.html file, and follow the below instructions.

The HTML

The HTML is only slightly more involved than the example we used in the first article of this guide; it just has a few extra IDs and a title.

<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>

Add the above code into the body of your HTML.

Organizing your assets

This is where the fun begins! Before we start coding, we need three additional assets:

  1. The postcard background — download this image and save it in the same directory as your working HTML file.
  2. A typewriter font: The "Secret Typewriter" font from fontsquirrel.com — download the TTF file into the same directory as above.
  3. A handdrawn font: The "Journal" font from fontsquirrel.com — download the TTF file into the same directory as above.

Your fonts need some more processing before you start:

  1. Go to the fontsquirrel Webfont Generator.
  2. Using the form, upload both your font files and generate a webfont kit. Download the kit to your computer.
  3. Unzip the provided zip file.
  4. Inside the unzipped contents you will find two .woff files and two .woff2 files. Copy these four files into a directory called fonts, in the same directory as before. We are using two different files for each font to maximise browser compatibility; see our Web fonts article for a lot more information.

The CSS

Now we can dig into the CSS for the example. Add all the code blocks shown below inside the <style> element, one after another.

First, we prepare the ground by defining our @font-face rules, all the basics on the <body> element, and the <form> element:

@font-face {
    font-family: 'handwriting';
    src: url('fonts/journal-webfont.woff2') format('woff2'),
         url('fonts/journal-webfont.woff') format('woff');
    font-weight: normal;
    font-style: normal;
}

@font-face {
    font-family: 'typewriter';
    src: url('fonts/veteran_typewriter-webfont.woff2') format('woff2'),
         url('fonts/veteran_typewriter-webfont.woff') format('woff');
    font-weight: normal;
    font-style: normal;
}

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);
}

Now we can position our elements, including the title and all the form elements:

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;
}

That's where we start working on the form elements themselves. First, let's ensure that the <label>s are given the right font:

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

The text fields require some common rules. Simply put, we remove their borders and backgrounds, and redefine their padding and margin:

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

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

  background: none;
}

When one of these fields gains focus, we highlight them with a light grey, transparent, background. Note that it's important to add the outline property, in order to remove the default focus highlight added by some browsers:

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

Now that our text fields are complete, we need to adjust the display of the single and multiple line text fields to match, since they won't typically look the same using the defaults.

The single-line text field needs some tweaks to render nicely in Internet Explorer. Internet Explorer does not define the height of the fields based on the natural height of the font (which is the behavior of all other browsers). To fix this, we need to add an explicit height to the field, as follows:

input {
    height: 2.5em; /* for IE */
    vertical-align: middle; /* This is optional but it makes legacy IEs look better */
}

<textarea> elements default to being rendered as a block element. The two important things here are the resize and overflow properties. Because our design is a fixed-size design, we will use the resize property to prevent users from resizing our multi-line text field. The overflow property is used to make the field render more consistently across browsers. Some browsers default to the value auto, while some default to the value scroll. In our case, it's better to be sure every one will use auto:

textarea {
  display : block;

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

  resize  : none;
  overflow: auto;
}

The <button> element is really convenient with CSS; you can do whatever you want, even using pseudo-elements:

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;
}

And voila!

Note: If your example does not work quite like you expected and you want to check it against our version, you can find it on GitHub — see it running live (also see the source code).

Conclusion

As you can see, as long as we want to build forms with just text fields and buttons, it's easy to style them using CSS. If you want to know more of the little CSS tricks that can make your life easier when working with form widgets, take a look at the form part of the normalize.css project.

In the next article, we will see how to handle form widgets which fall in the "bad" and "ugly" categories.

文档标签和贡献者

 此页面的贡献者: lovedebug, yydzxz, lucoo01
 最后编辑者: lovedebug,