好久没更新了
This commit is contained in:
@@ -12,7 +12,7 @@ html(HyperText Markup Language --超文本标记语言),不是一个编
|
||||
|
||||
开始之前 需要新建一个 后缀名为.html 的文件,我们后面所说的所有操作,都是在html 文件中进行的
|
||||
|
||||
可以使用的编辑器有很多: 记事本,editplus, notepad++, **vscode** ....这里推荐vscode
|
||||
可以使用的编辑器有很多: 记事本,editplus, notepad++, hbuilder **vscode** ....这里推荐vscode
|
||||
|
||||
### html 基本结构
|
||||
|
||||
@@ -30,12 +30,16 @@ html(HyperText Markup Language --超文本标记语言),不是一个编
|
||||
|
||||
> 在解读上面的代码之前,我们先来看这些由<(左尖括号), 内容 , >(右尖括号) 组成的内容,这些内容叫做标签(tag), 在html中用<> 把他们包裹起来是为了与其他纯文本内容进行区分
|
||||
|
||||
> <!DOCTYPE html> 是Document Type Declaration 的简称,用来声明文档,也就是告诉浏览器当前使用的是哪种HTML
|
||||
> <html></html> 表示页面编写的都是HTML代码,必须成对出现,除了文档生命之外的所有代码都必须写在<html></html>中间
|
||||
> <head></head> 表示页面的头部,页面的标题(title标签),meta元信息定义,文档样式表和脚本等信息 一般写在head 中间
|
||||
> <body></body> 表示页面的身体 页面内容需要写在 body 标签内 --
|
||||
html 元素和标签的区别:
|
||||
> HTML标签是超文本标记语言的最基本单位,而HTML 元素指的是从开始标签(start tag)到结束标签(end tag)的所有代码。
|
||||
|
||||
|
||||
> \<!DOCTYPE html> 是Document Type Declaration 的简称,用来声明文档,也就是告诉浏览器当前使用的是哪种HTML
|
||||
> \<html>\</html> 表示页面编写的都是HTML代码,必须成对出现,除了文档生命之外的所有代码都必须写在\<html>\</html>中间
|
||||
> \<head>\</head> 表示页面的头部,页面的标题(title标签),meta元信息定义,文档样式表和脚本等信息 一般写在head 中间
|
||||
> \<body>\</body> 表示页面的身体 页面内容需要写在 body 标签内 --
|
||||
>
|
||||
> <meta charset="utf-8" /> 设置文档使用utf-8编码集
|
||||
> \<meta charset="utf-8" /> 设置文档使用utf-8编码集
|
||||
|
||||
### 写第一个网页 --hello world
|
||||
|
||||
@@ -73,13 +77,10 @@ html(HyperText Markup Language --超文本标记语言),不是一个编
|
||||
|
||||

|
||||
|
||||
元素分类:
|
||||
|
||||
分类方式:
|
||||
|
||||
标签分类:
|
||||
- 有无闭合标签
|
||||
- 单标签
|
||||
- 没有闭合标签,单标签书写形式以 / 结尾 如:<img /> <input /> ...
|
||||
- 没有闭合标签,单标签书写形式以 / 结尾 如:\<img /> \<input /> ...
|
||||
|
||||
- 双标签
|
||||
|
||||
@@ -92,8 +93,7 @@ html(HyperText Markup Language --超文本标记语言),不是一个编
|
||||
<span>这是文本标签 </span>
|
||||
```
|
||||
|
||||
|
||||
|
||||
元素分类:
|
||||
- 块级元素和内联元素
|
||||
|
||||
- 块级标签:在页面中以块的形式展现——相对于其前面的内容他会出现在新的一行,其后面的内容也会被挤到下一行展现。一个块级元素不会被嵌套进内联元素中,但可以嵌套在其他块级元素。
|
||||
@@ -137,7 +137,6 @@ html(HyperText Markup Language --超文本标记语言),不是一个编
|
||||
一个属性需要包含如下内容:
|
||||
|
||||
> 1.一个空格,位于元素名称和属性名称之间
|
||||
>
|
||||
> 2. 属性名称,后面跟着一个等于号(=)
|
||||
> 3. 一个属性值,用“” 包裹
|
||||
|
||||
@@ -205,7 +204,7 @@ html(HyperText Markup Language --超文本标记语言),不是一个编
|
||||
<a href="www.baidu.com'>baidu</a>
|
||||
```
|
||||
|
||||
上面这种写法是错误的!!!!!
|
||||
<p style="color:red">上面这种写法是<b>错误</b>的!!!!!</p>
|
||||
|
||||
|
||||
|
||||
@@ -217,20 +216,20 @@ html(HyperText Markup Language --超文本标记语言),不是一个编
|
||||
|
||||
在html代码中,我们让每一个嵌套的元素以两个空格缩进,
|
||||
|
||||
```
|
||||
原意字符 等价字符引用
|
||||
< <
|
||||
> >
|
||||
'' "
|
||||
' &apos
|
||||
& &
|
||||
```
|
||||
| 原意字符 | 等价字符引用 |
|
||||
|---|---|
|
||||
| (空格)| |
|
||||
|<|<|
|
||||
|>|>|
|
||||
|''|"|
|
||||
|'|&apos|
|
||||
|&|&|
|
||||
|
||||
|
||||
|
||||
### html 注释
|
||||
|
||||
<!-- 注释内容 -->
|
||||
\<!-- 注释内容 -->
|
||||
|
||||
```
|
||||
<p>我在注释外!</p>
|
||||
@@ -238,3 +237,32 @@ html(HyperText Markup Language --超文本标记语言),不是一个编
|
||||
<!-- <p>我在注释内!</p> -->
|
||||
```
|
||||
|
||||
阅读上面的文档,完成以下练习:
|
||||
|
||||
1. 写出html基本结构
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
2. 写出至少5个单标签和至少8个双标签
|
||||
|
||||
|
||||
|
||||
|
||||
3. 新建一个html文件,页面上展示hello world
|
||||
world加粗
|
||||
完成内网通发截图
|
||||
|
||||
4. 新建一个html文件,页面上展示一篇文章的题目,作者,发布日期,正文内容,阅读量,点赞量,评论量
|
||||
其中,标题单独一行,下面放作者,发布日期,下面放正文内容,最下面放阅读量,点赞量,评论量
|
||||
完成内网通发截图
|
||||
5. 在任务4的基础上 在正文之前插入一个图片作为文章封面
|
||||
完成内网通发截图
|
||||
|
||||
6. 在任务5的基础上,从最上面添加一个输入框和搜索按钮,点击搜索,将输入框中输入的值带入www.baidu.com的地址栏中
|
||||
完成内网通发截图
|
||||
|
||||
7. 用自己的方式调整任务4的html页面的样式
|
||||
完成内网通发截图
|
||||
134
htmlpress/biaoge.md
Normal file
134
htmlpress/biaoge.md
Normal file
@@ -0,0 +1,134 @@
|
||||
# 表格(table)
|
||||
|
||||
表格:由行和列组成的结构化数据集(表格数据)
|
||||
|
||||
### 使用场景
|
||||
|
||||
html表格应用于展示表格数据,而不是用来实现网页布局
|
||||
|
||||
用表格实现网页布局出现的问题:
|
||||
|
||||
1. 表格布局减少了视觉受损的用户的可访问性
|
||||
2. 表格会产生更多的标签,使代码变得更难于编写,维护,调试
|
||||
3. 表格不能自动响应 正确的布局容器(如div ) 他们的默认宽度是父元素的100% 但表格的默认大小是根据其内容而定的。因此 如果要做移动端适配,就需要采取额外的措施来改变表格的样式
|
||||
|
||||
### 新建一个表格
|
||||
|
||||
1. 每个表格的内容都被包含在<table></table> 中 而且这些内容需要写在html结构的body部分
|
||||
2. 在表格中,最小的内容容器是单元格,是通过(td)创建的 这是一列
|
||||
3. 如果想换行,需要把位于同一行的内容包含在 一个tr 标签中 即用<tr></tr> 定义一行
|
||||
|
||||
示例:
|
||||
|
||||
```
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<table border="1">
|
||||
<tr>
|
||||
<td>姓名</td>
|
||||
<td>年龄</td>
|
||||
<td>性别</td>
|
||||
<td>班级</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>asd</td>
|
||||
<td>14</td>
|
||||
<td>男</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lily</td>
|
||||
<td>12</td>
|
||||
<td>女</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>asd</td>
|
||||
<td>14</td>
|
||||
<td>男</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lily</td>
|
||||
<td>12</td>
|
||||
<td>女</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
效果如下:
|
||||
|
||||

|
||||
|
||||
上面的代码中出现的 <table border="1"></table> 中的border 用于给表格加上边框
|
||||
|
||||
|
||||
|
||||
#### 表格表头(th)
|
||||
|
||||
table包裹的 th标签会有加粗的效果 看起来是表格的表头
|
||||
|
||||
把上面表格的顶部四个单元格做成表头效果:
|
||||
|
||||
```
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<table border="1">
|
||||
<tr>
|
||||
<th>姓名</th>
|
||||
<th>年龄</th>
|
||||
<th>性别</th>
|
||||
<th>班级</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>asd</td>
|
||||
<td>14</td>
|
||||
<td>男</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lily</td>
|
||||
<td>12</td>
|
||||
<td>女</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>asd</td>
|
||||
<td>14</td>
|
||||
<td>男</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lily</td>
|
||||
<td>12</td>
|
||||
<td>女</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### 允许单元格跨行或列
|
||||
|
||||
|
||||
|
||||
93
htmlpress/html标签详解.md
Normal file
93
htmlpress/html标签详解.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# html 主要标签
|
||||
## 文字相关的标签
|
||||
|
||||
### 标题和段落
|
||||
**标题标签(hn)**
|
||||
* h1
|
||||
* h2
|
||||
* h3
|
||||
* h4
|
||||
* h5
|
||||
* h6
|
||||
> h1~h6标用来声明标题,h1定义最大的标题,h6定义最小的标题,注意不要用来改变同一行的文字大小,这种样式需求应使用层叠样式表(css)实现
|
||||
|
||||
实例:
|
||||
<h1>这是h1</h1>
|
||||
<h2>这是h2</h2>
|
||||
<h3>这是h3</h3>
|
||||
<h4>这是h4</h4>
|
||||
<h5>这是h5</h5>
|
||||
<h6>这是h6</h6>
|
||||
|
||||
**段落标签**
|
||||
* p
|
||||
> 在html中,每个段落是通过<p> 标签进行定义的。
|
||||
|
||||
实例:
|
||||
|
||||
```
|
||||
<p>我是一个段落标签</p>
|
||||
```
|
||||
|
||||
阅读下面的代码体会合理的结构层次
|
||||
效果:
|
||||
|
||||
<h1>三国演义</h1>
|
||||
|
||||
<p>罗贯中</p>
|
||||
|
||||
<h2>第一回 宴桃园豪杰三结义 斩黄巾英雄首立功</h2>
|
||||
|
||||
<p>话说天下大势,分久必合,合久必分。周末七国分争,并入于秦。及秦灭之后,楚、汉分争,又并入于汉……</p>
|
||||
|
||||
<h2>第二回 张翼德怒鞭督邮 何国舅谋诛宦竖</h2>
|
||||
|
||||
<p>且说董卓字仲颖,陇西临洮人也,官拜河东太守,自来骄傲。当日怠慢了玄德,张飞性发,便欲杀之……</p>
|
||||
|
||||
<h3>却说张飞</h3>
|
||||
|
||||
<p>却说张飞饮了数杯闷酒,乘马从馆驿前过,见五六十个老人,皆在门前痛哭。飞问其故,众老人答曰:“督邮逼勒县吏,欲害刘公;我等皆来苦告,不得放入,反遭把门人赶打!”……</p>
|
||||
```
|
||||
<h1>三国演义</h1>
|
||||
|
||||
<p>罗贯中</p>
|
||||
|
||||
<h2>第一回 宴桃园豪杰三结义 斩黄巾英雄首立功</h2>
|
||||
|
||||
<p>话说天下大势,分久必合,合久必分。周末七国分争,并入于秦。及秦灭之后,楚、汉分争,又并入于汉……</p>
|
||||
|
||||
<h2>第二回 张翼德怒鞭督邮 何国舅谋诛宦竖</h2>
|
||||
|
||||
<p>且说董卓字仲颖,陇西临洮人也,官拜河东太守,自来骄傲。当日怠慢了玄德,张飞性发,便欲杀之……</p>
|
||||
|
||||
<h3>却说张飞</h3>
|
||||
|
||||
<p>却说张飞饮了数杯闷酒,乘马从馆驿前过,见五六十个老人,皆在门前痛哭。飞问其故,众老人答曰:“督邮逼勒县吏,欲害刘公;我等皆来苦告,不得放入,反遭把门人赶打!”……</p>
|
||||
```
|
||||
|
||||
> 结构层次原则:
|
||||
> 1.您应该最好只对每个页面使用一次\<h1> — 这是顶级标题,所有其他标题位于层次结构中的下方。
|
||||
>2.请确保在层次结构中以正确的顺序使用标题。不要使用\<h3>来表示副标题,后面跟\<h2>来表示副副标题 - 这是没有意义的,会导致奇怪的结果。
|
||||
>3. 在可用的六个标题级别中,您应该只在每页使用不超过三个,除非您认为有必要使用更多。具有许多级别的文档(即,较深的标题层次结构)变得难以操作并且难以导航。在这种情况下,如果可能,建议将内容分散在多个页面上。
|
||||
|
||||
## 列表 list
|
||||
### 无序列表 ul-li
|
||||
<ul>
|
||||
<li>香菱</li>
|
||||
<li>皇女</li>
|
||||
<li>旅行者</li>
|
||||
<li>派蒙</li>
|
||||
</ul>
|
||||
|
||||
```
|
||||
<ul>
|
||||
<li>香菱</li>
|
||||
<li>皇女</li>
|
||||
<li>旅行者</li>
|
||||
<li>派蒙</li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
阅读上面的文档,完成以下练习
|
||||
|
||||
1. 新建一个html页面,
|
||||
234
htmlpress/表单.md
Normal file
234
htmlpress/表单.md
Normal file
@@ -0,0 +1,234 @@
|
||||
创建我的第一个表单
|
||||
|
||||
* HTML表单是什么?
|
||||
* 设计表单
|
||||
* 主动学习:使用HTML实现我们的表单
|
||||
* 基本表单样式
|
||||
* 向您的web服务器发送表单数据
|
||||
|
||||
本文提供了您第一次创建HTML表单的经验,包括设计一个简单表单,使用正确的HTML元素实现它,通过CSS添加一些非常简单的样式,以及如何将数据发送到服务器。
|
||||
预备知识:
|
||||
|
||||
基本计算机素养和对HTML的基本理解。
|
||||
目标: 为了熟悉HTML表单是什么,它们被用来做什么,如何设计它们,以及简单情况下需要的基本HTML元素。
|
||||
|
||||
HTML表单是什么?
|
||||
HTML表单是用户和web站点或应用程序之间交互的主要内容之一。它们允许用户将数据发送到web站点。大多数情况下,数据被发送到web服务器,但是web页面也可以自己拦截它并使用它。
|
||||
|
||||
HTML表单是由一个或多个小部件组成的。这些小部件可以是文本字段(单行或多行)、选择框、按钮、复选框或单选按钮。大多数情况下,这些小部件与描述其目的的标签配对——正确实现的标签能够清楚地指示视力正常的用户和盲人用户输入表单所需的内容。
|
||||
|
||||
HTML表单和常规HTML文档的主要区别在于,大多数情况下,表单收集的数据被发送到web服务器。在这种情况下,您需要设置一个web服务器来接收和处理数据。如何设置这样的服务器超出了本文的范围,但是如果您想了解更多,请参阅模块后面的发送表单数据。
|
||||
设计表单
|
||||
|
||||
在开始编写代码之前,最好先退一步,花点时间考虑一下您的表单。设计一个快速的模型将帮助您定义您想要询问用户的正确的数据集。从用户体验(UX)的角度来看,要记住:表单越大,失去用户的风险就越大。保持简单,保持专注:只要求必要的数据。在构建站点或应用程序时,设计表单是非常重要的一步。这超出了本文的范围,涵盖了表单的用户体验,但是如果您想深入了解这个主题,您应该阅读下面的文章:
|
||||
|
||||
杂志<Smashing Magazine>中有很好的关于表单用户体验的文章,或许其中最重要的应该是他们的Extensive Guide To Web Form Usability.
|
||||
UXMatters 也是一个非常有思想的资源,从基本的最佳实践到复杂的问题如多页表单,都有很好的建议。
|
||||
|
||||
在本文中,我们将构建一个简单的联系人表单。让我们做一个粗略的草图。
|
||||
|
||||
The form to build, roughly sketch
|
||||
|
||||
我们的表单将包含三个文本字段和一个按钮。我们向用户询问他们的姓名、电子邮件和他们想要发送的信息。点击这个按钮将把他们的数据发送到一个web服务器。
|
||||
主动学习:使用HTML实现我们的表单
|
||||
|
||||
好了,现在我们准备进入HTML代码并对表单进行编码。为了构建我们的联系人表单,我们将使用以下HTML元素:<form>, <label>, <input>, <textarea>, and <button>.
|
||||
|
||||
在进一步讨论之前,先创建一个简单HTML模板的本地副本—您将在这里输入您的表单HTML。
|
||||
<form> 元素
|
||||
|
||||
所有HTML表单都以一个<form>元素开始:
|
||||
|
||||
<form action="/my-handling-form-page" method="post">
|
||||
|
||||
</form>
|
||||
|
||||
这个元素正式定义了一个表单。就像<div>元素或<p>元素,它是一个容器元素,但它也支持一些特定的属性来配置表单的行为方式。它的所有属性都是可选的,但实践中最好至少要设置action属性和method属性。
|
||||
|
||||
action 属性定义了在提交表单时,应该把所收集的数据送给谁(/那个模块)(URL)去处理。.
|
||||
method 属性定义了发送数据的HTTP方法(它可以是“get”或“post”).
|
||||
|
||||
注意:如果您想深入了解这些属性是如何工作的,那么将在发送表单数据文章中详细说明。
|
||||
|
||||
现在,将上面的<form> 元素添加到您的HTML主体中
|
||||
<label>, <input> 和 <textarea> 元素
|
||||
|
||||
我们的联系人表单非常简单,包含三个文本字段,每个字段都有一个标签。该名称的输入字段将是一个基本的单行文本字段,电子邮件的输入字段将是一个只接受电子邮件地址的单行文本字段,而消息的输入字段将是一个基本的多行文本字段。
|
||||
|
||||
就HTML代码而言,我们需要如下的东西来实现这些表单小部件:
|
||||
|
||||
<form action="/my-handling-form-page" method="post">
|
||||
<div>
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" id="name">
|
||||
</div>
|
||||
<div>
|
||||
<label for="mail">E-mail:</label>
|
||||
<input type="email" id="mail">
|
||||
</div>
|
||||
<div>
|
||||
<label for="msg">Message:</label>
|
||||
<textarea id="msg"></textarea>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
更新您的表单代码,使其看起来像上面的代码。
|
||||
|
||||
使用\<div> 元素可以使我们更加方便地构造我们自己的代码,并且更容易样式化(参见本文后面的文章)。注意在所有\<label>元素上使用for属性;它是将标签链接到表单小部件的一种正规方式。这个属性引用对应的小部件的id。这样做有一些好处。最明显的一个好处是允许用户单击标签以激活相应的小部件。如果您想更好地理解这个属性的其他好处,您可以找到如何构造HTML表单的详细信息。
|
||||
|
||||
在 \<input>元素中,最重要的属性是type 属性。这个属性非常重要,因为它定义了\<input>属性的行为方式。它可以从根本上改变元素,所以要注意它。稍后您将在原生表单控件文章中找到更多关于此的内容。
|
||||
|
||||
在我们的简单示例中,我们使用值 text 作为第一个输入——这个属性的默认值。它表示一个基本的单行文本字段,接受任何类型的文本输入。
|
||||
对于第二个输入,我们使用值email,它定义了一个只接受格式正确的电子邮件地址的单行文本字段。这会将一个基本的文本字段转换为一种“智能”字段,该字段将对用户输入的数据进行一些检查。在稍后的表单数据验证文章中,您将了解到更多关于表单验证的信息。
|
||||
|
||||
最后但同样重要的是,要注意\<input> 和\<textarea>\</textarea>的语法。这是HTML的一个奇怪之处。 \<input> 标签是一个空元素,这意味着它不需要关闭标签。相反, \<textarea>不是一个空元素,因此必须使用适当的结束标记来关闭它。这对HTML表单的特定特性有影响:定义默认值的方式。要定义\<input>的默认值,你必须使用value 属性,如下所示:
|
||||
|
||||
```
|
||||
<input type="text" value="by default this element is filled with this text" />
|
||||
|
||||
```
|
||||
|
||||
相反,如果您想定义\<textarea>的默认值,您只需在\<textarea>元素的开始和结束标记之间放置默认值,就像这样:
|
||||
|
||||
<textarea>by default this element is filled with this text</textarea>
|
||||
|
||||
\<button> 元素
|
||||
|
||||
我们的表格已经快准备好了,我们只需要再添加一个按钮,让用户在填写完表单后发送他们的数据。这是通过使用 \<button> 元素完成的。在 \</form>这个结束标签上方添加以下内容:
|
||||
|
||||
```
|
||||
|
||||
<div class="button">
|
||||
<button type="submit">Send your message</button>
|
||||
</div>
|
||||
|
||||
```
|
||||
<div class="button">
|
||||
<button type="submit">Send your message</button>
|
||||
</div>
|
||||
|
||||
您会看到\<button>元素也接受一个 type属性,它接受submit, reset或者 button 三个值中的任一个。
|
||||
|
||||
单击 type 属性定义为 submit 值(也是默认值)的按钮会发送表单的数据到<form>元素的action 属性所定义的网页。
|
||||
单击 type 属性定义为 reset 值的按钮 将所有表单小部件重新设置为它们的默认值。从用户体验的角度来看,这被认为是一种糟糕的做法。
|
||||
单击 type 属性定义为 button 值的按钮……不会发生任何事!这听起来很傻,但是用JavaScript构建定制按钮非常有用。
|
||||
|
||||
注意:您还可以使用相应类型的 <input>元素来生成一个按钮,如 <input type="submit">。<button>元素的主要优点是, <input>元素只允许纯文本作为其标签,而<button>元素允许完整的HTML内容,允许更复杂、更有创意的按钮文本。
|
||||
基本表单样式
|
||||
|
||||
现在您已经完成了表单的HTML代码,尝试保存它并在浏览器中查看它。
|
||||
现在,你会看到它看起来很丑。
|
||||
|
||||
注意: 如果你怀疑你的HTML代码不对,试着把它和我们完成的例子进行比较 —— first-form.html (你也可以观看预览版)。
|
||||
|
||||
如何排布好表单是公认的难点。这超出了本文的讨论范围,所以现在我们只需要让您添加一些CSS来让它看起来很好。
|
||||
|
||||
首先,在您的HTML头部中添加一个 <style>元素。应该是这样的:
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
||||
在样式标签中,添加如下的CSS,如下所示:
|
||||
|
||||
form {
|
||||
/* 居中表单 */
|
||||
margin: 0 auto;
|
||||
width: 400px;
|
||||
/* 显示表单的轮廓 */
|
||||
padding: 1em;
|
||||
border: 1px solid #CCC;
|
||||
border-radius: 1em;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
form li + li {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
label {
|
||||
/* 确保所有label大小相同并正确对齐 */
|
||||
display: inline-block;
|
||||
width: 90px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
/* 确保所有文本输入框字体相同
|
||||
textarea默认是等宽字体 */
|
||||
font: 1em sans-serif;
|
||||
|
||||
/* 使所有文本输入框大小相同 */
|
||||
width: 300px;
|
||||
box-sizing: border-box;
|
||||
|
||||
/* 调整文本输入框的边框样式 */
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
input:focus, textarea:focus {
|
||||
/* 给激活的元素一点高亮效果 */
|
||||
border-color: #000;
|
||||
}
|
||||
|
||||
textarea {
|
||||
/* 使多行文本输入框和它们的label正确对齐 */
|
||||
vertical-align: top;
|
||||
|
||||
/* 给文本留下足够的空间 */
|
||||
height: 5em;
|
||||
}
|
||||
|
||||
.button {
|
||||
/* 把按钮放到和文本输入框一样的位置 */
|
||||
padding-left: 90px; /* 和label的大小一样 */
|
||||
}
|
||||
|
||||
button {
|
||||
/* 这个外边距的大小与label和文本输入框之间的间距差不多 */
|
||||
margin-left: .5em;
|
||||
}
|
||||
|
||||
现在,它看起来没那么丑了。
|
||||
|
||||
注意: 你可以在GitHub上的这里找到它 first-form-styled.html (也可以在这儿看运行结果).
|
||||
向您的web服务器发送表单数据
|
||||
|
||||
最后一部分,也许是最棘手的部分,是在服务器端处理表单数据。如前所述,大多数时候HTML表单是向用户请求数据并将其发送到web服务器的一种方便的方式。
|
||||
|
||||
<form> 元素将定义如何通过action 属性和 method属性来发送数据的位置和方式。
|
||||
|
||||
但这还不够。我们还需要为我们的数据提供一个名称。这些名字对双方都很重要:在浏览器端,它告诉浏览器给数据各自哪个名称,在服务器端,它允许服务器按名称处理每个数据块。
|
||||
|
||||
要将数据命名为表单,您需要在每个表单小部件上使用 name 属性来收集特定的数据块。让我们再来看看我们的表单代码:
|
||||
|
||||
<form action="/my-handling-form-page" method="post">
|
||||
<div>
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" id="name" name="user_name">
|
||||
</div>
|
||||
<div>
|
||||
<label for="mail">E-mail:</label>
|
||||
<input type="email" id="mail" name="user_email">
|
||||
</div>
|
||||
<div>
|
||||
<label for="msg">Message:</label>
|
||||
<textarea id="msg" name="user_message"></textarea>
|
||||
</div>
|
||||
|
||||
...
|
||||
|
||||
在我们的例子中,表单会发送三个已命名的数据块 "user_name", "user_email", 和 "user_message"。这些数据将用使用HTTP POST 方法,把信息发送到URL为 "/my-handling-form-page"目录下。
|
||||
|
||||
在服务器端,位于URL"/my-handling-form-page" 上的脚本将接收的数据作为HTTP请求中包含的3个键/值项的列表。这个脚本处理这些数据的方式取决于您。每个服务器端语言(PHP、Python、Ruby、Java、c等等)都有自己的机制。深入到这个主题已经超出了本指南的范围,但是如果您想了解更多,我们已经在发送表单数据文章中提供了一些示例。
|
||||
总结
|
||||
|
||||
祝贺您,您已经构建了您的第一个HTML表单。它看起来就像这样:
|
||||
|
||||
然而,这仅仅是开始,现在是时候深入研究了。HTML表单比我们在这里看到的要强大得多,本指南的其他文章将帮助您掌握其余部分。
|
||||
|
||||
305
htmlpress/表单2.md
Normal file
305
htmlpress/表单2.md
Normal file
@@ -0,0 +1,305 @@
|
||||
Skip to main content
|
||||
Skip to search
|
||||
|
||||
Search MDN
|
||||
Sign in
|
||||
发送表单数据
|
||||
|
||||
学习 Web 开发
|
||||
HTML表单指南
|
||||
发送表单数据
|
||||
|
||||
Select your preferred language
|
||||
Table of contents
|
||||
|
||||
数据都去哪儿了?
|
||||
特殊案例:发送文件
|
||||
常见的安全问题
|
||||
结论
|
||||
相关链接
|
||||
在本单元中
|
||||
|
||||
上一页
|
||||
Overview: Forms
|
||||
下一页
|
||||
|
||||
本文将讨论当用户提交表单时发生了什么——数据去了哪,以及当它到达时该如何处理?我们还研究了与发送表单数据相关的一些安全问题。
|
||||
预备知识:
|
||||
|
||||
基本计算机素养,对HTML的理解,对HTTP 和服务器端编程的基础知识。
|
||||
目标: 了解表单数据提交时发生了什么,包括服务器上如何处理数据的基本概念。
|
||||
数据都去哪儿了?
|
||||
|
||||
在这里,我们将讨论在提交表单时数据会发生什么。
|
||||
客户端/服务器体系结构
|
||||
|
||||
web基于非常基本的客户端/服务器体系结构,可以总结如下:客户端(通常是web浏览器)向服务器发送请求(大多数情况下是Apache、Nginx、IIS、Tomcat等web服务器),使用HTTP 协议。服务器使用相同的协议来回答请求。
|
||||
|
||||
A basic schema of the Web client/server architecture
|
||||
|
||||
在客户端,HTML表单只不过是一种方便的用户友好的方式,可以配置HTTP请求将数据发送到服务器。这使用户能够提供在HTTP请求中传递的信息。
|
||||
|
||||
注意:为了更好地了解客户端—服务器架构是如何工作的,请阅读我们的服务器端网站编程的第一个步骤模块。
|
||||
在客户端:定义如何发送数据
|
||||
|
||||
<form>元素定义了如何发送数据。它的所有属性都是为了让您配置当用户点击提交按钮时发送的请求。两个最重要的属性是action和method。
|
||||
action 属性
|
||||
|
||||
这个属性定义了发送数据要去的位置。它的值必须是一个有效的URL。如果没有提供此属性,则数据将被发送到包含这个表单的页面的URL。
|
||||
|
||||
在这个例子中,数据被发送到一个绝对URL —— http://foo.com:
|
||||
|
||||
<form action="http://foo.com">
|
||||
|
||||
这里,我们使用相对URL——数据被发送到服务器上的不同URL
|
||||
|
||||
<form action="/somewhere_else">
|
||||
|
||||
在没有属性的情况下,像下面一样,<form>数据被发送到表单出现的相同页面上:
|
||||
|
||||
<form>
|
||||
|
||||
许多较老的页面使用下面的符号表示数据应该被发送到包含表单的相同页面;这是必需的,因为直到HTML5action属性都需要该符号。现在,这不再需要了。
|
||||
|
||||
<form action="#">
|
||||
|
||||
注意:可以指定使用HTTPS(安全HTTP)协议的URL。当您这样做时,数据将与请求的其余部分一起加密,即使表单本身是托管在使用HTTP访问的不安全页面上。另一方面,如果表单是在安全页面上托管的,但是您指定了一个不安全的HTTP URL,它带有action属性,所有的浏览器都会在每次尝试发送数据时向用户显示一个安全警告,因为数据不会被加密。
|
||||
method属性
|
||||
|
||||
该属性定义了如何发送数据。HTTP协议提供了几种执行请求的方法;HTML表单数据可以通过许多不同的方法进行数据传输,其中最常见的是GET方法和POST方法。
|
||||
|
||||
为了理解这两种方法之间的区别,让我们回过头来看看HTTP是如何工作的。
|
||||
每当您想要访问Web上的资源时,浏览器都会向URL发送一个请求。
|
||||
HTTP请求由两个部分组成:一个包含关于浏览器功能的全局元数据集的头部,和一个包含服务器处理特定请求所需信息的主体。
|
||||
GET 方法
|
||||
|
||||
GET方法是浏览器使用的方法,请求服务器返回给定的资源:“嘿,服务器,我想要得到这个资源。”在这种情况下,浏览器发送一个空的主体。由于主体是空的,如果使用该方法发送一个表单,那么发送到服务器的数据将被追加到URL。
|
||||
|
||||
考虑下面这个表单:
|
||||
```
|
||||
|
||||
<form action="http://foo.com" method="get">
|
||||
<div>
|
||||
<label for="say">What greeting do you want to say?</label>
|
||||
<input name="say" id="say" value="Hi">
|
||||
</div>
|
||||
<div>
|
||||
<label for="to">Who do you want to say it to?</label>
|
||||
<input name="to" id="to" value="Mom">
|
||||
</div>
|
||||
<div>
|
||||
<button>Send my greetings</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
```
|
||||
|
||||
由于已经使用了GET方法,当你提交表单的时候,您将看到www.foo.com/?say=Hi&to=Mom在浏览器地址栏里。
|
||||
|
||||
数据作为一系列的名称/值对被附加到URL。在URL web地址结束之后,我们得到一个问号(?),后面跟着由一个与符号(&)互相分隔开的名称/值对。在本例中,我们将两个数据传递给服务器。
|
||||
|
||||
say, 它有一个 Hi的值。
|
||||
to, 它有一个 Mom的值。
|
||||
|
||||
HTTP请求如下:
|
||||
|
||||
GET /?say=Hi&to=Mom HTTP/2.0
|
||||
Host: foo.com
|
||||
|
||||
注意:你可以在GitHub 上看到本例子——见 get-method.html (预览版).
|
||||
POST 方法
|
||||
|
||||
POST方法略有不同。这是浏览器在询问响应时使用与服务器通信的方法,该响应考虑了HTTP请求正文中提供的数据:“嘿,服务器,看一下这些数据,然后给我回一个适当的结果。”如果使用该方法发送表单,则将数据追加到HTTP请求的主体中。
|
||||
|
||||
让我们来看一个例子,这是我们在上面的GET部分中所看到的相同的形式,但是使用method属性设置为post。
|
||||
|
||||
<form action="http://foo.com" method="post">
|
||||
<div>
|
||||
<label for="say">What greeting do you want to say?</label>
|
||||
<input name="say" id="say" value="Hi">
|
||||
</div>
|
||||
<div>
|
||||
<label for="to">Who do you want to say it to?</label>
|
||||
<input name="to" id="to" value="Mom">
|
||||
</div>
|
||||
<div>
|
||||
<button>Send my greetings</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
当使用POST方法提交表单时,没有数据会附加到URL,HTTP请求看起来是这样的,而请求主体中包含的数据是这样的:
|
||||
|
||||
POST / HTTP/2.0
|
||||
Host: foo.com
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: 13
|
||||
|
||||
say=Hi&to=Mom
|
||||
|
||||
Content-Length数据头表示主体的大小,Content-Type数据头表示发送到服务器的资源类型。稍后我们将讨论这些标头。
|
||||
|
||||
注意:你可以在 GitHub 上看到本例—— 见 post-method.html (预览版).
|
||||
查看HTTP请求
|
||||
|
||||
HTTP请求永远不会显示给用户(如果您想要看到它们,您需要使用诸如Firefox Network Monitor或Chrome Developer Tools之类的工具)。例如,您的表单数据将显示在Chrome网络选项卡中:
|
||||
|
||||
按下 F12
|
||||
选择 "Network"
|
||||
选择 "All"
|
||||
在 "Name" 标签页选择 "foo.com"
|
||||
选择 "Headers"
|
||||
|
||||
你可以获得表单数据,像下图显示的那样
|
||||
|
||||
唯一显示给用户的是被调用的URL。正如我们上面提到的,使用GET请求用户将在他们的URL栏中看到数据,但是使用POST请求用户将不会看到。这一点很重要,有两个原因:
|
||||
|
||||
如果您需要发送一个密码(或其他敏感数据),永远不要使用GET方法否则数据会在URL栏中显示,这将非常不安全。
|
||||
如果您需要发送大量的数据,那么POST方法是首选的,因为一些浏览器限制了URL的大小。此外,许多服务器限制它们接受的URL的长度。
|
||||
|
||||
在服务器端:检索数据
|
||||
|
||||
无论选择哪种HTTP方法,服务器都会接收一个字符串并解析,以便将数据作为键/值对序列获取。您访问这个序列的方式取决于您使用的开发平台以及您可能使用的任何特定框架。您使用的技术也决定了如何处理密钥副本;通常,最近收到的密钥的值是优先的。
|
||||
例如:原始PHP
|
||||
|
||||
PHP提供了一些全局对象来访问数据。假设您已经使用了POST方法,那么下面的示例将获取数据并将其显示给用户。当然,你对数据的处理取决于你自己。您可以显示它,将它存储到数据库中,通过电子邮件发送它,或者以其他方式处理它。
|
||||
|
||||
```
|
||||
<?php
|
||||
// The global $_POST variable allows you to access the data sent with the POST method by name
|
||||
// To access the data sent with the GET method, you can use $_GET
|
||||
$say = htmlspecialchars($_POST['say']);
|
||||
$to = htmlspecialchars($_POST['to']);
|
||||
|
||||
echo $say, ' ', $to;
|
||||
?>
|
||||
|
||||
```
|
||||
|
||||
这个例子显示了一个带有我们发送的数据的页面。您可以在我们的示例php-example.html中看到这一点——该文件包含与我们之前看到的相同的示例表单,它使用了post的method和php-example.php的action。当提交时,它将表单数据发送到php-example.php,其中包含了上述代码块中所见的php代码。当执行此代码时,浏览器中的输出是Hi Mom。
|
||||
|
||||
注意:当您将本例加载到本地浏览器中时,这个示例将无法工作---浏览器无法解析PHP代码,因此当提交表单时,浏览器只会为您提供下载PHP文件。为了让它生效,您需要通过某种类型的PHP服务器运行这个示例。本地PHP测试的好选择有MAMP(Mac和Windows)和AMPPS(Mac、Windows、Linux)。
|
||||
例子: Python
|
||||
|
||||
这个例子展示了如何使用Python完成同样的事情——在web页面上显示提交的数据。
|
||||
这将使用Flask framework来呈现模板、处理表单数据提交等(参见python-example.py)。
|
||||
|
||||
from flask import Flask, render_template, request
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/', methods=['GET', 'POST'])
|
||||
def form():
|
||||
return render_template('form.html')
|
||||
|
||||
@app.route('/hello', methods=['GET', 'POST'])
|
||||
def hello():
|
||||
return render_template('greeting.html', say=request.form['say'], to=request.form['to'])
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
||||
|
||||
以上代码中引用的两个模板如下:
|
||||
|
||||
form.html: 与我们在The POST method小节中看到的相同的表单,但是将action设置为{{ url_for('hello') }}。(这是一个Jinja2模板,它基本上是HTML,但是可以包含对运行包含在花括号中的web服务器的Python代码的调用。url_for('hello')基本上是在“提交表单时重定向到/hello”。
|
||||
greeting.html: 这个模板只包含一行,用于呈现渲染时传递给它的两个数据块。
|
||||
这是通过前面所见的hello()函数完成的,该函数在/helloURL被导向时运行。
|
||||
|
||||
注意:同样,如果您只是尝试将其直接加载到浏览器中,那么这段代码将无法工作。Python的工作方式与PHP略有不同——要在本地运行此代码,您需要安装Python/pip,然后使用pip3 install flask安装Flask。此时,您应该能够使用python3 python-example.py来运行这个示例,然后在浏览器中导航到localhost:5000。
|
||||
其他语言和框架
|
||||
|
||||
还有许多其他的服务器端技术可以用于表单处理,包括Perl、Java、 .Net、Ruby等。只挑你最喜欢的用就好。话虽如此,但值得注意的是,直接使用这些技术并不常见,因为这可能很棘手。更常见的是使用许多优秀的框架,这些框架使处理表单变得更容易,例如:
|
||||
|
||||
Django for Python (比Flask要重量级一些,但是有更多的工具和选项。)
|
||||
Express for Node.js
|
||||
Laravel for PHP
|
||||
Ruby On Rails for Ruby
|
||||
Phoenix for Elixir
|
||||
|
||||
要注意的是,即使使用这些框架,使用表单也不一定很容易。但这比从头开始编写所有功能要简单得多,而且会节省很多时间。
|
||||
|
||||
注意:向您介绍任何服务器端语言或框架超出了本文的范围。如果你想要学习这些它们,上面的链接会给你一些帮助。
|
||||
|
||||
特殊案例:发送文件
|
||||
|
||||
用HTML表单发送文件是一个特殊的例子。文件是二进制数据——或者被认为是这样的——而所有其他数据都是文本数据。由于HTTP是一种文本协议,所以处理二进制数据有特殊的要求。
|
||||
enctype 属性
|
||||
|
||||
该属性允许您指定在提交表单时所生成的请求中的Content-Type的HTTP数据头的值。这个数据头非常重要,因为它告诉服务器正在发送什么样的数据。默认情况下,它的值是application/x-www-form-urlencoded。它的意思是:“这是已编码为URL参数的表单数据。”
|
||||
|
||||
如果你想要发送文件,你需要额外的三个步骤:
|
||||
|
||||
将method属性设置为POST,因为文件内容不能放入URL参数中。
|
||||
将enctype的值设置为multipart/form-data,因为数据将被分成多个部分,每个文件单独占用一个部分,表单正文中包含的文本数据(如果文本也输入到表单中)占用一个部分。
|
||||
包含一个或多个File picker小部件,允许用户选择将要上传的文件。
|
||||
|
||||
例如:
|
||||
|
||||
```
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<div>
|
||||
<label for="file">Choose a file</label>
|
||||
<input type="file" id="file" name="myFile">
|
||||
</div>
|
||||
<div>
|
||||
<button>Send the file</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
```
|
||||
|
||||
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<div>
|
||||
<label for="file">Choose a file</label>
|
||||
<input type="file" id="file" name="myFile">
|
||||
</div>
|
||||
<div>
|
||||
<button>Send the file</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
注意:一些浏览器支持\<input>的multiple属性,它允许只用一个 \<input> 元素选择一个以上的文件上传。服务器如何处理这些文件取决于服务器上使用的技术。如前所述,使用框架将使您的生活更轻松。
|
||||
|
||||
警告:为了防止滥用,许多服务器配置了文件和HTTP请求的大小限制。在发送文件之前,先检查服务器管理员的权限是很重要的。
|
||||
常见的安全问题
|
||||
|
||||
每次向服务器发送数据时,都需要考虑安全性。到目前为止,HTML表单是最常见的攻击路径(可能发生攻击的地方)。这些问题从来都不是来自HTML表单本身,它们来自于服务器如何处理数据。
|
||||
|
||||
根据你所做的事情,你会遇到一些非常有名的安全问题:
|
||||
XSS 和 CSRF
|
||||
|
||||
跨站脚本(XSS)和跨站点请求伪造(CSRF)是常见的攻击类型,它们发生在当您将用户发送的数据显示给这个用户或另一个用户时。
|
||||
|
||||
XSS允许攻击者将客户端脚本注入到其他用户查看的Web页面中。攻击者可以使用跨站点脚本攻击的漏洞来绕过诸如同源策略之类的访问控制。这些攻击的影响可能从一个小麻烦到一个重大的安全风险。
|
||||
|
||||
CSRF攻击类似于XSS攻击,因为它们以相同的方式开始攻击——向Web页面中注入客户端脚本——但它们的目标是不同的。CSRF攻击者试图将权限升级到特权用户(比如站点管理员)的级别,以执行他们不应该执行的操作(例如,将数据发送给一个不受信任的用户)。
|
||||
|
||||
XSS攻击利用用户对web站点的信任,而CSRF攻击则利用网站对其用户的信任。
|
||||
|
||||
为了防止这些攻击,您应该始终检查用户发送给服务器的数据(如果需要显示),尽量不要显示用户提供的HTML内容。相反,您应该对用户提供的数据进行处理,这样您就不会逐字地显示它。当今市场上几乎所有的框架都实现了一个最小的过滤器,它可以从任何用户发送的数据中删除HTML<script>、<iframe> 和<object> 元素。这有助于降低风险,但并不一定会消除风险。
|
||||
SQL注入
|
||||
|
||||
SQL 注入是一种试图在目标web站点使用的数据库上执行操作的攻击类型。这通常包括发送一个SQL请求,希望服务器能够执行它(通常发生在应用服务器试图存储由用户发送的数据时)。这实际上是攻击网站的主要途径之一。
|
||||
|
||||
其后果可能是可怕的,从数据丢失到通过使用特权升级控制整个网站基础设施的攻击。这是一个非常严重的威胁,您永远不应该存储用户发送的数据,而不执行一些清理工作(例如,在php/mysql基础设施上使用mysql_real_escape_string()。
|
||||
HTTP数据头注入和电子邮件注入
|
||||
|
||||
这种类型的攻击出现在当您的应用程序基于表单上用户的数据输入构建HTTP头部或电子邮件时。这些不会直接损害您的服务器或影响您的用户,但它们会引发一个更深入的问题,例如会话劫持或网络钓鱼攻击。
|
||||
|
||||
这些攻击大多是无声的,并且可以将您的服务器变成僵尸。
|
||||
偏执:永远不要相信你的用户
|
||||
|
||||
那么,你如何应对这些威胁呢?这是一个远远超出本指南的主题,不过有一些规则需要牢记。最重要的原则是:永远不要相信你的用户,包括你自己;即使是一个值得信赖的用户也可能被劫持。
|
||||
|
||||
所有到达服务器的数据都必须经过检查和消毒。总是这样。没有例外。
|
||||
|
||||
远离有潜在危险的字符转义。应该如何谨慎使用的特定字符取决于所使用的数据的上下文和所使用的服务器平台,但是所有的服务器端语言都有相应的功能。
|
||||
限制输入的数据量,只允许有必要的数据。
|
||||
沙箱上传文件(将它们存储在不同的服务器上,只允许通过不同的子域访问文件,或者通过完全不同的域名访问文件更好)。
|
||||
|
||||
如果你遵循这三条规则,你应该避免很多问题,但是如果你想要得到一个有能力的第三方执行的安全检查,这是一个好主意。不要以为你已经看到了所有可能的问题。
|
||||
|
||||
注意:我们的服务器端学习主题的网站安全性文章更详细地讨论了上述威胁和潜在的解决方案。
|
||||
结论
|
||||
|
||||
如您所见,发送表单数据很容易,但要确保应用程序的安全性是很棘手的。请记住,前端开发人员不是应该定义数据安全模型的人。是的,我们将看到,执行客户端数据验证是可能的,但是服务器不能信任这种验证,因为它无法真正知道客户端到底发生了什么。
|
||||
|
||||
454
htmlpress/表格.md
454
htmlpress/表格.md
@@ -1,134 +1,370 @@
|
||||
# 表格(table)
|
||||
HTML 表格 入门
|
||||
|
||||
表格:由行和列组成的结构化数据集(表格数据)
|
||||
学习 Web 开发
|
||||
学习 HTML :指南与教程
|
||||
HTML 表格
|
||||
HTML 表格 入门
|
||||
|
||||
### 使用场景
|
||||
Select your preferred language
|
||||
Table of contents
|
||||
|
||||
html表格应用于展示表格数据,而不是用来实现网页布局
|
||||
什么是表格?
|
||||
动手练习: 创建你的第一个表格
|
||||
使用 <th> 元素添加标题
|
||||
允许单元格跨越多行和列
|
||||
为表格中的列提供共同的样式
|
||||
小结
|
||||
在本单元中
|
||||
|
||||
用表格实现网页布局出现的问题:
|
||||
Overview: Tables
|
||||
下一页
|
||||
|
||||
1. 表格布局减少了视觉受损的用户的可访问性
|
||||
2. 表格会产生更多的标签,使代码变得更难于编写,维护,调试
|
||||
3. 表格不能自动响应 正确的布局容器(如div ) 他们的默认宽度是父元素的100% 但表格的默认大小是根据其内容而定的。因此 如果要做移动端适配,就需要采取额外的措施来改变表格的样式
|
||||
本文将从HTML表格开始,介绍一些基本的内容,如行和单元格、标题、使单元格跨越多个列和行,以及如何将列中的所有单元组合在一起进行样式化。
|
||||
前置知识: HTML基本概念 (参见 Introduction to HTML)。
|
||||
目标: 了解熟悉HTML表格基本知识。
|
||||
什么是表格?
|
||||
|
||||
### 新建一个表格
|
||||
表格是由行和列组成的结构化数据集(表格数据),它能够使你简捷迅速地查找某个表示不同类型数据之间的某种关系的值 。比如说,某个人和他的年龄,一天或是一周,当地游泳池的时间表 。
|
||||
|
||||
1. 每个表格的内容都被包含在<table></table> 中 而且这些内容需要写在html结构的body部分
|
||||
2. 在表格中,最小的内容容器是单元格,是通过(td)创建的 这是一列
|
||||
3. 如果想换行,需要把位于同一行的内容包含在 一个tr 标签中 即用<tr></tr> 定义一行
|
||||
A sample table showing names and ages of some people - Chris 38, Dennis 45, Sarah 29, Karen 47.
|
||||
|
||||
示例:
|
||||
A swimming timetable showing a sample data table
|
||||
|
||||
```
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<table border="1">
|
||||
<tr>
|
||||
<td>姓名</td>
|
||||
<td>年龄</td>
|
||||
<td>性别</td>
|
||||
<td>班级</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>asd</td>
|
||||
<td>14</td>
|
||||
<td>男</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lily</td>
|
||||
<td>12</td>
|
||||
<td>女</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>asd</td>
|
||||
<td>14</td>
|
||||
<td>男</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lily</td>
|
||||
<td>12</td>
|
||||
<td>女</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
表格在人类社会中很常见,而且已经存在很长时间了,下面这张1800年的美国人口普查文件中就可以证明:
|
||||
|
||||
效果如下:
|
||||
A very old parchment document; the data is not easily readable, but it clearly shows a data table being used.
|
||||
|
||||

|
||||
因此,HTML的创建者们提供了一种方法来构建和呈现web上的表格数据,这也就不足为奇了。
|
||||
表格如何工作?
|
||||
|
||||
上面的代码中出现的 <table border="1"></table> 中的border 用于给表格加上边框
|
||||
表格的一个特点就是严格. 通过在行和列的标题之间进行视觉关联的方法,就可以让信息能够很简单地被解读出来。观察下面的示例表格,然后找一个单数人称代词,这个单数人称代词是用于第三人称的, 用于女性的, 用作句子中的对象. 你可以把相应的行和列的标题关联起来,找到答案。
|
||||
|
||||
人称代词
|
||||
Subject Object
|
||||
单数 第一人称 I me
|
||||
第二人称 you you
|
||||
第三人称 ♂ he him
|
||||
♀ she her
|
||||
o it it
|
||||
复数 第一人称 we us
|
||||
第二人称 you you
|
||||
第三人称 they them
|
||||
|
||||
正确完成后, 即使是盲人也可以解析 HTML 表格中的数据,一个成功的 HTML 表格应该做到无论用户是视力正常还是视力受损,都能提高用户的体验。
|
||||
表格风格
|
||||
|
||||
#### 表格表头(th)
|
||||
你可以在 GitHub 上找到上面表格的 HTML源码 ; 先去看看, 当然也可以看看这个 look at the live example! 你也许会注意到一件事情,那就是这个表格看上去可读性不是很好,那是因为现在这个页面上面的那个表格通过 MDN 站点添加了一些样式, 而 GitHub 上面的并没有添加。
|
||||
|
||||
table包裹的 th标签会有加粗的效果 看起来是表格的表头
|
||||
不要幻想; 为了能够让表格在网页上有效, 你需要提供一些 CSS 的样式信息,以及尽可能好的 HTML 固定结构. 在这个模块中,我们将专注于 HTML 部分; 在你完成这里的内容之后,你可以浏览 Styling tables 来了解 CSS 的部分。
|
||||
|
||||
把上面表格的顶部四个单元格做成表头效果:
|
||||
虽然在这个模块中我们不会专注于 CSS, 但是我们提供了一个较小的 CSS 样式表让你使用,和默认的没有采用任何 CSS 样式的表相比,表格会更加可读。 你可以在 stylesheet here 获取样式表,以及在 HTML template 获取 HTML 文件来应用样式表,这些会让你在 “测试 HTML 表格” 中有一个好的起点。
|
||||
|
||||
```
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<table border="1">
|
||||
<tr>
|
||||
<th>姓名</th>
|
||||
<th>年龄</th>
|
||||
<th>性别</th>
|
||||
<th>班级</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>asd</td>
|
||||
<td>14</td>
|
||||
<td>男</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lily</td>
|
||||
<td>12</td>
|
||||
<td>女</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>asd</td>
|
||||
<td>14</td>
|
||||
<td>男</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lily</td>
|
||||
<td>12</td>
|
||||
<td>女</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
注意: 也可以看下 personal_pronouns table with this styling applied 这个版本, 这个是应用了 CSS 以后表格看上去的样子。
|
||||
什么时候你不应该使用 HTML 表格?
|
||||
|
||||

|
||||
HTML 表格 应该用于表格数据 ,这正是 HTML 表格设计出来的用途. 不幸的是, 许多人习惯用 HTML 表格来实现网页布局, e.g. 一行包含 header, 一行包含几列内容, 一行包含 footer, etc. 你可以在我们的 Accessibility Learning Module 中的 Page Layouts 获得更多细节内容和一个示例。这种做法以前是很常见的,因为以前 CSS 在不同浏览器上的兼容性比较糟糕 ; 表格布局现在不太普遍,但您可能仍然会在网络的某些角落看到它们。
|
||||
|
||||
简单来说, 使用表格布局而不使用 CSS layout techniques 是很糟糕的. 主要的理由有以下几个:
|
||||
|
||||
表格布局减少了视觉受损的用户的可访问性: 屏幕阅读器, 被盲人所使用, 解析存在于 HTML 页面上的标签,然后为用户读出其中的内容。因为对于布局来说,表格不是一个正确的工具, 使用的标记比使用 CSS 布局技术更复杂, 所以屏幕阅读器的输出会让他们的用户感到困惑。
|
||||
表格会产生很多标签: 正如刚才提到的, 表格布局通常会比正确的布局技术涉及更复杂的标签结构,这会导致代码变得更难于编写、维护、调试.
|
||||
表格不能自动响应: 当你使用正确的布局容器 (比如 <header>, <section>, <article>, 或是 <div>), 它们的默认宽度是父元素的 100%. 而表格的的默认大小是根据其内容而定的。因此,需要采取额外的措施来获取表格布局样式,以便有效地在各种设备上工作。
|
||||
|
||||
### 允许单元格跨行或列
|
||||
动手练习: 创建你的第一个表格
|
||||
|
||||
对于表格的理论知识,我们已经说了很多了,所以, 让我们来看一个使用的例子,并建立一个简单的表格.
|
||||
|
||||
首先, 将 blank-template.html 和 minimal-table.css 拷贝到你的本地环境上。
|
||||
每一个表格的内容都包含在这两个标签中 : <table></table>. 在你的 HTML 的 <body> 中添加这些内容。
|
||||
在表格中,最小的内容容器是单元格, 是通过 <td> 元素创建的 ('td' 代表 'table data'). 把下面的内容添加到你的表格标签中:
|
||||
|
||||
<td>Hi, I'm your first cell.</td>
|
||||
|
||||
如果我们想要一行四个单元格,我们需要把这组标签拷贝三次,更新你表中的内容,让它看起来是这样的:
|
||||
|
||||
<td>Hi, I'm your first cell.</td>
|
||||
<td>I'm your second cell.</td>
|
||||
<td>I'm your third cell.</td>
|
||||
<td>I'm your fourth cell.</td>
|
||||
|
||||
你会看到, 单元格不会放置在彼此的下方, 而是自动与同一行上的其他单元格对齐. 每个 <td> 元素 创建一个单独单元格,它们共同组成了第一行。我们添加的每个单元格都使行的长度变长。
|
||||
|
||||
如果想让这一行停止增加,并让单元格从第二行开始,我们需要使用 <tr> 元素 ('tr' 代表 'table row'). 让我们现在来证实一下。
|
||||
|
||||
把你已经创建好的 4 个单元格放入 <tr> 标签, 就像:
|
||||
|
||||
<tr>
|
||||
<td>Hi, I'm your first cell.</td>
|
||||
<td>I'm your second cell.</td>
|
||||
<td>I'm your third cell.</td>
|
||||
<td>I'm your fourth cell.</td>
|
||||
</tr>
|
||||
|
||||
现在你已经实现了一行,可以继续增加至两行、三行。每一行都需要一个额外的 <tr> 元素来包装,每个单元格的内容都应该写在 <td>中。
|
||||
|
||||
这样会产生一个如下所示的表:
|
||||
Hi, I'm your first cell. I'm your second cell. I'm your third cell. I'm your fourth cell.
|
||||
Second row, first cell. Cell 2. Cell 3. Cell 4.
|
||||
|
||||
注意: 你也可以在 GitHub 中查看 simple-table.html (see it live also).
|
||||
使用 <th> 元素添加标题
|
||||
|
||||
现在,让我们把注意力转向表格标题,表格中的标题是特殊的单元格,通常在行或列的开始处,定义行或列包含的数据类型 (举个例子, 看到本篇文章中第一个示例中的 "单数" 或者 "Object" ). 为了说明它们为什么这么有用, 来看下面这个例子,首先是源代码:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Knocky</td>
|
||||
<td>Flor</td>
|
||||
<td>Ella</td>
|
||||
<td>Juan</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Breed</td>
|
||||
<td>Jack Russell</td>
|
||||
<td>Poodle</td>
|
||||
<td>Streetdog</td>
|
||||
<td>Cocker Spaniel</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Age</td>
|
||||
<td>16</td>
|
||||
<td>9</td>
|
||||
<td>10</td>
|
||||
<td>5</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Owner</td>
|
||||
<td>Mother-in-law</td>
|
||||
<td>Me</td>
|
||||
<td>Me</td>
|
||||
<td>Sister-in-law</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Eating Habits</td>
|
||||
<td>Eats everyone's leftovers</td>
|
||||
<td>Nibbles at food</td>
|
||||
<td>Hearty eater</td>
|
||||
<td>Will eat till he explodes</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
这是表格实际呈现的效果:
|
||||
Knocky Flor Ella Juan
|
||||
Breed Jack Russell Poodle Streetdog Cocker Spaniel
|
||||
Age 16 9 10 5
|
||||
Owner Mother-in-law Me Me Sister-in-law
|
||||
Eating Habits Eats everyone's leftovers Nibbles at food Hearty eater Will eat till he explodes
|
||||
|
||||
这里的问题是:虽然你可以弄清楚发生了什么,但是尽可能的交叉参考数据并不容易。如果列和行的标题以某种方式出现,那将会更好。
|
||||
动手练习: 表格标题
|
||||
|
||||
让我们来改进这个表格.
|
||||
|
||||
首先, 把 dogs-table.html 和 minimal-table.css 文件保存到你的本地环境,HTML 文件包含上文你看到的几种狗的数据。
|
||||
为了将表格的标题在视觉上和语义上都能被识别为标题,你可以使用 <th> 元素 ('th' 代表 'table header'). 用法和 <td>是一样的,除了它表示为标题,不是普通的单元格以外。进入你的 HTML 文件, 将表格中应该是标题的 <td> 元素标记的内容,都改为用 <th> 元素标记。
|
||||
保存你的 HTML 文件,然后在浏览器中加载,然后你应该会看到,现在的标题更像标题了。
|
||||
|
||||
注意: 你可以在 GitHub 中找到完成的版本 dogs-table-fixed.html (see it live also).
|
||||
为什么标题是有用的?
|
||||
|
||||
我们已经给出了部分答案,当标题明显突出的时候,你可以更加简单地找到你想找的数据,设计上也会看起来更好。
|
||||
|
||||
注意: 即使你不给表格添加你自己的样式,表格标题也会带有一些默认样式:加粗和居中,让标题可以突出显示。
|
||||
|
||||
表格标题也有额外的好处,随着 scope 属性 (我们将在下一篇文章中了解到),这个属性允许你让表格变得更加无障碍,每个标题与相同行或列中的所有数据相关联。屏幕阅读设备能一次读出一列或一行的数据,这是非常有帮助的。
|
||||
允许单元格跨越多行和列
|
||||
|
||||
有时我们希望单元格跨越多行或多列。以下是一个简单的例子,显示了一些常见动物的名字。在某些情况下,我们要显示动物名称旁边的男性和女性的名字。有时候我们又不需要,那不需要的情况下,我们希望写着动物的名字的单元格的宽度可以是两个单元格的宽度 (因为写着名字的行会有两列,而没有写名字的行只有一列,行的宽度是不一样的)。
|
||||
|
||||
一开始的标记写法是这样的:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Animals</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Hippopotamus</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Horse</th>
|
||||
<td>Mare</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Stallion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Crocodile</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Chicken</th>
|
||||
<td>Hen</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Rooster</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
但是输出的结果不是我们想要的:
|
||||
Animals
|
||||
Hippopotamus
|
||||
Horse Mare
|
||||
Stallion
|
||||
Crocodile
|
||||
Chicken Hen
|
||||
Rooster
|
||||
|
||||
我们需要一个方法,让 "Animals", "Hippopotamus", 和 "Crocodile" 的单元格的宽度变为两个单元格, "Horse" 和 "Chicken" 的高度变为两行 (因为要拥有一个男性名字和女性名字,可以先看效果图)。幸好, 表格中的标题和单元格有 colspan 和 rowspan 属性,这两个属性可以帮助我们实现这些效果。这两个属性接受一个没有单位的数字值,数字决定了它们的宽度或高度是几个单元格。比如, colspan="2" 使一个单元格的宽度是两个单元格。
|
||||
|
||||
让我们使用 colspan 和 rowspan 来改进现有的表格。
|
||||
|
||||
首先,把 animals-table.html 和 minimal-table.css 文件复制到你的本地环境,HTML 文件中包含了你刚才看到的动物示例的数据。
|
||||
接着,使用 colspan 让 "Animals", "Hippopotamus", 和 "Crocodile" 占 2 个单元格的宽度。
|
||||
最后,使用 rowspan 让 "Horse" 和 "Chicken" 占 2 个单元格的高度。
|
||||
保存后,用浏览器打开你写的 HTML 文件,看看改进的地方。
|
||||
|
||||
注意: 你也可以在 GitHub 上找到完成的版本 animals-table-fixed.html (see it live also).
|
||||
为表格中的列提供共同的样式
|
||||
|
||||
在我们继续介绍之前,我们将介绍本文中的最后一个功能。HTML有一种方法可以定义整列数据的样式信息:就是 <col> 和 <colgroup> 元素。 它们存在是因为如果你想让一列中的每个数据的样式都一样,那么你就要为每个数据都添加一个样式,这样的做法是令人厌烦和低效的。你通常需要在列中的每个 <td> 或 <th> 上定义样式,或者使用一个复杂的选择器,比如 :nth-child()。
|
||||
|
||||
下面是一个简单的示例:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Data 1</th>
|
||||
<th style="background-color: yellow">Data 2</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Calcutta</td>
|
||||
<td style="background-color: yellow">Orange</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Robots</td>
|
||||
<td style="background-color: yellow">Jazz</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
下面就是上述代码的结果:
|
||||
Data 1 Data 2
|
||||
Calcutta Orange
|
||||
Robots Jazz
|
||||
|
||||
这样不太理想,因为我们不得不在列中的每个单元格中重复那些样式信息 (在真实的项目中,我们或许会设置一个 class 包含那三个单元格 ,然后在一个单独的样式表中定义样式). 为了舍弃这种做法,我们可以只定义一次,在 <col> 元素中。<col> 元素被规定包含在 <colgroup> 容器中,而 <colgroup>就在 <table> 标签的下方。我们可以通过如下的做法来创建与上面相同的效果:
|
||||
|
||||
<table>
|
||||
<colgroup>
|
||||
<col>
|
||||
<col style="background-color: yellow">
|
||||
</colgroup>
|
||||
<tr>
|
||||
<th>Data 1</th>
|
||||
<th>Data 2</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Calcutta</td>
|
||||
<td>Orange</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Robots</td>
|
||||
<td>Jazz</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
我们使用了两个 <col>来定义“列的样式”,每一个<col>都会制定每列的样式,对于第一列,我们没有采取任何样式,但是我们仍然需要添加一个空的 <col> 元素,如果不这样做,那么我们的样式就会应用到第一列上,这和我们预想的不一样。
|
||||
|
||||
如果你想把这种样式信息应用到每一列,我们可以只使用一个 <col> 元素,不过需要包含 span 属性,像这样:
|
||||
|
||||
<colgroup>
|
||||
<col style="background-color: yellow" span="2">
|
||||
</colgroup>
|
||||
|
||||
就像 colspan 和 rowspan, span 需要一个无单位的数字值,用来制定你想要让这个样式应用到表格中多少列
|
||||
动手练习: colgroup and col
|
||||
|
||||
又到了需要你自己独立完成的时间了。
|
||||
|
||||
下面你可以看到一位语言老师的时间表。星期五,她有一个新的课程,全天教荷兰语,但是在星期二和星期四的几个时间点,她也教德语。她想把那些包含她教学的日子的列高亮显示。
|
||||
|
||||
通过下面这些步骤来重构这个表格。
|
||||
|
||||
首先,把 timetable.html 文件复制到你的本地环境。这个 HTML 文件包含你在上文中看到的表格,不过是减去样式信息的。
|
||||
在 table 的顶部添加一个 <colgroup> 元素,就放在 <table> 标签下面,<colgroup>可以添加 <col> 元素 (继续看下面剩余的步骤)。
|
||||
第一列和第二列不需要应用样式。
|
||||
为第三列添加一个背景颜色。style 属性是 background-color:#97DB9A;
|
||||
为第四列设置一个独立的宽度,style 属性是 width: 42px;
|
||||
为第五列添加一个背景颜色。style 属性是 background-color: #97DB9A;
|
||||
为第六列添加不同的背景颜色和边框,表示这是一个特殊的日子,表示她正在教一个新的课。 style 属性是 background-color:#DCC48E; border:4px solid #C1437A;
|
||||
最后两天是休息日,所以只需将它们设置为无背景颜色,但需要设置宽度;style 属性是 width: 42px;
|
||||
|
||||
看看你是否能完成这个示例,如果你遇到了困难,或想要核对你完成的作品,你可以在 GitHub 上找到完成的版本 timetable-fixed.html (see it live also)。
|
||||
小结
|
||||
|
||||
本章节仅仅包含了 HTML 表格的基础。在下一篇文章中,我们将介绍一些稍微更高级的表格功能,并开始考虑方便视力障碍的人士的访问
|
||||
|
||||
Overview: Tables
|
||||
下一页
|
||||
|
||||
在本单元中
|
||||
|
||||
HTML table basics
|
||||
HTML table advanced features and accessibility
|
||||
Structuring planet data
|
||||
|
||||
Related Topics
|
||||
|
||||
新手请从这开始!
|
||||
Web 入门
|
||||
HTML — 构建 Web
|
||||
HTML 介绍
|
||||
多媒体与嵌入
|
||||
HTML 表格
|
||||
HTML 表格概览
|
||||
HTML 表格基础
|
||||
HTML 高级表格特性和可访问性
|
||||
作业:构建行星数据
|
||||
CSS — 设计 Web
|
||||
CSS first steps
|
||||
CSS building blocks
|
||||
样式化文字
|
||||
CSS 排版概述
|
||||
JavaScript — 用户端动态脚本
|
||||
JavaScript 第一步
|
||||
JavaScript 基础要件
|
||||
JavaScript 对象介绍
|
||||
Asynchronous JavaScript
|
||||
客户端网页 API
|
||||
Web forms — Working with user data
|
||||
Core forms learning pathway
|
||||
Advanced forms articles
|
||||
可访问性 — 使每个人都能使用 Web
|
||||
可访问性指南
|
||||
可访问性测评
|
||||
工具与测试
|
||||
Client-side web development tools
|
||||
Introduction to client-side frameworks
|
||||
React
|
||||
Ember
|
||||
Vue
|
||||
Svelte
|
||||
Git and GitHub
|
||||
跨浏览器测试
|
||||
服务端网页编程
|
||||
第一步
|
||||
Django 网站框架 (Python)
|
||||
Express 网页框架 (node.js/JavaScript)
|
||||
更多资源
|
||||
常见问题
|
||||
|
||||
Last modified: 2020年9月15日, by MDN contributors
|
||||
|
||||
Web Technologies
|
||||
Learn Web Development
|
||||
About MDN
|
||||
Feedback
|
||||
|
||||
About
|
||||
MDN Web Docs Store
|
||||
Contact Us
|
||||
Firefox
|
||||
|
||||
|
||||
213
htmlpress/表格2.md
Normal file
213
htmlpress/表格2.md
Normal file
@@ -0,0 +1,213 @@
|
||||
HTML表格高级特性和可访问性
|
||||
|
||||
学习 Web 开发
|
||||
学习 HTML :指南与教程
|
||||
HTML 表格
|
||||
HTML表格高级特性和可访问性
|
||||
|
||||
Select your preferred language
|
||||
Table of contents
|
||||
|
||||
使用 <caption> 为你的表格增加一个标题
|
||||
添加 <thead>, <tfoot>, 和 <tbody> 结构
|
||||
嵌套表格
|
||||
对于视力受损的用户的表格
|
||||
总结
|
||||
|
||||
上一页
|
||||
Overview: Tables
|
||||
下一页
|
||||
|
||||
这个模块的第二篇文章中,我们来看一下 HTML 表格更高级的功能,比如像 表格的标题/摘要,以及将你表格中的各行分组成头部、正文、页脚部分,提高视力受损用户的可访问性。
|
||||
学习本章节的前提条件: HTML 的基础知识 (see Introduction to HTML).
|
||||
目的: 学习 HTML 表格进一步的功能,以及表格的无障碍访问性。
|
||||
使用 <caption> 为你的表格增加一个标题
|
||||
|
||||
你可以为你的表格增加一个标题,通过 <caption> 元素,再把 <caption> 元素放入 <table> 元素中. 你应该把它放在<table> 标签的下面。
|
||||
|
||||
<table>
|
||||
<caption>Dinosaurs in the Jurassic period</caption>
|
||||
|
||||
...
|
||||
</table>
|
||||
|
||||
从上面简单的例子可以推断,标题意味着包含对于表格内容的描述,这对那些希望可以快速浏览网页中的表格对他们是否有帮助的读者们来说,是非常好的功能。特别是盲人用户,不需要让屏幕阅读设备读出很多单元格的内容,来让用户了解这张表格讲的是什么,而是可以依靠标题的内容,来决定是否需要了解更详细的内容。
|
||||
|
||||
标题就放在 <table> 标签的下面。
|
||||
|
||||
注意: 这个 summary 属性也可以在<table> 元素中使用,用来提供一段描述,同样可以被屏幕阅读设备阅读。我们推荐使用 <caption> 元素来代替使用,因为 summary 被 HTML5 规范, deprecated (废除了),也不能被视力正常的用户阅读。 (它不会出现在页面上)
|
||||
动手练习: 添加一个标题
|
||||
|
||||
我们来试试看吧,回顾一下我们在之前的文章中第一次遇到的例子。.
|
||||
|
||||
打开你的语言老师的学校时间表,就是 HTML Table Basics 结尾中的例子,或者把 timetable-fixed.html 文件复制下面.
|
||||
为表格添加一个合适的标题。
|
||||
保存你的代码,然后用浏览器打开,看看你的表格是什么样的。
|
||||
|
||||
注意:你也可以在 GitHub 上找到我们的版本 timetable-caption.html (see it live also).
|
||||
添加 <thead>, <tfoot>, 和 <tbody> 结构
|
||||
|
||||
由于你的表格在结构上有点复杂,如果把它们定义得更加结构化,那会帮助我们更能了解结构。一个明确的方法是使用 <thead>, <tfoot>,和 <tbody>, 这些元素允许你把表格中的部分标记为表头、页脚、正文部分。
|
||||
|
||||
这些元素不会使表格更易于屏幕阅读器用户访问,也不会造成任何视觉上的改变。然而,它们在应用样式和布局上会起到作用,可以更好地让 CSS 应用到表格上。给你一些有趣的例子,在长表格的情况下,你可以在每个打印页面上使表格页眉和页脚重复,你也可以让表格的正文部分显示在一个单独的页面上,并通过上下滚动来获得内容。
|
||||
|
||||
试着使用它们:
|
||||
|
||||
<thead> 需要嵌套在 table 元素中,放置在头部的位置,因为它通常代表第一行,第一行中往往都是每列的标题,但是不是每种情况都是这样的。如果你使用了 <col>/<colgroup> 元素,那么 <thead>元素就需要放在它们的下面。
|
||||
<tfoot> 需要嵌套在 table 元素中,放置在底部 (页脚)的位置,一般是最后一行,往往是对前面所有行的总结,比如,你可以按照预想的方式将<tfoot>放在表格的底部,或者就放在 <thead> 的下面。(浏览器仍将它呈现在表格的底部)
|
||||
<tbody> 需要嵌套在 table 元素中,放置在 <thead>的下面或者是 <tfoot> 的下面,这取决于你如何设计你的结构。(<tfoot>放在<thead>下面也可以生效.)
|
||||
|
||||
注意: <tbody> 总是包含在每个表中,如果你没有在代码中指定它,那就是隐式的。可以来验证一下,打开一个你之前没有包含 <tbody> 的例子,然后在你的 browser developer tools 中观察你的代码,你会看到浏览器为你添加了这个标签。你也许会想问,为什么你应该在所有表中都需要这个元素,因为它可以让你更好地控制表格结构和样式。
|
||||
动手练习: 添加表格结构
|
||||
|
||||
让我们动手使用这些新元素。
|
||||
|
||||
首先,把 spending-record.html 和 minimal-table.css 拷贝到你的本地环境。
|
||||
尝试在浏览器中打开它,你会发现看起来不错,但是它可以被改善得更好。 "SUM" 行包含了已经使用的金额的总和,不过它出现在了错误的位置,以及代码中还遗失了一些细节。
|
||||
将明显的标题行改为使用 <thead> 元素,"SUM" 行使用 <tfoot> 元素,剩余的内容使用 <tbody> 元素。
|
||||
先保存,再刷新。你会看到,添加了 <tfoot> 元素后,导致 "SUM" 这行跑到了表格的底部。
|
||||
接着, 添加一个 colspan 属性,使 "SUM" 单元格占 4 个单元格的位置,所以实际数字是显示在 “Cost” 列的底部。
|
||||
让我们为表格添加一些简单的额外属性,能够让你理解这些属性是如何帮助更好地让表格应用 CSS 的。在你的 HTML 文件的 head 标签部分,你会看到一个空的 <style> 元素. 在 style 元素中添加下列 CSS 代码:
|
||||
|
||||
tbody {
|
||||
font-size: 90%;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
tfoot {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
先保存,再刷新,然后观察一下结果。如果没有 <tbody> 和 <tfoot> 元素,你也许会写更加复杂的选择器来应用同样的样式。
|
||||
|
||||
注意: 我们并不期望目前你可以理解所有 CSS 的内容。当你经过我们的 CSS 模块的时候,你应该会了解更多 (Introduction to CSS 是一个好的起点;我们也有专门的文章 styling tables).
|
||||
|
||||
你完成的表格应该如下所示:
|
||||
|
||||
注意: 你也可以在 GitHub 上找到 spending-record-finished.html (see it live also).
|
||||
嵌套表格
|
||||
|
||||
在一个表格中嵌套另外一个表格是可能的,只要你包含完整的结构,包括 <table> 元素。这样通常是不建议的,因为这种做法会使标记看上去很难理解,对使用屏幕阅读的用户来说,可访问性也降低了。以及在很多情况下,也许你只需要插入额外的 单元格/行/列 到已有的表格中。然而有时候是必要的,比如你想要从其他资源中更简单地导入内容。
|
||||
|
||||
下面的代码演示了一个简单的嵌套表格:
|
||||
|
||||
<table id="table1">
|
||||
<tr>
|
||||
<th>title1</th>
|
||||
<th>title2</th>
|
||||
<th>title3</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nested">
|
||||
<table id="table2">
|
||||
<tr>
|
||||
<td>cell1</td>
|
||||
<td>cell2</td>
|
||||
<td>cell3</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td>cell2</td>
|
||||
<td>cell3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>cell4</td>
|
||||
<td>cell5</td>
|
||||
<td>cell6</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
输出看起来是这样的:
|
||||
title1 title2 title3
|
||||
cell1 cell2 cell3
|
||||
cell2 cell3
|
||||
cell4 cell5 cell6
|
||||
对于视力受损的用户的表格
|
||||
|
||||
让我们简要回顾一下如何使用数据表。一个表格可以是一个便利的工具,或者让我们快速访问数据,并允许我们查找不同的值。比如,你只需要稍微看一眼下列的表格,你就能得知 2016 年 8 月份在 Gent 出售了多少个 Rings (戒指)。为了理解信息,我们让数据与列标题或行标题之间建立视觉联系。
|
||||
Items Sold August 2016 Clothes Accessories
|
||||
Trousers Skirts Dresses Bracelets Rings
|
||||
Belgium Antwerp 56 22 43 72 23
|
||||
Gent 46 18 50 61 15
|
||||
Brussels 51 27 38 69 28
|
||||
The Netherlands Amsterdam 89 34 69 85 38
|
||||
Utrecht 80 12 43 36 19
|
||||
|
||||
但假设你无法通过视觉关联这些数据呢? 那么你应该如何阅读上述的表格? 视力受损的用户经常使用一个屏幕阅读设备来为他们读出网页上的信息。对于盲人来说,阅读简单的文字没有什么问题,但是要理解一张表格的内容,这就有一些难度了。虽然,使用正确的标记,我们可以用程序化来代替视觉关联。
|
||||
|
||||
注意: 根据世界卫生组织 2017 年的数据,大约有 2.53 亿人患有视觉障碍。
|
||||
|
||||
本篇文章提供了更一步的技术来使表格的可访问性尽可能地提高。
|
||||
使用列和行的标题
|
||||
|
||||
屏幕阅读设备会识别所有的标题,然后在它们和它们所关联的单元格之间产生编程关联。列和行标题的组合将标识和解释每个单元格中的数据,以便屏幕阅读器用户可以类似于视力正常的用户的操作来理解表格。
|
||||
|
||||
我们之前的文章就提到过这一点,可见 Adding headers with <th> elements.
|
||||
scope 属性
|
||||
|
||||
本篇文章的一个新话题是 scope 属性,可以添加在<th> 元素中,用来帮助屏幕阅读设备更好地理解那些标题单元格,这个标题单元格到底是列标题呢,还是行标题。比如: 回顾我们之前的支出记录示例,你可以明确地将列标题这样定义:
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Purchase</th>
|
||||
<th scope="col">Location</th>
|
||||
<th scope="col">Date</th>
|
||||
<th scope="col">Evaluation</th>
|
||||
<th scope="col">Cost (€)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
以及每一行都可以这样定义一个行标题 (如果我们已经使用了 th 和 td 元素):
|
||||
|
||||
<tr>
|
||||
<th scope="row">Haircut</th>
|
||||
<td>Hairdresser</td>
|
||||
<td>12/09</td>
|
||||
<td>Great idea</td>
|
||||
<td>30</td>
|
||||
</tr>
|
||||
|
||||
屏幕阅读设备会识别这种结构化的标记,并一次读出整列或整行,比如:
|
||||
|
||||
scope 还有两个可选的值 : colgroup 和 rowgroup。这些用于位于多个列或行的顶部的标题。 如果你回顾这部分文章开始部分的 "Items Sold August 2016" 表格。你会看到 "Clothes" 单元格在"Trousers", "Skirts", 和 "Dresses" 单元格的上面。这几个单元格都应该被标记为 (<th>),但是 "Clothes" 是一个位于顶部且定义了其他三个子标题的标题。 因此 "Clothes" 应该有一个 scope="colgroup"属性,而另外三个子标题应该有 scope="col"属性。
|
||||
id 和标题属性
|
||||
|
||||
如果要替代 scope 属性,可以使用 id 和 headers 属性来创造标题与单元格之间的联系。使用方法如下:
|
||||
|
||||
为每个<th> 元素添加一个唯一的 id 。
|
||||
为每个 <td> 元素添加一个 headers 属性。每个单元格的headers 属性需要包含它从属于的所有标题的id,之间用空格分隔开。
|
||||
|
||||
这会给你的HTML表格中每个单元格的位置一个明确的定义。像一个电子表格一样,通过 headers 属性来定义属于哪些行或列。为了让它工作良好,表格同时需要列和行标题。
|
||||
|
||||
回到我们的花费成本示例,前两个片段可以重写为:
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th id="purchase">Purchase</th>
|
||||
<th id="location">Location</th>
|
||||
<th id="date">Date</th>
|
||||
<th id="evaluation">Evaluation</th>
|
||||
<th id="cost">Cost (€)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th id="haircut">Haircut</th>
|
||||
<td headers="location haircut">Hairdresser</td>
|
||||
<td headers="date haircut">12/09</td>
|
||||
<td headers="evaluation haircut">Great idea</td>
|
||||
<td headers="cost haircut">30</td>
|
||||
</tr>
|
||||
|
||||
...
|
||||
|
||||
</tbody>
|
||||
|
||||
注意: 这个放进为标题单元格和数据单元格之间创造了非常精确的联系。但是这个方法使用了大量的标记,所以容错率比较低。使用 scope 的方法对于大多数表格来说,也够用了。
|
||||
动手练习: 使用 scope 和 headers
|
||||
|
||||
对于这个最后的练习,首先把 items-sold.html 和 minimal-table.css,拷贝到你的本地环境。
|
||||
现在尝试添加适当的 scope 属性来让表格变得更加恰当。
|
||||
最后,尝试把未添加 scope 属性的源文件再复制一份。这次使用 id 和 headers 属性让表格变得更加恰当。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user