精通 CSS - 高级 Web 标准解决方案 7. 对表单和数据表格应用样式
本章主要讲了两个标签 <table>
(表格)和 <fieldset>
(表单)。
不过这两个元素在实际使用中已经越来越少见了。
7.1 对数据表格应用样式
7.1.1 表格特有的元素
- summary 类似于图像的 alt 属性
- caption 表格的标题
- thead、tbody、tfoot 表格逻辑部分
- col、colgroup 对表格列定义或分组(支持的浏览器并不多)
7.1.2 数据表格标记
<table class="cal" summary="A calendar style data picker">
<caption>
<a href="#" rel="prev"><</a> May 2019 <a href="#" rel="next">></a>
</caption>
<colgroup>
<col id="sun" />
<col id="mon" />
<col id="tue" />
<col id="wed" />
<col id="thur" />
<col id="fri" />
<col id="sat" />
</colgroup>
<thead>
<tr>
<th scope="col">Sun</th>
<th scope="col">Mon</th>
<th scope="col">Tue</th>
<th scope="col">Wed</th>
<th scope="col">Tur</th>
<th scope="col">Fri</th>
<th scope="col">Sat</th>
</tr>
</thead>
<tbody>
<tr>
<td class="null">28</td>
<td class="null">29</td>
<td class="null">30</td>
<td><a href="#">1</a></td>
<td><a href="#">2</a></td>
<td><a href="#">3</a></td>
<td><a href="#">4</a></td>
</tr>
<!-- ... -->
<tr>
<td><a href="#">26</a></td>
<td><a href="#">27</a></td>
<td><a class="selected">28</a></td>
<td><a href="#">29</a></td>
<td><a href="#">30</a></td>
<td><a href="#">31</a></td>
<td class="null">1</td>
</tr>
</tbody>
</table>
7.1.3 对表格应用样式
CSS 规范有两个表格边盒模型:单独的和叠加的。
单独模型中,在各个单元格周围有边框;
叠加模型中,单元格共享边框。
大多数浏览器默认采用单独模型。
使用 border-collapse
属性控制边盒模型。该属性 可能的值:
- separate:默认值,叠加模型
- collapse:单独模型
- inherit:从父元素继承
table.cal {
border-collapse: separate;
border-spacing: 0;
text-align: center;
color: #333;
}
.cal th, .cal td {
margin: 0;
padding: 0;
}
7.1.4 添加视觉样式
/* 设置表格标题样式 */
.cal caption {
font-size: 1.25em;
padding-top: 0.692em;
padding-bottom: 0.692em;
background-color: #d4dde6;
}
.cal caption [rel="prev"] {
float: left;
margin-left: 0.2em;
}
.cal caption [rel="next"] {
float: right;
margin-right: 0.2em;
}
.cal caption a:link,
.cal caption a:visited {
text-decoration: none;
color: #333;
padding: 0.2em;
}
.cal caption a:hover,
.cal caption a:active,
.cal caption a:focus {
background-color: #6d8ab7;
}
/* 设置行标题样式 */
.cal thead th {
background-color: #d4dde6;
border-bottom: 1px solid #a9bacb;
font-size: 0.875em;
}
/* 设置表格体样式 */
.cal tbody {
color: #a4a4a4;
text-shadow: 1px 1px 1px white;
background-color: #d0d9e2;
}
/* 设置单元格样式 */
.cal tbody td {
border-top: 1px solid #e0e0e1;
border-right: 1px solid #9f9fa1;
border-bottom: 1px solid #acacad;
border-left: 1px solid #dfdfe0;
}
/* 设置链接样式 */
.cal tbody a {
display: block;
text-decoration: none;
color: #333;
background-color: #c0c8d2;
font-weight: bold;
padding: 0.385em 0.692em 0.308em 0.692em;
}
/* 设置鼠标悬停状态 */
.cal tbody a:hover,
.cal tbody a:focus,
.cal tbody a:active,
.cal tbody .selected a:link,
.cal tbody .selected a:visited,
.cal tbody .selected a:hover,
.cal tbody .selected a:focus,
.cal tbody .selected a:active {
background-color: #6d8ab7;
color: white;
text-shadow: 1px 1px 2px #22456b;
}
.cal tbody td:hover,
.cal tbody td.selected {
border-top: 1px solid #2a3647;
border-right: 1px solid #465977;
border-bottom: 1px solid #576e92;
border-left: 1px solid #466080;
}
7.2 简单的表单布局
7.2.1 有用的表单元素
fieldset
用来对相关的信息块进行分组。
使用 legend
元素添加标题。
label
标签元素常用来关联表单控件。
隐式关联
<label>email <input name="email" type="text" /></label>
显示关联
<label for="email">email</label>
<input name="email" id="email" type="text" />
在表单输入控件和标签之间创建关联需要 id 属性;而将表单数据发送回服务器需要 name 属性。
7.2.2 基本布局
没有样式的表单:
<fieldset>
<legend>Your Contact Details</legend>
<div>
<label for="author">Name:<em class="required">(Required)</em></label>
<input name="author" id="author" type="text" />
</div>
<div>
<label for="email">Email Address:</label>
<input name="email" id="email" type="text" />
</div>
<div>
<label for="url">Web Address:</label>
<input name="url" id="url" type="text" />
</div>
</fieldset>
设置表单样式:
fieldset {
margin: 1em 0;
padding: 1em;
border: 1px solid #ccc;
background: #f8f8f8;
}
legend {
font-weight: bold;
}
label {
/* 将标签设置为 block 会产生边框,并迫使输入框转到下一行 */
display: block;
cursor: pointer;
}
input {
width: 20em;
}
7.2.3 其它元素
文本区域 textarea
<fieldset>
<legend>Comments</legend>
<div>
<label for="text">Message:</label>
<textarea name="text" id="text"></textarea>
</div>
</fieldset>
textarea {
width: 100%;
height: 10em;
}
单选按钮 & 复选框 通常需要把标签放在元素右边。
<fieldset id="remember-me">
<legend>Remember Me</legend>
<div>
<label for="remember-yes"><input id="remember-yes" class="radio" name="remember" typee="radio" value="yes" />Yes</label>
</div>
<div>
<label for="remember-no"><input id="remember-no" class="radio" name="remember" typee="radio" value="no" />No</label>
</div>
</fieldset>
input.radio, input.checkbox, input.submit {
width: auto;
}
#remember-me .radio {
margin-right: 1em;
}
必填域
许多表单包含必须填写的域。可以在这些必填域旁边放上有样式的文本或星号。
<fieldset>
<legend>Your Contact Details</legend>
<div>
<label for="author">Name:<em class="required">(Required)</em></label>
<input name="author" id="author" type="text" />
</div>
</fieldset>
.required {
font-size: 0.75em;
color: #760000;
}
7.3 复杂的表单布局
减少使用的垂直空间,将标签和表单元素水平布置。
label {
float: left;
width: 10em;
cursor: pointer;
}
/* 清理 div 容器,避免影响下一组标签 */
form div {
clear: left;
}
7.3.1 可访问的数据输入元素
有时候我们不希望每个元素都显示标签,但又希望代码中有标签可供屏幕阅读器(为视觉有障碍的人设计的阅读屏幕的工具,该工具会自动忽略隐藏的元素。)访问。
<div>
<label for="dateOfBirth">Date Of Birth:</label>
<input name="dateOfBirth" id="dateOfBirth" type="text" />
<label id="monthOfBirthLabel" for="monthOfBirht">Month of Birth:</label>
<select name="monthOfBirht" id="monthOfBirth">
<option value="1">January</option>
<option value="2">February</option>
<option value="3">March</option>
<!-- ... -->
</select>
<label for="yearOfBirth">Year Of Birth:</label>
<input name="yearOfBirth" id="yearOfBirth" type="text" />
</div>
#monthOfBirthLabel, #yearOfBirthLabel {
/* 隐藏标签(之所不用 display: none 是因为这样会导致屏幕阅读器访问不到它) */
text-indent: -1000em;
/* 不设置为 inline-block 的话 text-indent 貌似不起作用 */
display: inline-block;
/* 为了防止标签影响布局,需要将标签的宽度设置为 0 */
width: 0;
}
/* 设置每个空间的尺寸和外边距 */
input#dateOfBirth {
width: 3em;
margin-right: 0.5em;
}
input#monthOfBirth {
width: 10em;
margin-right: 0.5em;
}
input#yearOfBirth {
width: 5em;
}
7.3.2 多列复选框
使用 fieldset 实现标签组的效果。由于 legend 元素定位定位在每个浏览器上可能不一样,所以改用 h2 元素。
<fieldset id="favoriteColor">
<h2>Favorite Color:</h2>
<div class="col">
<div>
<label><input class="checkbox" id="red" type="checkbox" value="red" />red</label>
<label><input class="checkbox" id="yellow" type="checkbox" value="yellow" />yellow</label>
<label><input class="checkbox" id="pink" type="checkbox" value="pink" />pink</label>
<label><input class="checkbox" id="green" type="checkbox" value="green" />green</label>
</div>
</div>
<div class="col">
<div>
<label><input class="checkbox" id="orange" type="checkbox" value="orange" />orange</label>
<label><input class="checkbox" id="purple" type="checkbox" value="purple" />purple</label>
<label><input class="checkbox" id="blue" type="checkbox" value="blue" />blue</label>
<label><input class="checkbox" id="other" type="checkbox" value="other" />other</label>
</div>
</div>
</fieldset>
<!-- 覆盖 fieldset 的样式 -->
fieldset#favoriteColor {
margin: 0;
padding: 0;
border: none;
background: transparent;
}
/* 将标题用作标签,将其设置为向左浮动 */
fieldset#favoriteColor h2 {
width: 10em;
float: left;
font-size: 1em;
font-weight: normal;
}
/* 将列也设置为向左浮动,实现列的效果 */
fieldset#favoriteColor .col {
width: 8em;
float: left;
clear: none;
}
/* 清除标签的浮动 */
fieldset#favoriteColor label {
float: none;
display: block;
}
提交按钮
最常用的是 type
为 submit 的 input
元素。但可以使用 button
元素替代 input
元素。
可以在 button
元素中放入图片,使图片成为按钮。
<div>
<button type="submit">
<img src="/img/button.png" alt="Like It" />
</button>
</div>
关闭 button
的默认样式。
button {
border: none;
background: none;
cursor: pointer;
}
OS X 等系统为了操作系统样式的统一性,禁止修改 input
按钮的样式,但是,button
元素不受限制。
button.book {
width: 200px;
height: 50px;
border: 1px solid #989898;
/** 设置圆角 **/
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
border-radius: 6px;
/** 设置背景 **/
background: url(/img/button-bg.png) #c5e063 bottom left repeat-x;
/** 设置阴影 **/
-moz-box-shadow: 2px 2px 2px #ccc;
-webkit-box-shadow: 2px 2px 2px #ccc;
box-shadow: 2px 2px 2px #ccc;
/** 设置字体 **/
color: #fff;
font-size: 26px;
font-weight: bold;
text-shadow: 1px 1px 1px #666;
}
7.3.3 表单反馈
表单验证的错误消息等
<div>
<label for="email">Email Address:<em class="feedback">Incorrect email address. Please try again.</em></label>
<input name="email" id="email" type="text" />
</div>
将段落的 position 设置为 relative,从而建立一个新的定位上下文。然后对返回 em
进行绝对定位。
div {
clear: left;
position: relative;
}
.feedback {
position: absolute;
left: 30em;
right: 0;
top: 0.5em;
/* 警告字体设置为红色、粗体 */
font-weight: bold;
color: #760000;
/* 左边加一个警告图像 */
padding-left: 18px;
background: url(/img/error.png) no-repeat left top;
}
附 1. 引用
- 《精通 CSS - 高级 Web 标准解决方案(第 2 版)》 - Andy Budd, Simon Collison, Cameron Moll 著;陈剑瓯 译。