网页表单样式
在之前的几篇文章中,我们展示了如何在 HTML 中创建网页表单。现在,我们将展示如何在 CSS 中为它们设置样式。
表单小部件样式方面的挑战
历史
1995 年,HTML 2 规范 引入了表单控件(也称为“表单小部件”或“表单元素”)。但 CSS 直到 1996 年末才发布,而且直到几年后才被大多数浏览器支持;因此,在此期间,浏览器依赖于底层操作系统来渲染表单小部件。
即使有了 CSS,浏览器供应商最初也不愿使表单元素可样式化,因为用户已经习惯了各自浏览器的外观。但情况已经发生了变化,现在表单小部件大多是可样式化的,但也有一些例外。
小部件类型
易于样式化
<form>
<fieldset>
和<legend>
- 单行文本
<input>
(例如类型文本、url、电子邮件),除了<input type="search">
。 - 多行
<textarea>
- 按钮(
<input>
和<button>
两种) <label>
<output>
难以样式化
- 复选框和单选按钮
<input type="search">
文章 高级表单样式 展示了如何对这些进行样式化。
具有内部组件的元素无法仅用 CSS 进行样式化
<input type="color">
- 与日期相关的控件,例如
<input type="datetime-local">
<input type="range">
<input type="file">
- 参与创建下拉小部件的元素,包括
<select>
、<option>
、<optgroup>
和<datalist>
。 <progress>
和<meter>
例如,日期选择器日历和 <select> 上的按钮(单击时显示选项列表)无法仅使用 CSS 进行样式化。
文章 高级表单样式 和 如何构建自定义表单控件 描述了如何对这些进行样式化。
注意: 一些专有的 CSS 伪元素,例如 ::-moz-range-track
,能够对这些内部组件进行样式化,但这些在浏览器之间不一致,因此不太可靠。我们稍后会提到这些。
简单表单小部件的样式
字体和文本
CSS 字体和文本功能可以轻松地与任何小部件一起使用(是的,您可以在表单小部件中使用 @font-face
)。但是,浏览器的行为通常不一致。默认情况下,一些小部件不会从其父元素继承 font-family
和 font-size
。许多浏览器使用系统的默认外观。为了使表单的外观与您内容的其余部分保持一致,您可以将以下规则添加到您的样式表中
button,
input,
select,
textarea {
font-family: inherit;
font-size: 100%;
}
inherit
属性值会导致属性值与父元素属性的计算值匹配;继承父元素的值。
下面的屏幕截图显示了差异。左侧是 <input type="text">
、<input type="date">
、<select>
、<textarea>
、<input type="submit">
和 <button>
在 macOS 上的 Chrome 中的默认渲染,使用平台的默认字体样式。右侧是相同的元素,应用了我们上面的样式规则。
默认值在许多方面有所不同。继承应该将它们的字体更改为父元素的字体系列——在本例中,是父容器的默认衬线字体。它们都这样做了,但有一个奇怪的例外——<input type="submit">
在 Chrome 中没有从父段落继承。相反,它使用 font-family: system-ui
。这是使用 <button>
元素而不是等效输入类型的另一个原因!
关于表单是否应该使用系统默认样式或自定义样式(旨在与您的内容匹配)存在很多争论。这个决定由您作为网站或 Web 应用程序的设计者来决定。
盒子大小
所有文本字段都完全支持与 CSS 盒模型相关的每个属性,例如 width
、height
、padding
、margin
和 border
。但是,如前所述,浏览器在显示这些小部件时依赖于系统默认样式。您需要决定如何将它们与您的内容融合在一起。如果您想保留小部件的原生外观和感觉,那么如果您想赋予它们一致的大小,您将面临一些困难。
这是因为每个小部件都有自己的边框、填充和边距规则。 要使几个不同的窗口小部件具有相同的大小,可以使用 box-sizing
属性以及其他属性的一些一致值
input,
textarea,
select,
button {
width: 150px;
padding: 0;
margin: 0;
box-sizing: border-box;
}
在下面的屏幕截图中,左列显示了 <input type="radio">
、<input type="checkbox">
、<input type="range">
、<input type="text">
、<input type="date">
、<select>
、<textarea>
、<input type="submit">
和 <button>
的默认渲染。另一方面,右列显示了应用了我们上面的规则的相同元素。注意,这使我们能够确保所有元素都占据相同的空间,尽管平台为每种类型的窗口小部件设置了默认规则。
屏幕截图可能无法显示的是,单选按钮和复选框控件仍然看起来一样,但它们在 width
属性提供的 150 像素的水平空间中居中。其他浏览器可能不会将小部件居中,但它们确实会遵守分配的空间。
图例放置
<legend>
元素可以进行样式化,但控制其放置可能有点棘手。默认情况下,它始终位于其 <fieldset>
父元素的顶部边框上方,靠近左上角。要将其放置在其他位置,例如在 fieldset 中的某个位置或靠近左下角,您需要依赖于定位。
以以下示例为例
要以这种方式定位图例,我们使用了以下 CSS(出于简洁起见,删除了其他声明)
fieldset {
position: relative;
}
legend {
position: absolute;
bottom: 0;
right: 0;
}
<fieldset>
也需要定位,以便 <legend>
相对于它定位(否则 <legend>
将相对于 <body>
定位)。
<legend>
元素对于可访问性非常重要——它将被辅助技术作为 fieldset 内每个表单元素的标签的一部分进行朗读——但使用像上面这样的技术是可以的。图例内容仍然会以相同的方式朗读;只是视觉位置发生了变化。
注意: 您也可以使用 transform
属性来帮助您定位 <legend>
。但是,当您使用例如 transform: translateY();
定位它时,它会移动,但在 <fieldset>
边框中留下了难看的间隙,这很难消除。
一个具体的样式示例
让我们看看如何对 HTML 表单进行样式化的具体示例。我们将构建一个外观奇特的“明信片”联系表单;此处查看完成版本.
如果您想按照此示例操作,请制作 postcard-start.html 文件 的本地副本,并按照以下说明操作。
HTML
HTML 只是比我们在 本指南的第一篇文章 中使用的示例稍微复杂一些;它只有一些额外的 ID 和标题。
<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>
将以上代码添加到 HTML 的 body 中。
组织您的资产
这就是乐趣开始的地方!在开始编码之前,我们需要三个额外的资产
- 明信片背景——下载此图像并将其保存到与您的工作 HTML 文件相同的目录中。
- 打字机字体:dafont.com 上的“Mom's Typewriter”字体——将 TTF 文件下载到与上面相同的目录中。
- 手绘字体:dafont.com 上的“Journal”字体——将 TTF 文件下载到与上面相同的目录中。
您的字体需要在开始之前进行更多处理
- 转到 fontsquirrel.com 的 Webfont Generator。
- 使用表单上传您的两个字体文件并生成一个 Web 字体工具包。将工具包下载到您的计算机。
- 解压缩提供的 zip 文件。
- 在解压缩的内容中,您会找到一些字体文件(在撰写本文时,两个
.woff
文件和两个.woff2
文件;它们将来可能会有所不同。)将这些文件复制到名为 fonts 的目录中,与之前相同的目录中。我们使用每个字体的两个不同文件来最大限度地提高浏览器兼容性;有关更多信息,请参阅我们的 Web 字体 文章。
CSS
现在我们可以深入研究示例的 CSS。将下面显示的所有代码块依次添加到 <style>
元素中。
整体布局
首先,我们通过定义 @font-face
规则以及对 <body>
和 <form>
元素设置的所有基本样式来进行准备。如果 fontsquirrel 的输出与我们上面描述的不同,您可以在下载的 Web 字体工具包中的 stylesheet.css
文件中找到正确的 @font-face
块(您需要用它们替换下面的 @font-face
块,并更新到字体文件的路径)
@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/momot___-webfont.woff2") format("woff2"),
url("fonts/momot___-webfont.woff") format("woff");
font-weight: normal;
font-style: normal;
}
body {
font: 1.3rem sans-serif;
padding: 0.5em;
margin: 0;
background: #222;
}
form {
position: relative;
width: 740px;
height: 498px;
margin: 0 auto;
padding: 1em;
box-sizing: border-box;
background: #fff url(background.jpg);
/* we create our grid */
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: 10em 1em 1em 1em;
}
注意,我们使用了一些 CSS 网格 和 Flexbox 来布局表单。使用它,我们可以轻松地定位我们的元素,包括标题和所有表单元素
h1 {
font:
1em "typewriter",
monospace;
align-self: end;
}
#message {
grid-row: 1 / 5;
}
#from,
#reply {
display: flex;
}
标签和控件
现在我们可以开始处理表单元素本身。首先,让我们确保 <label>
使用正确的字体。
label {
font:
0.8em "typewriter",
sans-serif;
}
文本字段需要一些通用的规则。换句话说,我们删除它们的 borders
和 backgrounds
,并重新定义它们的 padding
和 margin
input,
textarea {
font:
1.4em/1.5em "handwriting",
cursive,
sans-serif;
border: none;
padding: 0 10px;
margin: 0;
width: 80%;
background: none;
}
当这些字段中的一个获得焦点时,我们使用浅灰色透明背景突出显示它们(对于可用性和键盘可访问性,始终拥有焦点样式非常重要)
input:focus,
textarea:focus {
background: rgb(0 0 0 / 10%);
border-radius: 5px;
}
现在我们的文本字段已经完成,我们需要调整单行和多行文本字段的显示以匹配,因为它们使用默认值通常看起来不一样。
调整文本区域
<textarea>
元素默认渲染为内联块元素。这里有两个重要的属性:resize
和 overflow
。虽然我们的设计是固定大小的,我们可以使用 resize
属性来阻止用户调整多行文本字段的大小,但最好不要阻止用户调整 textarea
的大小,如果他们愿意的话。使用 overflow
属性可以使字段在不同浏览器中的渲染更加一致。一些浏览器默认值为 auto
,而另一些则默认值为 scroll
。在我们的例子中,最好确保每个人都使用 auto
textarea {
display: block;
padding: 10px;
margin: 10px 0 0 -10px;
width: 100%;
height: 90%;
border-right: 1px solid;
/* resize : none; */
overflow: auto;
}
设置提交按钮样式
<button>
元素用 CSS 设置样式非常方便,您可以随意操作,甚至可以使用 伪元素
button {
padding: 5px;
font: bold 0.6em sans-serif;
border: 2px solid #333;
border-radius: 5px;
background: none;
cursor: pointer;
transform: rotate(-1.5deg);
}
button:after {
content: " >>>";
}
button:hover,
button:focus {
background: #000;
color: #fff;
}
最终结果
测试您的技能
您已阅读完本文,但您能记住最重要的信息吗?在您继续之前,您可以进行一些进一步的测试,以验证您是否保留了这些信息 - 请查看 测试您的技能:样式基础。
总结
如您所见,只要我们想使用文本字段和按钮构建表单,就可以轻松地使用 CSS 对其进行样式设置。在 下一篇文章 中,我们将看到如何处理属于“糟糕”和“丑陋”类别的表单小部件。