第一天接触HTML,很多人第一件事就是复制一段代码粘贴到记事本里,双击打开,看到一片白底黑字,然后就开始背标签。背了两天,h1、p、img 倒是记住了,可一脱离模板就发现自己连一个空白页面都搭不利索。问题出在哪?出在你把 HTML 的“骨架”和“标签”割裂开看了。HTML 入门其实就一句话:先认骨架,再抓标签,最后拿标签去填空。这篇内容我把 Day01 的学习路线给你捋完整了,按我平时的习惯走,纯小白看完能自己手动写出一个结构干净、不乱报错的页面,写过一段时间但一直靠模板撑场面的同学,也可以借这个机会把底子补一补。
1. 先别急着背标签:HTML骨架究竟长什么样
1.1 把HTML理解成毛坯房
很多教程一上来就扔给你几十个标签,让你背,这是最劝退的学习方式。HTML 的英文全称是 HyperText Markup Language,翻译过来是“超文本标记语言”。注意,它不是编程语言,没有 if、for、变量和作用域,它做的唯一一件事就是用一堆“标签”告诉浏览器:这里是一个标题,那里是一段文字,这张图放这个位置,这个表单点一下能提交。你可以把 HTML 想成毛坯房的承重结构,CSS 是墙面、地板和瓷砖,JavaScript 才是水电和智能家居。毛坯房没砌好,后面装修再漂亮也白搭。
所以学习 HTML 的第一天,不是把所有标签都记下来,而是先把“骨架”这堵承重墙立起来。骨架不乱,标签才有地方放。
1.2 标准骨架逐行拆解
打开任意一个现代网页,右键查看源代码,你会发现最终都会落到这样一个结构上:
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>
<!-- 你写的内容将来都放在这里 -->
</body>
</html>
这段代码一共没多少行,但每一行都有讲究。
<!doctype html> 不是标签,它是文档类型声明。它告诉浏览器:“请用现代标准模式来解析我,不要用古董兼容模式。”很多老网页缺了这行,在IE里会进入怪异模式,盒模型和排版全乱。现在虽然浏览器容错能力很强,但你写标准骨架,将来排查问题会省一半力气。
<html lang="zh-cn"> 是根元素,整个页面所有标签都装在它里面。lang 属性告诉浏览器和搜索引擎,这个页面是中文内容。为什么重要?对屏幕阅读器来说,它决定用哪套语音库朗读;对搜索引擎来说,它决定收录语言。中文站点建议写成 zh-CN,英文站写 en。
<head> 是页面的“配置区”,里面写的内容不会直接显示在浏览器里,但它控制着页面编码、viewport、标题、样式和脚本。很多人忽略了 head,这是不对的,后面专门讲。
<body> 才是用户真正看到的内容区。你在浏览器里看到的所有文字、图片、按钮,全部写在 body 里面。骨架的练习,其实就是守着 head 和 body 这两个大容器,把标签分门别类放对位置。
1.3 为什么骨架顺序不能乱
有人觉得 <meta charset="utf-8"> 写在 title 后面也没事,事实是大多数情况确实能显示,但如果你在 meta 之前出现了非 ASCI 字符,或者浏览器先解析了 title 里的中文,就可能出现乱码。标准姿势是:meta charset 放在 head 最前面,紧跟其后的是 title。
viewport 这个 meta 也不可省略。它的作用是让页面按设备宽度渲染,而不是默认用 980px 的虚拟宽度。没有它,手机端打开页面会像看缩小版网页,字体小到看不清楚。所以移动端适配第一步,不是 CSS,而是先写对 viewport。
骨架顺序还可以用“先声明、后设置、再内容”来记:先 doctype 声明文档类型,再 head 设置编码和配置,最后 body 放内容。这个顺序建议你手动敲五遍,不要复制粘贴。第一遍照抄,第二遍盖住代码默写,第三遍故意删掉 doctype 或者 meta charset,然后刷新看浏览器如何表现。你会发现,只有亲手踩过坑,才真正明白那一行的价值。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. head区没你想象得简单:meta和title都得会
2.1 head区是给浏览器看的说明书
很多新手看 head 标签少,就跳过不学,这是亏的。head 相当于产品说明书,浏览器、搜索引擎、社交平台分享机器人都在读它。你辛辛苦苦写了一个页面,想分享到微信或微博,结果缩略图不显示、标题乱码、描述是乱的,大概率就是 head 没写对。
head 里面常用的标签包括:title、meta、link、style、script、base。第一天不需要全部掌握,但 title、meta、link、style、script 这五个必须认识,因为几乎每个页面都会用到。
2.2 meta标签:除了charset还要会这几个
meta 是一个“自我描述”标签,通过 name 加 content 的形式给页面附加信息。我不建议你背所有 meta,但下面这张表里的,是实际开发中高频出现的。
| 写法 | 作用 |
|---|---|
<meta charset="utf-8"> |
声明文档编码,防乱码 |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
移动端适配,按设备宽度渲染 |
<meta name="description" content="页面描述"> |
搜索结果显示的摘要,控制好对点击率有帮助 |
<meta name="keywords" content="关键词1,关键词2"> |
老式SEO控制项,现在搜索引擎权重很低 |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
让IE用最新内核渲染,已逐步被淘汰 |
<meta property="og:title" content="分享标题"> |
社交平台分享时使用的标题,Open Graph协议 |
viewport 建议直接复制标准写法,不要自己乱改。description 要写成一句完整的人话,比如“HTML入门教程,从骨架到标签全掌握”,不要堆关键词。keywords 现在基本可以不写,把精力放在内容和 title 上更值得。
2.3 title、link、style、script的正确摆放姿势
title 是整个页面里 SEO 权重最高的标签,内容会直接出现在浏览器标签页和搜索结果里。它的格式建议是“页面核心关键词——网站名称”,不要写一个孤零零的“首页”。如果一个页面标题都没有,搜索引擎很难判断页面价值。
link 标签最常用的是引入外部 CSS:
html复制<link rel="stylesheet" href="css/style.css">
rel 属性必须写成 stylesheet,这是链接和引入文档的关系声明,漏了样式会挂不上。href 路径写错了,页面就是纯裸奔状态。
style 标签适合写在 head 里,给当前页面写少量独立样式。新手经常犯的错是把 style 写在 body 里,或者写在外部 CSS 文件里却用了 <style> 包裹,这两种都会导致样式异常。
script 标签的位置是重灾区。传统做法是把 JS 放在 body 最底部,因为浏览器解析 HTML 是自上而下的,JS 执行时如果上面的 DOM 还没生成,就会拿到空对象。现代方案可以给 script 加 defer 属性,让脚本在文档解析完成后再执行,这样就能继续放在 head 里了:
html复制<script src="js/app.js" defer></script>
但第一天我不建议你追求太复杂,记住“CSS 进 head,JS 出 body 或加 defer”,就已经超过很多人了。
3. 正文区标签分类:把散装的HTML标签装进抽屉
3.1 文本和段落标签这么用才对
body 里的标签最容易学混。我习惯把它们按功能分类,第一类是文本与段落。
html复制<h1>一级标题:页面核心主题</h1>
<h2>二级标题:章节标题</h2>
<h3>三级标题:小节标题</h3>
<p>这是一个段落,段落和段落之间默认有间距,不要用换行代替。</p>
<p>这是第二个段落。</p>
<br>
<strong>加粗,表示内容很重要</strong>
<em>斜体,表示语气强调</em>
<span>一个普通的行内容器</span>
<hr>
h1 到 h6 是标题,层级关系要清晰。一个页面建议只写一个 h1,它通常给站点名或页面核心标题用,h2 往下可以无数个。很多人为了字体大小用 h1 到 h6,这是错误用法。标题字号是 CSS 的活,标签语义归 HTML 管。
p 是段落,它里面不要再嵌套 div、p 这类块级元素。段落之间请用 p 标签本身提供的间距,不要连写一堆 <br>。br 是强制换行,语义上通常用在地址、诗歌等需要明确换行的场景。hr 是主题分隔线,表示前后内容主题切换,不是用来画一条装饰线的。
strong 和 em 是带语义的强调,浏览器默认显示加粗和斜体。而 b 和 i 只是纯视觉样式,不带任何强调含义。后续你会发现,能用 strong 的地方不要用 b,能语义化就语义化。
文本里还有一些特殊字符需要转义,比如连续空格用 ,< 写 <,> 写 >,版权符号 © 写 ©。直接在 HTML 里写 < 可能会被浏览器当成标签开始符,导致解析错乱。
3.2 列表标签:不只是条目前面的圆点
列表是页面里太常见的内容。无序列表 ul 里放 li,适合导航、商品列表;有序列表 ol 里放 li,适合步骤、排行榜;dl/dt/dd 是自定义列表,适合术语和描述。
html复制<ul>
<li>苹果</li>
<li>香蕉</li>
</ul>
<ol start="5">
<li>第一步:打开电脑</li>
<li>第二步:新建文件</li>
</ol>
<dl>
<dt>HTML</dt>
<dd>超文本标记语言,负责页面结构。</dd>
</dl>
ol 的 start 属性可以让序号从指定数字开始;type 属性可以切换数字、字母、罗马数字,但实际场景中用得不多,更多靠 CSS 的 list-style-type 控制。
列表嵌套要注意,ul 的直接子元素必须是 li,不能是其他标签。如果要做多级菜单,正确写法是 li 里面再套一个 ul:
html复制<ul>
<li>
一级菜单
<ul>
<li>二级菜单</li>
</ul>
</li>
</ul>
这个看起来简单,但新手经常写错成 ul 直接套 ul,浏览器不报错,但语义是错的。
3.3 图片和链接:两个高频“翻车点”
img 标签是第一天就必须掌握的,因为它太常用了。核心属性是 src 和 alt。
html复制<img src="images/photo.jpg" alt="一张说明图" width="400">
src 是图片路径,建议用相对路径而不是 file:///C:/... 这种本地绝对路径。alt 是图片无法显示时的替代文字,也是无障碍访问和 SEO 的重要一环。如果图片只是装饰,alt 可以留空字符串 alt="",但不要不写。图片默认是内联替换元素,宽度和高度可以用属性写,但正式项目里通常用 CSS 控制。
图片加载失败是高频问题。一个稳妥的兜底方案是用 onerror 给 img 换一张默认图:
html复制<img src="images/goods.png" alt="商品图"
onerror="this.onerror=null; this.src='images/default.png';">
this.onerror=null 这行一定要写。不然默认图也加载失败时,会再次触发 onerror,死循环刷请求。
超链接 a 标签同样高频。href 是跳转地址,target 控制打开方式。target="_blank" 的意思是新开一个标签页,但会带来一个反向的 tabnabbing 安全风险,所以最好再加上 rel:
html复制<a href="https://example.com" target="_blank" rel="noopener noreferrer">外部链接</a>
页内锚点跳转也是常见需求,比如“一键返回顶部”,可以先给顶部元素加 id,再用 a 链接过去:
html复制<body id="top">
<!-- 页面内容 -->
<a href="#top">返回顶部</a>
<!-- 或用 JS:window.scrollTo({ top: 0, behavior: 'smooth' }) -->
href="#top" 的写法依赖 id 属性,自己试一次就会明白,比直接翻几十行 JS 简单得多。
3.4 不想整天写div,先认识这几个语义化标签
新手写页面容易一个 div 套到底,这也不能说错,但会让 HTML 失去语义。header、nav、main、section、article、footer 这些语义化标签,相当于给浏览器和搜索引擎划出了页面区域。
html复制<header>页面顶部</header>
<nav>主导航</nav>
<main>
<article>
<h2>文章标题</h2>
<section>
<h3>小节标题</h3>
<p>内容</p>
</section>
</article>
<aside>侧边栏</aside>
</main>
<footer>页脚信息</footer>
header 可以在页面里出现多次,文章头部、评论区头部都算。main 一个页面只能有一个,放主体内容。section 一般里面要有标题。article 适合能独立成篇的内容,比如博客正文、评论。footer 也允许出现多次。
用语义化标签最大的收益是维护成本变低。三个月后你回头改代码,看到 <main> 就知道这是主内容区,不用再费劲 class 命名。
4. 表格和表单:工作中最逃不掉的复合标签
4.1 表格想写对,先从“行”想,而不是“列”
表格是 HTML 里最容易让人晕的标签,因为它是二维的。新手写表格喜欢一列一列地加,但 HTML 表格的规则是“先有行,后有列”,一行 tr,再在行里放 td 或 th。
html复制<table>
<caption>课程表</caption>
<thead>
<tr>
<th>时间</th>
<th>周一</th>
<th>周二</th>
</tr>
</thead>
<tbody>
<tr>
<td>上午</td>
<td colspan="2">公共课</td>
</tr>
<tr>
<td rowspan="2">下午</td>
<td>CSS</td>
<td>JS</td>
</tr>
<tr>
<td>HTML</td>
<td>休息</td>
</tr>
</tbody>
</table>
thead 放表头,tbody 放数据行,tfoot 放汇总。即使结构简单,也建议写上 thead 和 tbody,方便样式控制和屏幕阅读器理解。
colspan 是横向合并单元格,取值是占几列。rowspan 是纵向合并,取值是占几行。合并这个只能多练,我的心得是:先在脑子里把表格画成网格,给每个单元格编号,再合并。否则经常出现“一个格消失了,整行对不齐”的场面。
表格默认没有边框,平时看到的边框都是 CSS 加的。第一天只需要知道 border-collapse: collapse 是用来合并相邻边框的。如果表格太宽,在移动端会撑破页面,外包一层 div 加 overflow-x: auto 是最快的响应式方案。
4.2 表单的核心是收集数据:form和input的配合
表单是前端里“交互感”最强的部分。form 标签负责划定提交区域,action 是提交地址,method 是提交方式。GET 适合搜索类请求,参数会拼在 URL 上;POST 适合提交数据,参数在请求体里。
html复制<form action="/submit" method="post">
<label for="username">用户名</label>
<input type="text" id="username" name="username" required>
<label for="pwd">密码</label>
<input type="password" id="pwd" name="pwd">
<label><input type="radio" name="sex" value="male"> 男</label>
<label><input type="radio" name="sex" value="female"> 女</label>
<select name="city" id="city">
<option value="bj">北京</option>
<option value="sh">上海</option>
</select>
<textarea name="intro" rows="3"></textarea>
<button type="submit">提交</button>
</form>
input 的 type 有很多种:text 是普通文本,password 会掩码,email 会做格式校验,number 只能输数字,checkbox 是复选框,radio 是单选,file 是文件上传。新手先把这几个吃透,剩下的遇到再查。
name 属性特别关键,它决定了提交到后台时,这个字段叫什么名字。没有 name 的 input,后台根本收不到数据。value 是默认值,placeholder 是输入提示。required 表示必填,配合 HTML5 校验能在提交前先拦一道,但服务端校验永远不能省。
4.3 label标签为什么是所有表单的“隐藏功臣”
label 是我见过最被低估的表单标签。它的作用是把一段文字和某个输入控件绑定。写好了,用户点击“用户名”三个字,光标会自动跳到输入框,移动端尤为明显,手指不用再精准点那个小框。
绑定方式有两种。第一种是 for 属性指向 input 的 id:
html复制<label for="username">用户名</label>
<input type="text" id="username" name="username">
第二种是把 input 直接放进 label 里:
html复制<label>
<input type="checkbox" name="agree"> 同意用户协议
</label>
我个人习惯推荐第二种,因为少一对 id 对应关系,结构性更强,不容易写错。但页面里有多个单选框时,第一种更清晰。label 对屏幕阅读器也友好,读屏软件会完整读出“用户名 编辑框”,而不是只读控件类型。
4.4 其他需要认识的复合标签:progress和details
第一天不必全学,但可以认识几个有意思的复合标签,开阔眼界。progress 用来显示进度条,value 是当前值,max 是最大值。details 和 summary 可以做原生折叠面板,不用写一行 JS:
html复制<details>
<summary>更多说明</summary>
<p>这里的内容默认隐藏,点击“更多说明”才会展开。</p>
</details>
这些标签解决了常见的交互需求,而且自带语义和键盘支持。遇到类似场景,先想想有没有原生标签能用,不要急着用 div 加 JS 硬造轮子。
5. 第一天最容易踩的坑:问题排查与避坑技巧
5.1 HTML文件双不开或者无法预览
新手最常见的报错是“我写好了 HTML,双击打开却是一片空白,或者直接跳到了文本编辑器”。先检查文件后缀名,Windows 默认可能隐藏扩展名,你写的是 index.html.txt,浏览器打开自然只显示源码。解决方法:在资源管理器里把“查看 - 文件扩展名”打开,改成 .html。
如果文件后缀没问题,但双击后默认用编辑器打开了,可以右键选择“打开方式”,然后选 Chrome、Edge 或 Firefox。路径里有中文和空格一般也能打开,但如果出现编码问题,建议养成规范文件名:全小写英文,单词之间用连字符,比如 my-first-page.html。这不仅是浏览器兼容问题,后面部署上线,文件名规范能省掉一箩筐 404。
VS Code 里可以用 Live Server 插件做实时预览,但第一天建议还是先习惯直接双击打开 HTML 文件,因为这样才能体会到“写代码 - 刷新 - 看结果”的原生反馈。
5.2 中文乱码
乱码的原因九成是“文档声明编码”和“文件实际保存编码”不一致。你在 head 里写了 <meta charset="utf-8">,但文件是用记事本默认 ANSI(GBK)保存的,浏览器按 UTF-8 解码就会乱。
处理方式有两种:记事本另存为时,把窗口底部编码选成 UTF-8;VS Code 则看右下角 “UTF-8” 字样,点击后选择“通过编码保存”,再选 UTF-8。改完保存刷新,乱码一般就没了。
另一个容易忽略的细节是,meta charset 一定要放在 head 的最靠前位置,最好就在 title 前面。如果放在 title 后面,浏览器在解析到 meta 之前可能已经用临时编码处理了 title 里的中文,也可能出问题。
5.3 图片不显示
先说最常见的现象:页面中图片图标是一个小裂口。打开浏览器开发者工具(F12),切到 Network 面板,清空后刷新,找到图片请求,看状态码:
| 状态码 | 含义 | 排查方向 |
|---|---|---|
| 404 | 资源不存在 | 文件路径、文件名、后缀 |
| 403 | 没有权限 | 服务器或本地文件权限,本地通常少见 |
| 200 | 请求成功 | 如果200但图裂,可能是图片本身坏了 |
| 失败 | 请求没发出 | html路径和文件名大小写,不要在路径中用特殊符号 |
路径是最大的坑。src="images/pic.jpg" 是相对当前 HTML 文件所在目录去找。如果 HTML 在根目录,图片在 images 文件夹下,这样写没问题。如果 HTML 也在子目录里,路径可能就错了。一个快速自测方法:直接在浏览器地址栏输入图片路径,比如 file:///C:/myproject/images/pic.jpg,能打开说明路径存在,打不开说明位置或名称不对。
还有一种情况是图片格式太老,比如 .webp 在某些老旧浏览器不支持,这时可以用 picture 标签提供多格式图片。但 Day01 先别深入,把 path 和 alt 搞明白,就解决了一半问题。
5.4 样式不生效和标签错位
样式不生效,先看有没有引入 CSS 文件,再看 rel 是不是 stylesheet,再看路径,最后刷新。新手经常改完 HTML,CSS 还是旧缓存,按 Ctrl+F5 强制刷新试试。
标签错位更隐蔽。比如写了 <p> 忘记闭合,浏览器会自动把后续内容都当段落处理。这时用开发者工具的 Elements 面板看标签树,通常能发现多了一个莫名其妙的闭合标签。养成习惯:所有标签写完立刻闭合,比如 <strong></strong>,而不是等整段写完再补。
块级元素和行内元素是第一个要分清的。div、p、h1、ul 是块级,默认占满一行,可以设置宽高。span、a、strong、em 是行内,不会换行,设置宽高无效。把块级元素放进 p 里,是 HTML5 规范明确不允许的,因为 p 只能包含短语内容。把 div 直接放进 p 里,浏览器解析时会把 p 断开,导致结构错乱。
5.5 常见嵌套错误的速查表
| 错误写法 | 问题 | 正确做法 |
|---|---|---|
<ul><div>...</div></ul> |
ul直接子级不是li | <ul><li><div>...</div></li></ul> |
<p><div>内容</div></p> |
p里不能放div | 用div代替p,或把div放p外面 |
<a href="#">...</a><a href="#">...</a> 互相嵌套 |
a不能嵌套a | 拆开或用span包裹再绑定事件 |
<form>...</form><form>...</form> 嵌套 |
form不能嵌套form | 拆成多个表单,或用fieldset分块 |
<button><button>提交</button></button> |
button不能嵌套button | 换一个按钮用a或span样式代替 |
这些错误在浏览器里不一定有明显提示,但会让页面结构不可预测。遇到样式诡异、点击错位、布局跳变,先怀疑标签嵌套,用开发者工具把层级逐个展开看一遍,往往比乱改 CSS 有用得多。
我把这些话放在最后说,是因为这些确实是我第一天学 HTML 时踩过、也看着无数人踩过的坑。我刚开始也是复制别人的模板,标签抄了一遍又一遍,真正让我记住骨架的,不是背,而是故意把 do type 删掉、把 meta charset 调换位置、把 div 塞进 p 里,然后打开浏览器看它怎么“将错就错”。如果你今天能把骨架手动敲五遍,每个标签改一改再刷新看看,那这第一课就算真正完成了。下一篇我会接着聊 CSS,但在此之前,请先做一个练习:新建一个页面,用 h1 写标题,p 写两段自我介绍,img 放一张图,a 链接到一个页面,再用表格排一个时间表。做完再往下走,比看十遍教程都有用。
