Web学习 - HTML

本文最后更新于 2026年4月11日 晚上

主要参考了

目录结构大体是参照MDN的,但是内容上会有我自己的省略 / 参考其他资料的补充。

HTML基础语法

什么是HTML

主要在上一篇笔记中有说明了,这里是一些补充 / 拾遗。

  • 最常见的HTML文件是index.html,通常用于网站主页
  • HTML的标签不区分大小写,但最佳实践还是所有标签都用小写书写

剖析一个HTML元素

元素是开始标签、内容和结束标签的总和。

空元素

并非所有元素都遵循"元素是开始标签、内容和结束标签的总和"的规律,有些元素只包含一个标签,通常用于在文档中插入/嵌入某些东西。这类元素被称为空元素

比如上面插入的那张图片:

<img src="https://image.wendaining.top/image-20260409143454274.png"  style="zoom:50%;" />

HTML 中,没有要求在空元素的标签末尾添加 /,但是这也是一种有效的语法。

属性

简单介绍

元素的属性belike:

<p class="editor-note">
     abcdefg
</p>

其中的class="editor-note"就是元素的属性。

属性包含关于元素的额外信息,这些信息不出现在内容中。

一个属性应该包含:

  • 一个在其与元素名之间的空格
  • (多个属性之间也用空格分隔)
  • 属性名后带等号和属性值

举个例子,<img>元素有多个属性,包括:

  • src:指定位置
  • alt:图像的文本描述
  • width, height,单位为像素

布尔属性

布尔属性比较特殊,和赋值无关,只要在属性的列中出现就是true,不出现就算false,举个例子:

<!-- 使用 disabled 属性来防止终端用户输入文本到输入框中 -->
<input disabled/>
<!-- 就算是这样写,结果仍然是启用的 -->
<input disabled=false/>
<!-- 下面这个输入框不包含 disabled 属性,所以用户可以向其中输入 -->
<input/>

属性周围的引号

有些情况下可以省略(比如没空格,单属性)

但是良好的开发实践建议始终包含属性引号

要在相同类型的引号内使用引号(单引号或双引号),请使用字符引用

<a href="https://www.example.com" title="一个&quot;有趣&quot;的引用">一个指向示例的链接。</a>

剖析HTML文档

<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8" />
    <title>我的测试页面</title>
  </head>
  <body>
    <p>这是我的页面</p>
  </body>
</html>
  1. <!doctype html>:文档类型声明,html文件的开头需要包括这个

  2. <html>:包裹页面上的所有内容,有时被称为根元素

  3. <head>:充当一个容器,用于存放你想包含在 HTML 页面中但不向页面浏览者显示的内容。这包括会出现在搜索结果中的关键字和页面描述、用于样式化内容的 CSS、字符集声明等等

  4. <meta charset="utf-8">

    这个元素代表了不能由其他 HTML 元相关元素(如 baselinkscriptstypetitle)表示的元数据。

    这句话有点绕,简化一下就是,诸如标题、样式、js代码等信息是有专门的head标签存放的,但是<meta>就是用来存放没有专门的标签的信息的。

  5. <title>:设置页面标题,会出现在加载该页面的浏览器标签页中

  6. <body> :包含显示在页面上的所有内容

HTML中的空白

<p id="noWhitespace">狗狗很 呆 萌。</p>

<p id="whitespace">狗狗很
    呆
        萌。</p>

这两段代码是等效的。无论你在 HTML 元素内容中使用了多少空白(可以包括一个或多个空格字符,也包括换行),HTML 解析器在渲染代码时都会将每个空白序列减少为单个空格。

不过,从JS访问的话,会保留所有空白:

const noWhitespace = document.getElementById("noWhitespace").innerHTML;
console.log(noWhitespace);
// "狗狗很 呆 萌。"

const whitespace = document.getElementById("whitespace").innerHTML;
console.log(whitespace);
// "狗狗很
//     呆
//         萌。"

字符引用

字面字符 字符引用等效项
< &lt;
> &gt;
" &quot;
' &apos;
& &amp;

前两个的记忆:less than, greater than

注释

<p>我不在注释里</p>

<!-- <p>但我在注释里</p> -->

HTML元信息

添加标题

区分<title><h1>:前者是表示整个HTML文件的标题的,后者是给body添加顶级标题的。

元数据:<meta>元素

元数据:描述数据的数据。

指定文档中的字符编码

<meta charset="utf-8" />

添加作者与描述

<meta name="wendaining" content="A Blog Site" />

如果name="description",会出现在搜索引擎里面:

<meta
  name="description"
  content="The MDN Web Docs site
  provides information about Open Web technologies
  including HTML, CSS, and APIs for both Web sites and
  progressive web apps." />
“MDN Web Docs”的搜索结果

其他类型的元数据

很多元数据是面向专有社交网站的,比如Twitter和Facebook,这些东西查询对应的API即可。

<meta property="og:title" content="Mozilla Developer Network" />

og:开头的就是一套Facebook写的,但是很通用的API。

添加自定义图标

<link rel="icon" href="logo.png" type="image/png">

也可以用ico格式:

<link rel="icon" href="favicon.ico" type="image/x-icon" />

在HTML中应用CSS和JavaScript

CSS使用<link>

<link rel="stylesheet" href="my-css.css" />

一般放在文档的头部rel="stylesheet" 表明这是文档的样式表,而 href 包含了样式表文件的路径。

当然,别忘记了在<head>里面嵌套<style>标签,里面写CSS的方式。

关于rel属性:

在日常开发中,你其实只需要记住最核心的这三个:

rel 的值 含义 浏览器的反应
stylesheet 样式表 “明白了,我得读取这个文件里的 CSS 代码,给网页上色。”
icon 图标 “收到了,我会把这个图片放在标签页的最左边。”
author 作者 “哦,这是指向作者介绍页面的链接。”

JavaScript脚本使用<script>

<script src="my-js-file.js" defer></script>

最好也放在网页的头部,同时最好加上 defer 以告诉浏览器在解析完成 HTML 后再加载 JavaScript。

为文档设定主语言

<html lang="zh-CN"></html>

也可以给分段设定语言:

<p>Japanese example: <span lang="ja">ご飯が熱い。</span>.</p>

HTML的文本级语义

标题和段落

段落:

<p>
    I'm a passage.
</p>

标题:

<h1>
    Header 1
</h1>

最好只对每个页面使用一次 <h1>——这是顶级标题,所有其他标题位于层次结构中的下方。

在现有的六个标题层次中,除非觉得有必要,否则应该争取每页使用不超过三个。

强调和重要性

强调

浏览器默认样式为斜体,但不应该纯粹为了获得斜体风格而使用这个标签。如果仅仅为了获得斜体样式而不增加语义辅助,应使用 span 元素和一些 CSS,或者是 <i> 元素(见下文)。

<p>我很<em>庆幸</em>你没有<em>迟到</em></p>

我很庆幸你没有迟到

着重强调

浏览器默认样式为粗体,但不应该纯粹为了获得粗体风格而使用这个标签。如果仅仅为了获得粗体样式而不增加语义辅助,应使用 span 元素和一些 CSS,或者是 <b> 元素(见下文)。

<p>
  这杯液体<strong>毒性很大</strong>——如果饮用了它,你<strong>可能<em>会死</em></strong></p>

这杯液体毒性很大——如果饮用了它,你可能会死

<em><strong>可以嵌套使用。

斜体、粗体、下划线等

到目前为止我们讨论的元素都有明确语义,但是<b> <i> <u>的情况不太一样。它们出现于还没有CSS的时候,像这样仅仅影响表象而且没有语义的元素,被称为表现元素并且不应该再被使用

因为语义对无障碍、搜索引擎优化(SEO)等非常重要。

列表

无序列表

<ul>
  <li>豆浆</li>
  <li>油条</li>
  <li>豆汁</li>
  <li>焦圈</li>
</ul>

<ul> stands for "unordered list", <li> stands for "list item".

有序列表

<ol>
  <li>沿这条路走到头</li>
  <li>右转</li>
  <li>直行穿过第一个十字路口</li>
  <li>在第三个十字路口处左转</li>
  <li>继续走 300 米,学校就在你的右手边</li>
</ol>

<ol> stands for "ordered list".

描述列表

描述列表的目的是标记一组项目及其相关描述,如术语-定义,问题-答案。

<dl>
  <dt>内心独白</dt>
  <dd>
    戏剧中,某个角色对自己的内心活动或感受进行念白表演,这些台词只面向观众,而其他角色不会听到。
  </dd>
  <dt>语言独白</dt>
  <dd>
    戏剧中,某个角色把自己的想法直接进行念白表演,观众和其他角色都可以听到。
  </dd>
  <dt>旁白</dt>
  <dd>
    戏剧中,为渲染幽默或戏剧性效果而进行的场景之外的补充注释念白,只面向观众,内容一般都是角色的感受、想法、以及一些背景信息等。
  </dd>
  <dd>
    写作中,指与当前主题相关的一段内容,通常不适于直接置于内容主线中,因此置于附近的其他位置(通常位于主线内容旁边一个文本框内)。
  </dd>
</dl>
内心独白
戏剧中,某个角色对自己的内心活动或感受进行念白表演,这些台词只面向观众,而其他角色不会听到。
语言独白
戏剧中,某个角色把自己的想法直接进行念白表演,观众和其他角色都可以听到。
旁白
戏剧中,为渲染幽默或戏剧性效果而进行的场景之外的补充注释念白,只面向观众,内容一般都是角色的感受、想法、以及一些背景信息等。
写作中,指与当前主题相关的一段内容,通常不适于直接置于内容主线中,因此置于附近的其他位置(通常位于主线内容旁边一个文本框内)。

最开始用<dl>(description list)包裹,每一项用<dt>(description term)包裹,每个描述用<dd>(description defination)包裹。

一个术语可以同时有多个描述

引用

块引用

<p>这是块引用:</p>
<blockquote
  cite="https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/blockquote">
  <p>
    <strong>HTML <code>&lt;blockquote&gt;</code> 元素</strong>(或<em
      >HTML 块级引用元素</em
    >)表示所附文本为扩展引用。
  </p>
</blockquote>

这是块引用:

HTML <blockquote> 元素(或HTML 块级引用元素)表示所附文本为扩展引用。

大概格式:<blockquote cite="xxxx"> 内容,一般带一个<p> </blockquote>

行内引用

把上面的blockquote换成q,里面不需要分段。

引文

上面两个的cite属性,浏览器事实上无法充分运用。如果不使用 JavaScript 或 CSS 编写自己的解决方案,就没有办法让浏览器显示 cite 的内容。

这里其实又是SEO开发思想的体现,语义第一,展示不重要。

这个后面很多标签中也有体现。

<p>
  根据<a href="/zh-CN/docs/Web/HTML/Element/blockquote"><cite>MDN 块引用页</cite></a></p>

<blockquote
  cite="https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/blockquote">
  <p>
    <strong>HTML <code>&lt;blockquote&gt;</code> 元素</strong>(或<em>HTML 块级引用元素</em>)表示所附文本为扩展引用。
  </p>
</blockquote>

<p>
  引用元素 <code>&lt;q&gt;</code><q cite="https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/q">用于不需要段落分隔的短引用。</q>——<a href="/zh-CN/docs/Web/HTML/Element/q"> <cite>MDN q 页面</cite></a>
</p>

比如这段代码的第一部分的<cite>看起来没什么用,但是作为语义规范需要保留。

缩略语

<p>我们使用 <abbr title="超文本标记语言">HTML</abbr>来组织网页文档。</p>

我们使用 HTML来组织网页文档。

鼠标放在上面会显示title属性的内容。

标记联系方式

<address>
  <p>wendaining<br/>
    Shanghai, China<br/>
    <ul>
        <li>Email: [email protected]</li>
        <li>GitHub: <a href="https://github.com/wendaining">Link</a></li>
    </ul>
</p>
</address>

wendaining
Shanghai, China

角标

  • 上角标<sup>
  • 下角标<sub>

都带结束标签。

代码

  • code:用于标记计算机通用代码。
  • pre:用于保留空白字符(通常用于代码块)——如果文本中使用了缩进或多余的空白,浏览器将忽略它,你将不会在渲染的页面上看到它。但是,如果你将文本包含在 <pre></pre> 标签中,那么空白将会以与你在文本编辑器中看到的相同的方式渲染出来。
  • var:用于标记具体变量名。
  • kbd:用于标记输入电脑的键盘(或其他类型)输入。
  • samp:用于标记计算机程序的输出。
代码HTML · 18 行
<pre><code>const para = document.querySelector('p');

para.onclick = function() {
  alert('噢,噢,噢,别点我了。');
}</code></pre>

<p>
  请不要使用 <code>&lt;font&gt;</code><code>&lt;center&gt;</code> 等表现元素。
</p>

<p>在上述的 JavaScript 示例中,<var>para</var> 表示一个段落元素。</p>

<p><kbd>Ctrl</kbd>/<kbd>Cmd</kbd> + <kbd>A</kbd> 选择全部内容。</p>

<pre>$ <kbd>ping mozilla.org</kbd>
<samp>PING mozilla.org (63.245.215.20): 56 data bytes
64 bytes from 63.245.215.20: icmp_seq=0 ttl=40 time=158.233 ms</samp></pre>

时间和日期

<time datetime="2016-01-20">2016 年 1 月 20 日</time>

构建文档

这一部分讨论如何规划基本的网站结构,并据此编写HTML。

文档的基本组成部分

  • 页眉:通常是一个横跨顶部的大条带
  • 导航栏:指向网站各个主要区段的超链接
  • 主内容:不解释,依网页而异
  • 侧边栏:
  • 页脚:通常包含细小文字、版权声明或联系信息

用于构建内容的HTML

  • 页眉 <header>
  • 导航栏 <nav>
  • 主内容 <main>,里面还可以有各种区段,比如<article> <section> <div>
  • 侧边栏 <aside>,经常放在<main>
  • 页脚 <footer>

HTML布局元素细节

无语义包装器

有时候现有的HTML元素没法很好的标识想表达的部分的语义,又或者只是想把一堆元素放在一起,然后用CSS或JS加以影响。

为了这种情况,有<div><span>元素。应配合使用class属性提供一些标签,使这些元素能易于定位。

<span>

<span>行级的无语义元素,比如:

<p>
  国王喝得酩酊大醉,在凌晨 1 点时才回到自己的房间,踉跄地走过门口。<span
    class="editor-note"
    >[编辑批注:此刻舞台灯光应变暗]</span
  >。
</p>

这里,“编辑批注”仅仅是对舞台剧导演提供额外指引;没有具体语义。对于视力正常的用户,CSS 应将批注内容与主内容稍微隔开一些。

<div>

块级的无语义元素。

div元素非常便利但容易被滥用。由于它们不携带语义值,会使 HTML 代码变得混乱。要小心使用,只有在没有更好的语义方案时才选择它,而且要尽可能少用,否则文档的升级和维护工作会非常困难。

换行与水平分割线

<br>是换行、<hr>是分割线。

创建超链接

链接的解析

将内容包裹在<a>里面,给一个包含网址的href属性即可。

<p>
  我创建了一个指向
  <a href="https://www.mozilla.org/zh-CN/">Mozilla 主页</a>的链接。
</p>

块级链接

任何内容包括块级元素都可以作为链接出现。

将标题作为链接:

<a href="https://developer.mozilla.org/zh-CN/">
  <h1>MDN Web 文档</h1>
</a>
<p>自从 2005 年起,就开始记载包括 CSS、HTML、JavaScript 等网络技术。</p>

将图片作为链接:

<a href="https://developer.mozilla.org/zh-CN/">
  <img src="mdn_logo.svg" alt="MDN Web 文档" />
</a>

使用title添加支持信息

这旨在包含关于链接的补充信息,例如页面包含什么样的信息或需要注意的事情。

<p>
  我创建了一个指向
  <a
    href="https://www.mozilla.org/zh-CN/"
    title="了解 Mozilla 使命以及如何参与贡献的最佳站点。">
    Mozilla 主页</a
  >的超链接。
</p>

文档片段

超链接不止可以链接到文档,也可以链接到文档的特定部分。这个特定部分需要有一个id

通常情况下,链接到一个特定的标题是有意义的。

<!-- contact.html -->
<h2 id="Mailing_Address">
    <a href="mailto:[email protected]">
    	向wdn发邮件
    </a>
</h2>
<!-- index.html -->
<p>
    mail to <a href="contact.html#Mailing_Address">here</a>
</p>

这里的mailto,加上之后用户点击,会打开邮件发送客户端。

事实上,mailto还可以指定更多信息,以至于可以包含邮件的标题、正文等,这里按下不表,自己查API。

链接到非HTML资源

<p>
  <a href="https://www.example.com/large-report.pdf">
    下载销售报告(PDF,大小为 10 MB)
  </a>
</p>

target="_blank"在新的浏览器标签页或新的窗口中打开链接

target="_self"(默认):在当前所在的标签页/窗口中打开链接

如果是需要下载的资源:使用 download 属性来提供一个默认的保存文件名。

<p>
  <a href="https://www.example.com/large-report.pdf" download="销售报告.pdf">
    下载销售报告(PDF,大小为 10 MB)
  </a>
</p>

HTML中的图片、视频、音频、表格、表单

图片

<figure>
  <img
    src="images/dinosaur.jpg"
    alt="The head and torso of a dinosaur skeleton;
            it has a large head with long sharp teeth"
    width="400"
    height="341" />

  <figcaption>
    A T-Rex on display in the Manchester University Museum.
  </figcaption>
</figure>
  • alt:无障碍,或者图片无法加载时显示的文字
  • width height 单位是px
  • <figure>:一个容器
  • <figcaption>:显示在图片下面的说明文字

视频

<video
  controls
  width="400"
  height="400"
  autoplay
  loop
  muted
  preload="auto"
  poster="poster.png">
  <source src="rabbit320.mp4" type="video/mp4" />
  <source src="rabbit320.webm" type="video/webm" />
  <p>你的浏览器不支持此视频。可点击<a href="rabbit320.mp4">此链接</a>观看</p>
</video>
  • controls:允许用户调节视频播放
  • autoplay:使内容立刻播放,音频也适用
  • loop muted:就字面意思,没啥好说的,第二个是默认关闭声音
  • poster:这个属性指向了一个图像的 URL,这个图像会在视频播放前显示
  • preload:这个属性被用来缓冲较大的文件
    • "none":不缓冲文件
    • "auto":页面加载后缓存媒体文件
    • "metadata":仅缓冲文件的元数据
  • <source>:字面意思,注意type属性,为了解码
  • video 元素内的段落:这个叫做后备内容,当浏览器不支持 <video> 元素的时候,就会显示这段内容

音频

<audio><video>除了width height poster以外几乎一模一样

表格

  • <tr>包裹每一行(row)
  • 在行的块里面,每个<td>包裹一个单元格

感觉意义不大,这一块语法有点杂,而且大概率用不到什么很复杂的设计,具体参考API / 问LLM都可以。

或者说很多地方也有excel / markdown导出HTML,也可以拿过来用。

按钮

<button>点击这里</button>

需要搭配JavaScript代码来完成工作。

表单

<form action="./submit_page" method="get">
  <h2>订阅我们的新闻简报</h2>
  <p>
    <label for="name">姓名(必填):</label>
    <input type="text" name="name" id="name" required />
  </p>
  <p>
    <label for="email">邮箱(必填):</label>
    <input type="email" name="email" id="email" required />
  </p>
  <p>
    <button>订阅新闻简报!</button>
  </p>
</form>
  • <form>元素:作为表单的外层元素,将所有的表单控件组织到一起;当点击<bottom>时,所有填写的数据将被提交。有这些属性:

    • action:包含一个路径,用于指定提交的表单数据将发送到哪个页面进行处理
    • method:指定将表单数据发送到服务器时所用的数据传输方法;当值为 get 时,数据会作为参数附加在 URL 的末尾进行发送
    • <form>内可以包含任意的HTML元素。这里的每一对输入框/标签和提交按钮分别放在一个单独的<p>元素中,这样每一组控件就会独占一行上。如果我们不这么做,所有的控件将会处于同一行上。如何分割组件的方法有很多,比如用<div>什么的,只要合乎语义即可。
  • <input> 元素:

    <input type="text" name="name" id="name" required />
    • type:指定要创建的表单控件类型。表单控件类型有很多,从各种简单的文本字段,到单选按钮、复选框等。比如,当值为 text 时,会渲染一个可接受任意文本的基本文本框,当值为color,会显示一个取色器,这里有很多,还有比如email password,读API即可。
    • name:为该数据项指定一个名称。当表单提交时,数据会以name/value pairs的形式发送。一般来说,name 属性的值就是这个数据项的“名称”,而用户在文本框输入的数据就是这个数据项的“值”。
    • required:指定该表单控件在提交表单前必须填写。这应仅用于必填字段,而不应设置在可选字段上。
  • <label>元素:用于描述应该在控件中输入的数据,<label><input>之间的关联方式是:给<input>设置一个 id 属性,然后给 <label> 设置 for 属性,其值与该<input>id 相同

    <label for="name">姓名(必填):</label>
    <input type="text" name="name" id="name" required />
  • <botton>元素:这个元素被放在<form>元素中时,默认行为是提交表单,当然这种默认行为可以通过修改type属性来修改:

    • type="submit":一般不需要显式声明,除非有多个按钮
    • type="reset":字面意思,但是不建议使用
    • type="botton":创建一个普通按钮,默认什么都不做,可以搭配JS实现功能

单选按钮

实现这样的单选按钮,使用<input type="ratio">

代码HTML · 23 行
<fieldset>
  <legend>选择酒店房型:</legend>
  <div>
    <input
      type="radio"
      id="hotelChoice1"
      name="hotel"
      value="economy"
      checked />
    <label for="hotelChoice1">经济型(+$0)</label>

    <input type="radio" id="hotelChoice2" name="hotel" value="superior" />
    <label for="hotelChoice2">高级型(+$50)</label>

    <input
      type="radio"
      id="hotelChoice3"
      name="hotel"
      value="penthouse"
      disabled />
    <label for="hotelChoice3">顶级套房(+$150)</label>
  </div>
</fieldset>

有这么几点需要注意:

  • 每组(每个<input>)单选按钮的 name 属性值必须相同,以便将它们关联成一组
  • 每个单选按钮必须有一个value属性,用于指定提交时该按钮对应的值
  • 描述整组选项的推荐做法是使用<fieldset>包裹这些选项,然后使用子元素<legend>提供整体描述
  • <fieldset>字段添加disabled属性,会导致整个表单被禁用
  • 需要其中一个按钮添加checked属性,这样意味着总会有一个选项被选中,并且无法取消选中一个单选按钮,除非选择另一个。

复选框

<fieldset>
  <legend>选择要参加的课程:</legend>
  <div>
    <input type="checkbox" id="yoga" name="yoga" />
    <label for="yoga">瑜伽(+$10)</label>

    <input type="checkbox" id="coffee" name="coffee" />
    <label for="coffee">咖啡烘焙(+$20)</label>

    <input type="checkbox" id="balloon" name="balloon" />
    <label for="balloon">气球动物艺术(+$5)</label>
  </div>
</fieldset>

和单选按钮的区别主要在于:

  • 可以选多个或0个选项,所以name也各不同
  • value一般不设置,因为具体是什么不重要,只要有传回就是true

下拉菜单

<label for="transport">出行方式:</label>
<select name="transport" id="transport">
  <option value="">--请选择一项--</option>
  <option value="plane">乘坐飞机</option>
  <option value="bike">骑自行车</option>
  <option value="walk">徒步</option>
  <option value="bus">乘坐公交</option>
  <option value="train">搭乘火车</option>
  <option value="jetPack">使用喷气背包</option>
</select>

多行输入文本框

<label for="comments">其他备注:</label>
<textarea id="comments" name="comments" rows="5" cols="33"></textarea>

缺省默认 cols="20"rows="2"

后记

感觉记了好多没啥用,查API文档也能用的语法...就当留个印象吧,能亲手写的机会微乎其微。