前言

作为程序员,技术的落实与巩固是必要的,因此想到写个系列,名为 why what or how 每篇文章解释清楚一个问题。

作为why what or how系列的第一章,选一个较为简单的话题,什么是 HTML

释义

HTML - HyperText Markup Language,超文本标记语言

标记语言,一类以固定的形式描述文档结构或是数据处理细节的语言,一般为纯文本形式,其内容作为其他程序的输入。

因此,HTML 是一种用于描述网页的标记语言,纯文本,其内容作为浏览器的输入。浏览器会解析 HTML 文本内容,最终呈现页面。

那么超文本又是什么?

在网页出现前,人们的阅读习惯是从前往后,从上到下,就像阅读小说,必须从头到尾的看完,思维是单向的,并不存在岔路口。而超文本从字面上理解就是:超出了一般的阅读习惯,看文章的时候思维是发散的,即通过链接的形式,跳出当前的思维流,转到另外一个页面,故而这些可以点击跳转的区域我们称之为超文本链接(具体到 HTML 标签上就是 a 标签),而具有这种特性的标记语言理所应当的被称为超文本标记语言。

那么为何浏览器偏偏要接收 HTML 而不接受其他的标记语言呢?这就不得不谈谈 HTML 与浏览器的诞生。

历史

  1. 1990 年,Tim Berners-Lee 提出了超文本的概念
  2. 1991 年,Tim Berners-LeeSGML 的基础上定义了 HTML ,并发布了 WorldWideWeb 浏览器,为了避免同 WWW 混淆,这个浏览器后来改名为 Nexus。同年发布了世界第一个站点 http://info.cern.ch/
  3. 1993 年,IETF(国际互联网工程任务组) 正式开始制定 HTML 规范,同年 Mosaic 浏览器发布,Web 的概念正式流行起来,之后的浏览器仍然在延用 Mosaic 的图形化操作界面思想
  4. 1994 年,Tim Berners-Lee 为了 Web 发展而成立了 W3C,同年 Netscape 成立,发布了第一款商业浏览器 Netscape Navigator(FireFox 的前身)
  5. 1995 年,IETF 发布 HTML 2.0 版本,同年 IE 3.0 正式发布,浏览器战争爆发
  6. 1996 年,W3C 接管了 HTML 的标准化工作,同年 Opera 浏览器发布
  7. 1997 年,W3C 发布 HTML 3.2 推荐标准
  8. 1998 年,Netscape 在于 IE 浏览器的战争中失利,将 Netscape Navigator 开源
  9. 1999 年,W3C 发布 HTML 4.0
  10. 2000 年,HTML 4.0 成为 ISO(国际标准化组织) 标准,至此之后 W3C 致力于 XHTML
  11. 2002 年,IE 成为主流浏览器
  12. 2003 年,SafariWebkit 渲染引擎登场
  13. 2004 年,由于 Web 的高速发展,HTML 4.0 中一些不合理的设计以及缺失的特性开始暴露,不满于 W3C 想要放弃 HTML,由浏览器厂商发起组织了 WHATWG 工作组,推进 HTML 的继续发展,也就是 HTML5
  14. 2004 年,Firefox 登场,第二场浏览器战争爆发,IE 溃败
  15. 2007 年,WHATWGW3C 握手言和,一起制定 HTML5 的标准
  16. 2008 年,两个工作组发布第一份草案,同年 ChromeV8 解析引擎登场,加速战争,统一战场
  17. 2014 年,发布 HTML5 ,同时 HTML 不再基于 SGML ,而是以一门单独的标记语言出现
  18. ...

纵观浏览器与 HTML 的发家史,浏览器的起起落落,HTML 版本的更新迭代,源头都是 Tim Berners-Lee ,或许 HTML 的命名与浏览器能解析 HTML 只是一种偶然,但这两种事物的出现却是一种必然,而这背后的主导者,是互联网,Tim Berners-Lee 也仅是执笔而已,为了纪念,他所创作的第一个站点也将被永久保存:http://info.cern.ch/

语法 or 结构

p-element
p标签

这是 HTML 中一个 p 标签,在 HTML 中大部分元素都有着同样的结构

  • 开始标签(Opening tag)
  • 结束标签(Closeing tag)
  • 标签内容(Enclosed text content)
  • 标签属性(An attribute and its value) - 以键值对的形式存在在开始标签上
  • 标签类型 - 开始标签中的第一个单词

只要是符合以上 5 个条件,就是一个合法的 HTML 标签。

当然大部分标签都有如上的结构,但还有小部分标签并没有标签内容,因此结束标签也就不必要的,比如引入图片

<img src="xxx.jpg" />

但是,针对于这种标签,需要在开始标签之后加上 / 代表该标记结束。

仅仅定义了标签当然是不够的,一个页面的呈现必须还要一个合理的结构。

HTML 结构的定义很简单:标签内容是标签的集合。这就像是函数的递归,嵌套的元素就构成了页面的结构。

HTML 中一段文字,换行,等文本内容也是一种元素,属于文本节点,这种节点仅有内容,而不具备标签的结构。

HTML 默认结构

正所谓没有规矩,不成方圆,想要让浏览器认识并成功显示页面需要有一个统一的模板,如下所示:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>my site</title>
  </head>
  <body>
    <p>hello world</p>
  </body>
</html>

从上到下每一行所代表的含义如下

  1. 声明该文档为 HTML 文档,由于 HTML 的发展,版本迭代了不少,各个版本的文档声明又不尽相同,而 HTML5 独立成一门单独的标记语言后,就不需要像之前版本一样写各种各样的声明,因此就简化为 <!DOCTYPE html>
  2. 页面根节点开始,标志着文档解析的开始
  3. 页面头节点开始,其子节点主要是告知浏览器需要知道但却不需要呈现在页面上的信息
  4. 通知浏览器使用 utf-8 的编码集呈现网页
  5. 通知浏览器该页面的标题为 my site ,通常浏览器会将该内容呈现在标题栏上
  6. 页面头节点结束
  7. 页面内容节点开始,其子节点为整个网页需要显示的内容,浏览器会将该内容渲染
  8. 一行段落,内容为 hello world
  9. 页面内容节点结束
  10. 页面根节点结束,文档解析结束

因此,我们可以大致知道,浏览器需要我们提供两部分的信息

  1. 一些与页面呈现无关但却需要通知浏览器的信息,即 head 的子元素,用于设置浏览器,比如编码方式,视口大小等
  2. 页面的结构,即 body 的子元素,用于呈现页面

除此之外,由于 head 中不需要有结构(信息只要一段一段的给即可,不需要嵌套),因此 head 中的元素只有一层,即没有子元素。

那么我们可以使用的标签都有哪些?

head 中的标签

head 中所能使用到的标签总共只有 6 个,如下

title

定义文档标题,通知浏览器页面的主体内容,浏览器一般将此信息置于标签栏,同时收藏或查看历史记录时,会以该信息作为关键字。形式如下:

<title>文档标题</title>

base

为网页上所有的超文本链接规定默认地址。浏览器在处理 body 中的链接会以该标签规定的默认地址为标志,该标签主要规定了两个内容

  • href - 所有的链接都以该属性的值作为默认链接
  • target - 规定浏览器打开某一链接的方式
    • _blank - 在新窗口中打开
    • _self - 在当前窗口中打开(如果是 iframe 中的文档,则在当前 iframe 中打开)
    • _parent - 在父窗口中打开(常用于 iframe 嵌套)
    • _top - 在顶层窗口中打开(常用于 iframe 多层嵌套)
    • framename - 在指定的 iframe 中打开

一个简单的例子

<base href="https://xxx.com" target="_blank" />

style

样式标签,其标签内容规定了页面的样式信息。可以在 MDN 上查看:CSS 介绍

script

脚本标签,其标签内容为浏览器需要执行的脚本信息。可以在 MDN 上查看:JavaScript

noscript

当页面不支持 script 或是用户主动关闭了 script 的执行时,浏览器将该标签内容作为提示信息,用于提示用户。

通知浏览器请求外部资源,丰富网页内容,或是优化体验,常见用法如下

  • 设置网页的 icon
<link rel="icon" type="image/x-icon" href="/path/to/icons/favicon.ico" />

如何使用网页 icon 以及浏览器具体对这个 icon 做了什么可以查看:详细介绍HTML favicon

  • 通知浏览器使用外部样式
<link rel="stylesheet" type="text/css" href="xxx.css" />

该种方式相信大家都已经耳熟能详了,主要是让样式进行分离,方便管理。

  • 提供 rss 订阅
<link rel="alternate" type="application/rss+xml" title="RSS" href="rss/path" />

这个主要是通知搜索引擎,当前页面的 rss 订阅在哪,浏览器上的插件也有能力获取到该信息。

  • 提供网页主页面
<link rel="canonical" href="main/page/path" />

主要用于搜索引擎,告知当前页面是附属于某个页面,引导搜索引擎去加载主页面。

  • 优化用户体验
<link rel="dns-prefetch" href="//xxx.com" />

通知浏览器提前抓取到 xxx.com 站点的 dns 信息,当页面下有大量关于 xxx.com 站点的请求时,添加该信息会加速数据的获取。

<link rel="prefetch" href="source/uri" />

通知浏览器提前抓取相应资源的内容,当用户加载该资源时,浏览器就会直接从缓存获取。

<link rel="preconnect" href="//xxx.com" />

通知浏览器提前与 xxx.com 站点进行 TCP 链接,加速资源的获取。

<link rel="prerender" href="//xxx.com" />

通知浏览器提前加载 xxx.com 站点的所有内容,当用户进去该站点时,就会立马呈现页面。

以上 4 个内容主要用于提升资源的加载速度,提升用户体验。但利弊时同时存在,当浏览器加载了大量资源,用户又不去访问时,就会照成资源大量消耗又得不到利用的情况。因此,合理的设置才是最正确的。

meta

最重要的总是最后出场,meta 单词意义就为元数据,该标签存在主要是帮助浏览器设置网页信息,常见用法如下:

  • 设置网页字符集
<meta charset="utf-8" />

HTML5 开始,用该种方式声明当前页面所采用的字符集,至于 HTML5 以前版本的声明方式,不推荐使用。

  • 设置网页重定向
<meta http-equiv="refresh" content="3;url=http://www.mozilla.org/" />

通知浏览器 3 秒后重定向到 url 所规定的地址。如果地址和当前网页是同一个地址,也就做到了隔 3 秒刷新一次的效果。

  • 设置网页缩放,以及视口大小
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />

通知浏览器设置视口,包括 宽度、初始缩放比例、最新缩放比例、最大缩放比例、是否允许用户进行缩放。

  • 告知网页信息
<meta name="author" content="页面作者" />
<meta name="description" content="页面大致描述" />
<meta name="keywords" content="页面关键字" />

常用到的 name 属性就是这些,但还有一些不常用的属性,如 application-namegeneratorreferrercreatorrobots 等可以在 MDN - META 上了解。

OK 总结一下就两点

  • head 中有 6 个子元素,title base style script noscript link meta
  • head 中的元素主要是告知浏览器一些信息,以及通知浏览器或搜索引擎做出相应动作

body 中的标签

body 就是描述网页内容的主体了,通过标签的嵌套来描述页面的内容。内容相关的标签主要分为几个大类:

  1. 块级标签,用于描述一片区域内的内容
  2. 内联标签,用于修饰一段文本
  3. 列表,用于列出相关联的几项内容
  4. 表格,用于展示二维数据
  5. 图片与多媒体,用于展示图片视频音频
  6. 表单,用于用户输入

至于如何编写 body 中的内容,可以参考该篇文章 文档与网站架构

这里列举一些常用的各个分类的标签

类型 常用标签
块级标签 p h[1-6] header nav main article aside footer div pre
内联标签 a code em i strong addr
列表 ul ol li dl dt dl
表格 table tr th td thead tbody tfoot caption
多媒体 img audio video
表单 form input textarea button

这里列举一下常用的通用标签属性

属性名 含义
id 设置 ID 一个元素仅能拥有一个 id,常用于 js 获取元素
class 设置类名,一个元素可以有多个类名,用于 css 设置元素样式
data-* 用于给元素设置一个附加属性,js 可以获取设置的值
type 用于表单元素,表示该元素为何种表单

完整的 HTML 标签可参照该篇文档 HTML 元素参考

HTML 与 JSP/ASP/PHP

想必大家都访问过 xxx.com/a.jsp 之类的网页,那么是否说浏览器请求了一个 jsp 文件,并解析展示了网页?

当然不是,能被浏览器解析并最终渲染成页面的只有 HTML 格式的文本,那么这种类型的链接又改如何解释呢?

在互联网的发展历程中,开发者发现有很多数据需要从数据库或是本地的文本文件中获取,但是手动写 HTML 文件太过于麻烦。以 java 为例,如果网站每天都会发生变化,那按照生成 HTML 文件的思路只能是每天生成一个 HTML 文件供用户访问,并且每天都要替换它,对很麻烦,那么该如何解决呢?

这就诞生了 jsp 。还是上面这个例子,jsp 的解决思路如下

  1. 用户请求 xxx.com/a.jsp
  2. java 程序捕获到用户的请求
  3. java 程序寻找相应的 jsp 文件
  4. java 程序到数据库或是本地文件中查出相应信息
  5. java 程序将这些信息填充到 jsp 文件中
  6. java 程序生成 HTML 格式的字符流
  7. java 程序将该字符流发送给浏览器
  8. 浏览器接收到字符流,判读出该字符流为 HTML 格式,开始解析并渲染

所以虽然浏览器的请求后缀为 jsp 但最终服务器发送给浏览器的还是 HTML 字符流。类似 ASP/PHP 等都是类似流程,因此 HTML 是单独于编程语言之外的语言,也可以说 HTML 是这些语言的输出,而 JSP/ASP/PHP 只不过辅助了程序进行输出 HTML 的一个中间文件而已。

总结

本文叙述了 HTML 标准和浏览器的诞生以及不断迭代的历史,和一些 HTML 的知识,既然以问句开篇,那么就以问句收尾,思考下这几个问题

  • 何为标记语言?
  • HTML 标签的结构如何?
  • HTML 是如何表述整个网页内容的?
  • 默认的 HTML 文档结构是怎样?
  • head 的作用是什么?又有哪些子元素?
  • 如何提升用户体验?涉及到的标签又是哪个?
  • body 是干嘛用的?常用的标签所代表的意义了解了吗?
  • 标签的大致分类有哪些?
  • HTMLjsp/asp/php 的关系如何?

最后

本文仅仅设计 HTML 不涉及 JSCSS ,本文不在于学习 HTML 在于归纳和总结,以及自己对 HTML 的一些看法,用于在已经了解 HTML 的基础上进一步巩固,至于想系统的学习,推荐几个网站

参考

最后的最后

该系列问题由 minimo 提出,爱你哟~~~