从零开始学习 HTML 编程

包含 head 和 body 的 HTML 文档树状图
HTML 文档的嵌套结构:html 包含 head 和 body

你打开过的每一个网页,无论是新闻网站、购物网站还是个人博客,都有一个用 HTML 编写的基本结构。HTML 不是那种需要做计算或写循环的编程语言,而是一种标记语言,告诉浏览器页面的每一部分是什么:标题、段落、图片、链接还是表单。本教程从零开始,带你做出一个可以实际使用的个人主页。

什么是 HTML

HTML 是 HyperText Markup Language(超文本标记语言)的缩写。“超文本”指的是由链接相互连接的文本,“标记”指的是用标签说明内容的含义。浏览器从上到下读取 HTML 文件,把这些标签解释为页面的结构,然后显示给用户。

HTML 不直接设置颜色或字体大小,那是 CSS 的工作;让页面可以交互,则是 JavaScript 的工作。三者的关系就像房子的框架(HTML)、墙面和装修(CSS),以及让房子能够运作的电线(JavaScript)。

需要的工具

编写 HTML 只需要两样工具:

1. **文本编辑器:** Windows 自带的记事本也能用,但推荐免费的 VS Code,它会高亮标签,并能自动补全代码。

2. **网页浏览器:** Chrome、Edge 或 Firefox,用来打开文件查看效果。

新建一个名为 `my-website` 的文件夹,然后在里面创建一个名为 `index.html` 的文件。`index.html` 是浏览器和网站服务器都认定为首页的标准文件名。

第一个网页

打开 `index.html`,输入下面的代码。

<!DOCTYPE html>
<html lang="zh-Hans">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>我的主页</title>
</head>
<body>
  <h1>你好,世界</h1>
  <p>这是我亲手写的第一个网页。</p>
</body>
</html>

逐个看看这些结构:

保存文件后双击,用浏览器打开,就能看到你写的标题和段落。

如何保存并运行每个示例

1. 在桌面新建一个名为 `my-website` 的文件夹。

2. 在该文件夹中新建 `index.html` 文件。后面每个示例对应的文件名都写在下面的表格中。

3. 复制示例中的代码,替换文件中的原有内容。

4. 以 UTF-8 编码保存。在记事本中选择“另存为”,并将编码设为 UTF-8。确认文件确实以 `.html` 结尾,而不是 `.html.txt`。

5. 双击文件即可在浏览器中打开,每次保存后也可以按 F5 刷新。

6. 如果使用 VS Code,建议安装 Live Server 扩展,这样每次保存页面都会自动刷新。

带有图片的示例(如画廊或咖啡店示例)需要把图片文件与 HTML 放在同一文件夹中,并且文件名必须与 `src` 的值完全一致。否则浏览器会显示破损的图片框,并改为显示 `alt` 文字。

文本与标题

HTML 提供从 `<h1>` 到 `<h6>` 的标题标签。`<h1>` 是最重要的标题,通常每个页面只使用一次。`<h2>` 到 `<h6>` 则按顺序用于小标题。

<h1>我的故事</h1>
<h2>童年</h2>
<p>我出生在北京,从小就喜欢读书。</p>
<p>我喜欢 <strong>编程</strong>,也喜欢 <em>摄影</em>。</p>
<p>这一行会<br>换到下一行。</p>

`<p>` 表示段落。`<strong>` 使文字加粗,并表示其重要性;`<em>` 使文字倾斜,并表示强调。`<br>` 在不开始新段落的情况下换行,它没有结束标签。

链接与图片

`<a>` 标签创建链接,`href` 的值就是目标地址。

<a href="https://www.example.com">访问示例网站</a>
<a href="about.html">前往关于我页面</a>

第一个链接指向外部网站,第二个链接打开同一文件夹中的 `about.html`。

`<img>` 标签用于显示图片。它需要 `src` 指定图片位置,并且应始终提供 `alt` 文字来描述图片,供看不见图片的人使用,或在图片无法加载时显示。

<img src="photo.jpg" alt="清晨的风景照片" width="400">

列表

无序列表使用 `<ul>`,有序列表使用 `<ol>`,每个条目使用 `<li>`。

<h2>我想学习的语言</h2>
<ul>
  <li>HTML</li>
  <li>CSS</li>
  <li>JavaScript</li>
</ul>

<h2>安装步骤</h2>
<ol>
  <li>下载程序</li>
  <li>按步骤安装</li>
  <li>打开程序开始使用</li>
</ol>

表格

表格使用 `<table>` 标签。每一行是 `<tr>`,表头单元格是 `<th>`,数据单元格是 `<td>`。

<table>
  <tr>
    <th>科目</th>
    <th>分数</th>
  </tr>
  <tr>
    <td>数学</td>
    <td>85</td>
  </tr>
  <tr>
    <td>英语</td>
    <td>78</td>
  </tr>
</table>

表格只应用于真正的表格型数据,不要用它来排版整个页面,否则屏幕阅读器会难以理解页面。

表单

表单让访问者把信息提交给服务器。例如,联系表单有姓名、邮箱和留言的输入框。

<form action="/send" method="post">
  <label for="name">姓名:</label>
  <input type="text" id="name" name="name" required>

  <label for="email">邮箱:</label>
  <input type="email" id="email" name="email" required>

  <label for="message">留言:</label>
  <textarea id="message" name="message" rows="4"></textarea>

  <button type="submit">发送</button>
</form>

`<label>` 通过 `for` 与输入框关联,`for` 的值必须与输入框的 `id` 相同。这样,点击标签就能让输入框获得焦点,屏幕阅读器也能读出每个输入框的用途。`required` 属性会阻止空白提交,`type="email"` 则让浏览器检查邮箱格式。

语义化标签

除了本身没有特定含义的 `<div>`,HTML5 还提供了能清楚描述页面结构的语义化标签。

<body>
  <header>
    <h1>我的网站</h1>
    <nav>
      <a href="index.html">首页</a>
      <a href="about.html">关于</a>
    </nav>
  </header>
  <main>
    <article>
      <h2>第一篇文章</h2>
      <p>文章的内容。</p>
    </article>
  </main>
  <footer>
    <p>版权所有 2026</p>
  </footer>
</body>

语义化标签有助于搜索引擎理解页面,也让使用屏幕阅读器的人更快地跳转到所需的部分。

属性:id 与 class

属性是写在标签内的附加信息,例如前面见过的 `href`、`src` 和 `alt`。最常用的两个是 `id` 和 `class`。

<p id="intro" class="highlight">这一段有自己的标识,并属于 highlight 分组。</p>
<p class="highlight">这一段也属于同一个分组。</p>

连接 CSS 与 JavaScript

为了让页面更美观,应把样式放在 CSS 文件中,并在 `<head>` 里用 `<link>` 标签引入。

<link rel="stylesheet" href="style.css">

`style.css` 中可以这样写:

body {
  font-family: sans-serif;
  background-color: #f5f7fb;
  color: #1a1a1a;
}
h1 {
  color: #2255aa;
}

JavaScript 通过 `<script>` 标签引入,通常放在 `</body>` 之前,使页面内容先加载完成。

<script src="main.js"></script>

小项目:个人主页

把所有内容组合起来,做一个个人主页。

<!DOCTYPE html>
<html lang="zh-Hans">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>我的主页</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header>
    <h1>张三</h1>
    <nav>
      <a href="#about">关于我</a>
      <a href="#skills">技能</a>
      <a href="#contact">联系</a>
    </nav>
  </header>

  <main>
    <section id="about">
      <h2>关于我</h2>
      <img src="me.jpg" alt="张三的照片" width="160">
      <p>我是一名正在每天学习新知识的网页开发者。</p>
    </section>

    <section id="skills">
      <h2>技能</h2>
      <ul>
        <li>HTML</li>
        <li>CSS</li>
        <li>JavaScript</li>
      </ul>
    </section>

    <section id="contact">
      <h2>联系</h2>
      <p>邮箱:<a href="mailto:[email protected]">[email protected]</a></p>
    </section>
  </main>

  <footer>
    <p>使用 HTML 制作</p>
  </footer>
</body>
</html>

链接 `#about` 指向同一页面中 `id="about"` 的元素,因此点击菜单会直接滚动到对应部分。`mailto:` 链接则会打开访问者的邮件程序。

实例:一步步制作咖啡店菜单

我们来制作一个虚构咖啡店的菜单页面,练习把多种标签组合在一起。先从基本骨架开始。

<!DOCTYPE html>
<html lang="zh-Hans">
<head>
  <meta charset="UTF-8">
  <title>花园咖啡菜单</title>
</head>
<body>
  <h1>花园咖啡菜单</h1>
  <p>每天营业,8:00 至 18:00。</p>
</body>
</html>

逐行说明:

接下来添加饮品分区。小标题使用 `<h2>`,列表使用 `<ul>` 和 `<li>`。

<h2>热咖啡</h2>
<ul>
  <li>浓缩咖啡 45 元</li>
  <li>拿铁 55 元</li>
  <li>卡布奇诺 55 元</li>
</ul>

<h2>冷饮</h2>
<ul>
  <li>冰美式 60 元</li>
  <li>抹茶拿铁 50 元</li>
</ul>

然后把价格放进表格,便于比较。这里使用前面讲过的 `<table>`、`<th>` 和 `<td>`。

<table>
  <tr>
    <th>饮品</th>
    <th>规格</th>
    <th>价格</th>
  </tr>
  <tr>
    <td>拿铁</td>
    <td>小杯</td>
    <td>55 元</td>
  </tr>
  <tr>
    <td>拿铁</td>
    <td>大杯</td>
    <td>65 元</td>
  </tr>
</table>

最后添加店铺照片和返回首页的链接,让页面真正可以使用。

<img src="shop.jpg" alt="被树荫遮蔽的花园咖啡店门面" width="600">
<p><a href="index.html">返回首页</a></p>

保存合并后的文件,用浏览器打开,就能看到包含标题、列表、表格和图片的菜单。修改某个饮品名称或价格后刷新浏览器,结果会立即显示。这种“编辑、保存、刷新”的循环,是你编写网页时每天都会用到的基本工作流程。

新手常犯的错误及解决方法

遇到问题时,打开浏览器的开发者工具(按 F12 并选择 Console 标签)。错误信息通常会指出出问题的行,能大大加快修复速度。

还值得了解的其他标签与命令

除了基础标签,HTML 还有许多能让页面更丰富的标签。以下是常用的几类,并附有简短示例。

强调与行内语义

<p>原价 <s>100 元</s>,现在只要 <mark>80 元</mark></p>
<p>水是 H<sub>2</sub>O,E = mc<sup>2</sup></p>
<p>注意:<small>不含税</small></p>
<p><abbr title="HyperText Markup Language">HTML</abbr> 的全称是什么?</p>
<p>会议时间是 <time datetime="2026-10-30">10 月 30 日</time></p>

`<mark>` 用于高亮文字,`<sub>` 和 `<sup>` 分别生成下标和上标,`<abbr>` 在鼠标悬停时显示全称,`<time>` 则提供人和机器都能读懂的日期。

引用与代码

<blockquote cite="https://example.com/source">
  学习就是不断地重复实践。
</blockquote>
<p>命令示例:<code>console.log("hi")</code></p>
<pre>
  这一行会保留
  输入时的空格和换行。
</pre>

`<blockquote>` 用于标示来自其他来源的引文,`<code>` 用于在句子中显示命令,`<pre>` 则完整保留空格和换行。

内容分组

<figure>
  <img src="chart.png" alt="月度销售图表" width="500">
  <figcaption>2026 年月度销售</figcaption>
</figure>

<details>
  <summary>点击查看报名方法</summary>
  <p>填写姓名和邮箱,然后确认即可。</p>
</details>

<dl>
  <dt>HTML</dt>
  <dd>用于构建网页结构的语言。</dd>
  <dt>CSS</dt>
  <dd>用于美化网页外观的语言。</dd>
</dl>

`<figure>` 和 `<figcaption>` 把图片与说明文字配对。`<details>` 在访问者点击前隐藏内容,`<dl>` 则把名词与解释成对排列。

视频、音频与嵌入框架

<video controls width="480" poster="cover.jpg">
  <source src="clip.mp4" type="video/mp4">
  你的浏览器不支持视频播放。
</video>

<audio controls>
  <source src="song.mp3" type="audio/mpeg">
</audio>

<iframe src="https://www.example.com/map" width="400" height="300" title="店铺位置地图"></iframe>

`controls` 会显示播放控件。`<iframe>` 可以把另一个页面嵌入自己的页面中。务必加上 `title`,让屏幕阅读器用户知道该框架的内容。

更多表单控件

<form>
  <fieldset>
    <legend>希望接收的资讯渠道</legend>
    <input type="checkbox" id="mail" name="channel" value="mail">
    <label for="mail">邮件</label>
    <input type="radio" id="sms" name="plan" value="sms">
    <label for="sms">短信</label>
  </fieldset>

  <label for="city">城市:</label>
  <select id="city" name="city">
    <option value="bj">北京</option>
    <option value="sh">上海</option>
  </select>

  <label for="visit">到访日期:</label>
  <input type="date" id="visit" name="visit">

  <label for="qty">数量:</label>
  <input type="number" id="qty" name="qty" min="1" max="10" value="1">
</form>

复选框允许多选,同一 `name` 的单选框只允许选一项。`<select>` 生成下拉菜单,`type="date"` 或 `type="number"` 则让浏览器显示适合该数据类型的控件。

分隔线与进度显示

<hr>
<p>下载已完成 70%</p>
<progress value="70" max="100"></progress>
<meter value="0.6" min="0" max="1">60%</meter>

`<hr>` 表示主题的分隔,而不只是装饰线。`<progress>` 显示进行中的任务,`<meter>` 则显示在某个范围内的测量值。

HTML 实例 10 则

下面是真实网站中常见的 10 种写法。每个示例都可以直接复制作为起点,并说明为什么这样编写。

示例 1:旅行日记

<article>
  <h2>清迈三天两夜</h2>
  <p>初春出行,天气凉爽宜人。</p>
  <ol>
    <li>第一天:双龙寺</li>
    <li>第二天:瓦洛洛市场</li>
    <li>第三天:因他暖山</li>
  </ol>
</article>

日记使用 `<article>`,因为它是可以独立阅读的内容。行程使用 `<ol>`,因为天数的顺序有意义,若改用 `<ul>` 就会失去这种顺序。

示例 2:带验证的注册表单

<form action="/register" method="post">
  <label for="username">用户名(4 至 12 个英文字母):</label>
  <input type="text" id="username" name="username"
         pattern="[A-Za-z]{4,12}" required>

  <label for="password">密码(至少 8 位):</label>
  <input type="password" id="password" name="password"
         minlength="8" required>

  <label for="birth">出生日期:</label>
  <input type="date" id="birth" name="birth">

  <button type="submit">注册</button>
</form>

`pattern` 用正则表达式检查文本,`minlength` 设定最小长度,`required` 表示必填。浏览器会在提交前提示用户修正,从而减轻服务器负担。但浏览器的检查很容易被绕过,因此服务器端仍必须再次验证。

示例 3:照片画廊

<section>
  <h2>旅途照片</h2>
  <figure>
    <img src="doi1.jpg" alt="因他暖山上的云海" width="300">
    <figcaption>清晨的云海</figcaption>
  </figure>
  <figure>
    <img src="temple.jpg" alt="被高大树木环绕的古老寺庙" width="300">
    <figcaption>老城区的一座寺庙</figcaption>
  </figure>
</section>

每张图片都放在 `<figure>` 中,并配有 `<figcaption>`,使说明文字真正与图片相关联。`alt` 应描述图片的内容,而不是只写“照片”。

示例 4:嵌套的导航菜单

<nav>
  <ul>
    <li><a href="index.html">首页</a></li>
    <li>
      <a href="shop.html">商店</a>
      <ul>
        <li><a href="shop-shirts.html">衬衫</a></li>
        <li><a href="shop-bags.html">包袋</a></li>
      </ul>
    </li>
    <li><a href="contact.html">联系我们</a></li>
  </ul>
</nav>

因为结构确实存在层级,所以菜单使用嵌套列表。屏幕阅读器可以告诉用户有多少项,以及每一项处于第几层。

示例 5:常见问题

<h2>常见问题</h2>
<details>
  <summary>下单后多久能收到商品?</summary>
  <p>根据地区不同,通常需要 1 至 3 个工作日。</p>
</details>
<details>
  <summary>可以退货吗?</summary>
  <p>如果商品未使用,可在 7 天内退货。</p>
</details>

`<details>` 可以让页面更简洁,无需 JavaScript 即可工作,并且对所有人都易于访问。

示例 6:套餐对比表

<table>
  <caption>套餐对比</caption>
  <thead>
    <tr>
      <th scope="col">项目</th>
      <th scope="col">基础版</th>
      <th scope="col">专业版</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">存储空间</th>
      <td>5 GB</td>
      <td>50 GB</td>
    </tr>
    <tr>
      <th scope="row">月费</th>
      <td>99 元</td>
      <td>299 元</td>
    </tr>
  </tbody>
</table>

`<caption>` 为表格命名,`<thead>` 和 `<tbody>` 将表头与内容分开,`scope` 则说明表头适用于列还是行。屏幕阅读器依靠这些信息正确地朗读数据。

示例 7:带出处的引文

<figure>
  <blockquote cite="https://example.com/book">
    <p>不要害怕慢,只怕停滞不前。</p>
  </blockquote>
  <figcaption>出自《作家之路》,<cite>作品名</cite></figcaption>
</figure>

`<cite>` 用于作品名称,而不是作者姓名。`<blockquote>` 上的 `cite` 属性指向来源。

示例 8:带建议的搜索框

<form action="/search" method="get" role="search">
  <label for="q">搜索商品</label>
  <input type="search" id="q" name="q" list="suggest" placeholder="例如:咖啡">
  <datalist id="suggest">
    <option value="中烘焙咖啡">
    <option value="深烘焙咖啡">
    <option value="绿茶">
  </datalist>
  <button type="submit">搜索</button>
</form>

`type="search"` 会为输入框提供清除按钮。`<datalist>` 在用户输入时提供建议。使用 `method="get"` 时,搜索词会出现在 URL 中,因此结果可以分享或收藏。

示例 9:使用 id 的页内链接

<nav>
  <a href="#intro">简介</a> |
  <a href="#terms">术语</a>
</nav>

<h2 id="intro">简介</h2>
<p>简介的正文内容……</p>

<h2 id="terms">术语</h2>
<dl>
  <dt>URL</dt>
  <dd>网络资源的地址。</dd>
  <dt>DNS</dt>
  <dd>将域名转换为 IP 地址的系统。</dd>
</dl>

以 `#` 开头的链接指向同一页面中的 `id`,因此浏览器无需加载新页面即可滚动到对应标题。

示例 10:面向搜索引擎和分享的元标签

<head>
  <meta charset="UTF-8">
  <meta name="description" content="从零开始学习用 HTML 制作网站。">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta property="og:title" content="从零开始学 HTML">
  <meta property="og:type" content="article">
  <link rel="canonical" href="https://example.com/html-course/">
</head>

`description` 是搜索引擎结果中常显示在标题下方的摘要。`og:title` 和 `og:type` 控制链接在社交媒体上分享时的显示方式。`canonical` 指明页面的主版本,有助于避免内容重复的问题。

额外示例的预期结果

示例保存为浏览器中应看到的内容
1. 旅行日记trip.html标题“清迈三天两夜”,下面是第 1 至第 3 天的编号列表
2. 注册表单register.html用户名、密码和出生日期输入框。如果用户名少于 4 个字母,浏览器会阻止提交并要求修改
3. 照片画廊gallery.html两张照片,每张下方有说明文字(图片文件必须与 HTML 在同一文件夹)
4. 嵌套菜单menu.html三个主菜单项,“商店”下有两个子项(没有 CSS 时只会显示为缩进的列表)
5. 常见问题faq.html两个问题。点击后展开答案,再次点击则收起
6. 对比表table.html上方有表格名称,列标题为“基础版”和“专业版”,行标题为粗体
7. 带出处的引文quote.html缩进的引用块,下方有出处行
8. 搜索框search.html输入文字时出现清除按钮;点击后显示建议(取决于浏览器)
9. 页内链接anchor.html点击“术语”会直接滚动到术语标题,地址以 `#terms` 结尾
10. 元标签head.html页面上不显示任何内容。可用“查看源代码”或 F12 的 Elements 标签查看 `<head>` 内部

从一开始就应养成的习惯

下一步

理解 HTML 之后,可以学习 CSS 来美化页面,再学习 JavaScript 让页面响应访问者的操作。之后还可以学习 Git 来管理代码,项目变大时再学习 React 或 Vue 等框架。

结语

HTML 是每个网页的基础。理解从 `<html>`、`<head>` 和 `<body>` 这些基本结构,到文本、链接、图片、列表、表格和表单的用法,你就能马上做出可以运行的页面。从小页面开始,逐步增加复杂度,每天练习一点,进步会很快。

本教程中制作的个人主页预览
本教程制作的个人主页