大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
HTML:从 0 写出完整页面
这一课你将能做到
- 从零写出一个结构完整、可直接在浏览器打开的 HTML 页面
- 正确使用表单(input/select/textarea)和表格(table)展示和收集数据
- 用语义化标签(header/nav/main/article/footer)搭建清晰的页面结构
为什么要学
HTML 是网页的骨架。你刷的任何网站——新闻、视频、购物——底层都是 HTML。CSS 负责好不好看,JavaScript 负责能不能动,但内容本身是 HTML 给的。不会 HTML,后面学的所有东西都没地方落地。
人话:HTML 就像盖房子时的户型图和承重结构,决定有几个房间、门在哪、窗在哪。CSS 是装修,JavaScript 是水电和电器。户型不对,装修再豪华也白搭。
对初学者来说,HTML 是进入前端门槛最低、反馈最快的一步:写几行代码,双击文件,浏览器立刻给你结果。
先建立图像
一个完整的 HTML 文档长这样:
<!DOCTYPE html>
<html lang="zh-CN">
<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>
结构对应关系:
<!DOCTYPE html> → 声明:这是 HTML5 文档
<html> → 根元素,整个页面的容器
<head> → 头部:放元信息,不直接显示
<body> → 主体:所有可见内容
浏览器拿到这个文件后,会把它解析成一棵 DOM 树(Document Object Model),每个标签变成树上的一个节点,后面的 CSS 和 JS 都是在这棵树上做操作。
跟着做
步骤 1:创建第一个页面
新建文件夹 my-site,在里面新建 index.html,用 VS Code 打开,输入:
<!DOCTYPE html>
<html lang="zh-CN">
<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>
保存后双击文件,浏览器打开就能看到内容。几个关键点:
<meta charset="UTF-8">必须放在<head>最前面,否则中文乱码<meta name="viewport" ...>让页面在手机上正常缩放,现代页面标配<title>显示在浏览器标签页上
步骤 2:常用文本标签
<h1>一级标题(一页只用一个)</h1>
<h2>二级标题</h2>
<h3>三级标题</h3>
<p>这是一个段落。段落会自动换行,前后有间距。</p>
<p>行内可以<strong>加粗</strong>、<em>斜体强调</em>、
<a href="https://developer.mozilla.org" target="_blank">放链接</a>。</p>
<ul>
<li>无序列表项 1</li>
<li>无序列表项 2</li>
</ul>
<ol>
<li>有序列表项 1</li>
<li>有序列表项 2</li>
</ol>
<img src="photo.jpg" alt="一张示例照片" width="300">
注意 <img> 的 alt 属性必须写:图片加载失败时显示,屏幕阅读器靠它给视障用户描述图片,搜索引擎也靠它理解图片内容。
步骤 3:语义化布局标签
把步骤 1 的 body 换成真实页面结构:
<body>
<header>
<h1>我的博客</h1>
<nav>
<a href="#home">首页</a>
<a href="#articles">文章</a>
<a href="#about">关于</a>
</nav>
</header>
<main>
<article>
<h2>我的第一篇文章</h2>
<p>发布于 2026-10-06</p>
<p>这是正文内容……</p>
</article>
<aside>
<h3>侧边栏</h3>
<p>一些推荐链接。</p>
</aside>
</main>
<footer>
<p>© 2026 我的博客</p>
</footer>
</body>
语义化标签和 <div> 渲染效果一样,但意义完全不同:搜索引擎、屏幕阅读器能读懂 <nav> 是导航、<article> 是一篇独立内容。满屏 <div> 的页面被称为「div 汤」,是初学者的典型坏味道。
步骤 4:表单
表单是网页收集用户输入的唯一方式,也是实际工作中最常用的部分:
<form action="/submit" method="post">
<div>
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required
placeholder="请输入用户名">
</div>
<div>
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" required>
</div>
<div>
<label for="pwd">密码:</label>
<input type="password" id="pwd" name="pwd" minlength="6" required>
</div>
<div>
<label for="city">城市:</label>
<select id="city" name="city">
<option value="">请选择</option>
<option value="bj">北京</option>
<option value="sh">上海</option>
</select>
</div>
<div>
<label for="bio">简介:</label>
<textarea id="bio" name="bio" rows="4"></textarea>
</div>
<div>
<input type="radio" id="m" name="gender" value="m">
<label for="m">男</label>
<input type="radio" id="f" name="gender" value="f">
<label for="f">女</label>
</div>
<button type="submit">提交</button>
</form>
关键规则:
<label>的for对应 input 的id,点击文字就能聚焦输入框name属性是提交给服务器时的字段名,没有 name 的输入不会被提交required、minlength、type="email"都是浏览器自带的免费校验
步骤 5:表格
展示结构化数据用 <table>,不要用它做页面布局:
<table border="1">
<thead>
<tr>
<th>姓名</th>
<th>科目</th>
<th>分数</th>
</tr>
</thead>
<tbody>
<tr>
<td>张三</td>
<td>数学</td>
<td>92</td>
</tr>
<tr>
<td>李四</td>
<td>数学</td>
<td>85</td>
</tr>
</tbody>
</table>
thead/tbody 分区让浏览器和搜索引擎理解表头与数据的关系;th 是表头单元格(自动加粗居中),td 是普通单元格。
讲清楚要点
- HTML 是标记语言,不是编程语言:它描述「这是什么」,不描述「怎么做」。没有变量、循环、逻辑。
- 标签成对出现:
<div>...</div>;少数自闭合:<img>、<br>、<input>、<meta>。 - 属性写在开始标签里:格式
name="value",多个属性空格分隔,值永远加双引号。 - 块级 vs 行内:
div/p/h1~h6/ul/table/form独占一行;span/a/strong/em/img/input不独占一行,宽度由内容决定。 - 语义化是专业分界线:能用
<nav>就不用<div class="nav">,这是面试和 Code Review 都会看的点。 - 浏览器极其宽容:标签写错了浏览器也会尽力渲染,所以错误经常「看起来没问题」——要用 F12 的 Elements 面板检查真实结构。
你可能会懵的地方
-
HTML、HTML5、XHTML 有什么区别? HTML5 是当前标准,新增语义化标签、原生音视频、表单校验。XHTML 是更严格的 XML 风格写法,已淘汰。学 HTML5 即可。
-
为什么我的中文显示成乱码? 两个条件必须同时满足:文件保存为 UTF-8 编码(VS Code 右下角能看到),且
<meta charset="UTF-8">写在 head 里。 -
<div>和<span>到底什么时候用? 它们是没有语义的通用容器:<div>用于块级分组(比如一张卡片),<span>用于行内局部(比如一段话里变色的几个词)。有语义标签可用时优先用语义标签。 -
表单提交后页面刷新正常吗? 正常,这是表单的默认行为。现代开发中通常用 JavaScript 拦截提交(
event.preventDefault()),改用 fetch 发请求,JS 课会讲。 -
id 和 class 有什么区别?
id全页面唯一,像身份证号;class可重复、可多个,像标签。CSS 和 JS 选元素时大量依赖 class。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
<p>文字 忘记 </p> | 嵌套错乱,后续样式全歪 | 开始标签配结束标签 |
一页多个 <h1> 当大字用 | h1 是页面主标题,应唯一 | 字号用 CSS 控制 |
<img src="a.jpg"> 不写 alt | 可访问性差,SEO 受损 | 始终写有意义的 alt |
用 <table> 做页面布局 | 历史陋习,难以维护 | 布局用 CSS flex/grid |
用 <br><br><br> 撑间距 | 滥用换行标签 | 用 CSS margin/padding |
| input 只有 id 没有 name | 提交时字段丢失 | name 是提交字段名,必须写 |
<a href=""> 空链接 | 点击刷新当前页 | 占位用 href="#" 或 button |
卡点急救
- 页面完全空白:F12 打开 Console 看报错;多半是文件没保存、路径不对,或某处标签没闭合导致解析中断。
- 中文乱码:确认
<meta charset="UTF-8">在 head 最前面,且文件本身保存为 UTF-8(VS Code 右下角可切换编码)。 - 改了代码浏览器没变化:缓存问题,Ctrl+F5(Mac:Cmd+Shift+R)强制刷新。
- 图片不显示:F12 的 Network 面板看图片请求是否 404;检查路径是相对 HTML 文件的位置。
面试常问
-
DOCTYPE 的作用? 告诉浏览器用标准模式渲染。不写会进入怪异模式(Quirks Mode),浏览器按 90 年代的非标准方式解析,盒模型等行为都不同。
-
语义化标签为什么重要? 三点:SEO(搜索引擎更好理解内容权重)、可访问性(屏幕阅读器靠语义导航)、可维护性(
<article>一看就懂,<div class="article">要靠约定)。 -
块级元素和行内元素的区别? 块级独占一行、可设宽高、默认撑满父容器;行内不独占一行、宽高由内容决定、设置宽高无效(img 等替换元素除外)。CSS 的
display属性可以互相转换。 -
label 的作用? 绑定表单控件:点击 label 文字等于点击对应输入框,扩大点击区域,同时让屏幕阅读器能读出字段含义。
自测三问
- 一个完整 HTML5 文档的顶层结构是什么?head 和 body 各放什么?
- 表单的
name、id、for三个属性分别起什么作用? - 说出至少 5 个语义化标签及其用途。
小结一句话
HTML 用标签描述网页结构——文档结构定骨架、语义标签给意义、表单表格管数据,掌握这三块就跨过了前端第一道门。
延伸
- MDN HTML 基础教程
- 下一课:CSS——给骨架穿上衣服,学会选择器、盒模型和现代布局。