我见过不少刚接触前端的朋友,拿到一个 HTML 文件后第一反应是去背标签、抄代码,结果写了半天,页面上的文字还是挤成一团,加粗不生效、引用没有缩进、代码块直接糊掉,根本分不清到底是哪里写错了。其实 HTML 的样式和格式化基础远没有想象中那么玄,它要解决的就三件事:文本怎么排版、计算机输出怎么展示、引用内容怎么分层。把这套规则吃透,后面再学 CSS 才会真正顺畅。
这篇内容适合刚入门 HTML 的读者,也适合那些能写出页面但标签用得比较随意、想补齐语义化功底的人。我会从页面骨架讲起,把文本格式化、计算机输出、引用这三组核心标签逐个拆开,再补上样式挂载和实操避坑。每一步都会解释为什么这样做,而不是只丢一串标签让你抄。
1. 动手前先搭好页面骨架:DOCTYPE、字符集与文件预览
很多初学者直接新建一个记事本就开始写标签,写完保存成 .html 文件,双击打开却发现乱码,或者样式怪怪的。问题往往不在标签本身,而是页面骨架没搭对。一个规范的 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>
<!-- 页面内容写在这里 -->
</body>
</html>
我曾经辅导过一批零基础学员,发现大家踩得最集中的坑有两个:一是把 <!DOCTYPE html> 漏掉或写错,二是 meta charset 没写或者放在了错误位置。DOCTYPE 的作用是告诉浏览器“我这是一个标准 HTML 文档”,没有它,浏览器会进入怪异模式,很多标签的默认样式就跟你想的不一样,比如盒模型计算方式、行高、字体大小都可能出现偏差。所以别嫌它啰嗦,每一行都有存在的理由。
lang="zh-CN" 是给浏览器和搜索引擎看的,声明页面内容以简体中文为主。它对页面视觉没有直接影响,但对无障碍阅读和 SEO 有帮助。至于 meta charset="UTF-8",那是防乱码的第一道防线。文件保存的编码格式和浏览器解析的编码格式必须一致,否则中文就会变成一堆看不懂的符号。用 VS Code 这类现代编辑器默认保存 UTF-8,但如果你用 Windows 自带记事本保存,偶尔会遇到编码不一致的问题。确认文件编码的最简单方法是在编辑器右下角看编码信息,确保是 UTF-8。
再来说说“HTML 文件无法预览”这个高频问题。严格说,HTML 文件是本地静态文件,用浏览器双击打开就能运行。如果你双击后打开的是一片空白,或者页面显示的是源代码,通常是下面几种情况之一:
- 文件扩展名是
.txt而不是.html,系统还把它当纯文本打开; - 浏览器默认程序被篡改,右键文件选“打开方式”,手动指定 Chrome、Edge 或 Firefox 即可;
- 文件名包含特殊字符或中文路径极长,偶尔会导致资源加载异常,改成英文文件名试试。
提示:写 HTML 不必每次都从
<!DOCTYPE html>手敲,在 VS Code 里新建一个.html文件,输入英文感叹号!后按 Tab 键,就能自动生成标准骨架。强烈建议一开始就使用这个方式,减少手打造成的低级错误。
如果你只是临时写一个很小的测试页面,跳出骨架直接用浏览器打开也能显示内容,但我不建议养成这种习惯。骨架就像房子的地基,早期嫌麻烦省掉的步骤,后面都会以更麻烦的方式回来找你。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 文本格式化标签逐个拆解:别把加粗和强调混为一谈
文本格式化是 HTML 中最日常、也是被误解最多的部分。很多新手以为格式化就是“让文字变好看”,于是看到加粗标签就往里套,结果页面充斥着结构混乱的 <b> 和 <i>,不仅样式失控,还让搜索引擎抓取不到内容的重点。正确的思路是:格式化标签分为纯样式标签和语义化标签两类,它们在默认视觉效果上可能相同,但表达的含义完全不同。
2.1 粗体与斜体:strong 与 b、em 与 i 的本质区别
先看最常用的加粗和斜体。<b> 标签只是让文字显示为粗体,不附加任何语气或重要性。而 <strong> 表示内容本身很重要,浏览器默认把强调内容显示成粗体,但它的语义是“重点”,不是“加粗”。同理,<i> 用于呈现斜体外观,比如书名、术语、外语短语;<em> 则表达语气上的强调,屏幕阅读器会加重读音。这两组标签的对应关系可以看下面的表:
| 标签 | 默认效果 | 语义含义 | 推荐场景示例 |
|---|---|---|---|
<b> |
粗体 | 无额外语义 | 文章摘要中的关键词加粗 |
<strong> |
粗体 | 内容很重要 | 警告信息、关键结论 |
<i> |
斜体 | 无额外语义 | 书名、船名、专业术语 |
<em> |
斜体 | 语气强烈 | 需要重读的字词 |
举一个实际例子。电商商品页里,“限时特惠”这种强调促销氛围的文字应该用 <strong> 吗?我认为不合适。促销提示的“限时”如果只是为了视觉上突出,用 <b> 就够了;如果这句话本身是价格变动的重要提示,要用 <strong> 让辅助设备读出来。同一个页面里 <b> 和 <strong> 可以共存,关键看你的意图是“看起来粗”还是“真的很重要”。
2.2 上标、下标、删除线与插入文本:理工科和文档场景的硬需求
文字格式化不只是加粗和斜体,还有一组很容易被忽略但非常实用的标签:<sub>(下标)、<sup>(上标)、<del>(删除线)和 <ins>(插入文本)。它们的典型应用场景是数学公式、化学式、版本修订记录。比如水的化学式,要写成 H₂O,就得用 <sub>:H<sub>2</sub>O,而不是直接在图片里画一个下标。平方米写成 m²,用 <sup>:m<sup>2</sup>。上标还能用来做脚注引用,比如“根据调研数据¹”里的“1”就是 <sup>1</sup>。
<del> 和 <ins> 经常成对出现在文档版本对比场景。<del> 表示删除的内容,默认加删除线;<ins> 表示新插入的内容,默认有下划线。很多人会用 <s> 或给 CSS 加 text-decoration: line-through 来模拟删除线,效果上差不多,但如果是编辑记录、价格对比这种“需要表达修改语义”的场景,用 <del> 更符合语义。
html复制<p>现价:<del>¥199</del> <ins>¥129</ins></p>
2.3 小号文本与高亮标记:small 和 mark 的实际用法
<small> 标签用于表示“附属细则”,比如免责声明、版权信息、法律条款,浏览器默认渲染成小一号的文字。注意,它是语义上的“次要信息”,不是单纯的字体缩小工具。如果你只是希望某段文字变小,更应该用 CSS 的 font-size 控制,而不是滥用 <small>。
<mark> 负责高亮标记,默认显示黄色背景。它在文档中表示“与当前上下文相关的内容”,比如搜索结果页面里,用户输入的关键词就可以用 <mark> 包起来。很多人第一反应是用 <span style="background-color: yellow;"> 实现同样的视觉效果,这也能跑,但用 <mark> 的额外价值是语义更清晰,后续如果要给所有高亮词统一换样式,直接写 mark { background-color: pink; } 就能一次性搞定。
这些标签看起来简单,实际组合使用时很容易出现嵌套过深的问题。比如有人写出 <strong><em><mark>重要又需要高亮的关键词</mark></em></strong>,浏览器能正常解析,但三层语义叠在一起,阅读和后续维护都困难。我的建议是,一层内容只表达一个核心语义,需要多重强调时优先考虑用 CSS 来控制额外的视觉样式,而不是继续套标签。
3. 计算机输出与代码展示:code、kbd、samp、var、pre 的正确搭配
网页上展示代码是开发者绕不开的场景,但很多人只会用一个 <pre> 标签包住代码,或者干脆把代码粘到 <p> 段落里,最终显示效果七零八落。HTML 其实为计算机输出准备了一整套专用标签,它们分别是 <code>、<kbd>、<samp>、<var> 和 <pre>,每一个都有明确的语义和适用场景。
3.1 单行代码用 code,别忘了转义尖括号
<code> 用来标记一段计算机代码。它默认以等宽字体显示,比如输入一个函数名 console.log,就写成 <code>console.log</code>。但这里有一个非常关键的坑:如果代码里包含尖括号 < 和 >,必须转义成 < 和 >,否则浏览器会把它当成真正的标签解析。
比如你想展示 <div> 这个标签本身:
html复制<p>请使用 <code><div></code> 标签来划分区块。</p>
如果不转义,直接写 <code><div></code>,浏览器会认为这是真的 div 标签开始,页面结构直接被打乱。这个错误对新手来说几乎是必踩的,后面我会在避坑章节继续展开。
3.2 多行代码块用 pre + code 组合
<pre> 标签的作用是保留代码中的空格和换行,这是它和普通段落最大的区别。但是 <pre> 默认字体并不是等宽字体,而且它也不会帮你处理代码高亮。所以最规范的做法是把 <pre> 和 <code> 组合起来:外层用 <pre> 保留格式,内层用 <code> 表示语义。
html复制<pre><code>function greet(name) {
return "Hello, " + name;
}</code></pre>
有人会问,为什么不直接给 <pre> 加个 CSS 类?从视觉效果上完全可行,但 <pre><code> 组合能让屏幕阅读器和代码提取工具更准确地识别“这是一段代码”。很多 Markdown 渲染器最终输出的 HTML 也是 <pre><code class="language-html"> 这种结构,说明这种嵌套方式已经成为事实标准。
3.3 kbd、samp、var:键盘按键、程序输出和变量标识
网页如果涉及操作文档,比如教用户“按 Ctrl+S 保存”,你当然可以直接写“Ctrl+S”,但更语义化的写法是用 <kbd> 包住按键名:<kbd>Ctrl</kbd> + <kbd>S</kbd>。默认样式下它会以等宽字体、略微加深的背景显示,一眼就能看出这是一个按键。有些网站还会给 <kbd> 加圆角、阴影,模拟真实键盘的视觉效果,这也是从语义标签出发扩展样式的典型例子。
<samp> 用来表示程序或系统的输出内容。比如命令行教程里,提示用户输入 ls -la 后,终端会输出一串文件列表,这串输出就可以用 <samp> 包裹:
html复制<p>运行 <code>ls -la</code> 后,系统输出:</p>
<samp>drwxr-xr-x 5 user staff 160 Dec 12 10:30 project</samp>
<var> 用于标记变量名,默认斜体显示。在介绍算法或公式时,比如“设 <var>x</var> 等于 5”,用 <var> 比直接用 <i> 更合适,因为它在语义上明确告诉浏览器这是一个变量。
这组标签最容易出错的地方是滥用 <pre>。有人会把整个页面所有代码都塞进一个 <pre> 里,结果页面又长又难滚动。正确的思路是:单行代码用 <code>,多行代码块用 <pre><code>,程序输出用 <samp>,按键名称用 <kbd>。这样页面结构清晰,也方便后续用 CSS 对不同元素做差异化样式。
4. 引用体系的完整用法:从短引用到长引用
引用是网页内容里非常常见但又最容易被忽视语义的部分。很多人引用别人文章时,就是把文字加个引号或缩进完事。HTML 为引用场景提供了 <blockquote>、<q>、<cite>、<abbr>、<address>、<bdo> 这组标签,从长引用到短引用,再到引用来源、缩写词、地址和文字方向,各司其职。
4.1 blockquote 长引用与 cite 来源标注
<blockquote> 用于引用一整段的文字,默认样式是缩进。它有一个 cite 属性可以用来填来源 URL,但注意这个属性只是元数据,不会在页面上直接显示出来,要显示来源文字必须自己写内容。比如:
html复制<blockquote cite="https://example.com/article">
<p>真正的发现之旅不在于寻找新风景,而在于拥有新的眼光。</p>
</blockquote>
<p>——出自《追忆似水年华》</p>
如果引用内容里包含多个段落,可以在 <blockquote> 里嵌套多个 <p>。另外,<blockquote> 不能用来缩进普通文字,如果你只是想让文字右边空出来,应该用 CSS margin,而不是拿引用标签硬撑。
4.2 q 短引用与浏览器自动加的引号
<q> 用于短的引用,比如一句话中引用别人的话。浏览器默认会为它添加引号,你不用手动输入。举个例子:
html复制<p>他说:<q>我今天一定会完成任务</q>,然后他真的做到了。</p>
在中文环境下,浏览器默认给 <q> 加的可能是英文引号,不同浏览器表现不一致。如果对引号样式有严格的中文排版要求,常常需要配合 CSS 的 quotes 属性手动指定。这也是一个坑:页面在 Chrome 上显示正常,到 Firefox 或 Safari 上引号样式却有细微差别。
4.3 address、abbr、bdo:三个容易被忽略的引用相关标签
<address> 专门用来标记联系信息,包括作者、组织、联系方式。它默认显示为斜体,但不能想当然地用它来写任何地址——只有“文档或文章作者的联络信息”才适合用。一个常见错误是拿 <address> 去写公司官网的办公地址,这在语义上并不准确,公司介绍页面里的地址用普通段落或 <p> 更合适。
<abbr> 用来标记缩写,比如“HTML”是“HyperText Markup Language”的缩写。写法是 <abbr title="HyperText Markup Language">HTML</abbr>。鼠标悬停时会显示完整名称,对阅读者和搜索引擎都友好。注意 title 属性首次显示时会有延迟,这属于浏览器原生行为,不推荐为了加速提示而用 JavaScript 模拟,容易造成无障碍问题。
<bdo> 用于覆盖文字方向。比如阿拉伯语、希伯来语这类从右向左书写的语言,可以用 <bdo dir="rtl"> 来设置。这个标签日常用到不多,但如果你在做多语言页面或引入外语文案,知道它的存在能少走弯路。
引用体系的标签虽然各自独立,组合起来就是一个完整的“出处”生态:引用来源用 cite 属性标识 URL,引用来源的名称用 <cite> 标签展示,如果引用的内容涉及缩写词,顺手用 <abbr> 标注全称。这样一套下来,文章的可信度和可读性都会明显提升。
5. 把这些格式化标签接到样式上:浏览器默认样式与自定义样式的博弈
学完格式化标签,很多人会有一个疑问:既然 <strong> 默认就是粗体,那我还要 CSS 干什么?这是一个需要马上纠正的认知。HTML 标签负责结构和语义,CSS 负责最终呈现。浏览器为每个标签设计的默认样式,只是“在没有 CSS 时的保底方案”,不是 HTML 的终极形态。
5.1 浏览器默认样式从哪来
你有没有想过,为什么 <h1> 比 <h2> 大,为什么 <ul> 前面有圆点?这些规则来自浏览器内置的默认样式表(User Agent Stylesheet)。以 Chrome 为例,它在渲染没有 CSS 的页面时,会套用一套名为 html.css 的内部样式规则。这套规则保证了即使作者完全不写样式,页面也能基本可读。
不同浏览器的默认样式存在细微差异,比如 <h1> 的上下边距、<blockquote> 的左右缩进值都可能不一样。这也是你可能听说过“CSS 复位”或“CSS reset”的原因——开发者为了让页面在不同浏览器下表现一致,会先把所有元素的默认 margin、padding 归零,再重新定义。理解了这一点,你就明白为什么同样一段 HTML,换个浏览器显示效果就变了。
5.2 内联样式、class 与 id,怎么选
把样式应用到 HTML 元素上有三种基本方式:内联样式、内部样式表和外部样式表。内联样式就是直接写在标签的 style 属性里:
html复制<p style="color: red; font-size: 18px;">这是一段红色文字</p>
这种方式最直接,但可维护性很差。如果一个页面里有 20 处文字都要改成红色,你就要改 20 个地方。所以我通常建议,内联样式只用于临时调试,或者用于邮件模板这类无法加载外部 CSS 的场景。日常开发应该把样式集中到 <style> 标签里,或独立的 .css 文件里。
在 CSS 中选择目标元素时,id 和 class 是最重要的两个钩子。id 在一个页面里只能出现一次,class 可以复用多个。可以用一个生活类比来理解:id 是你的身份证号,class 是你的职业身份,比如“程序员”“教练”可以被很多人共享。实际开发中,优先用 class 做样式,id 更多留给 JavaScript 操作或锚点定位。
5.3 覆盖默认样式时,别和“样式名已被使用或保留为内置样式”这类报错纠缠
在富文本编辑器或低代码平台里,有时会碰到“样式名已被使用或保留为内置样式”之类的提示。这通常不是 HTML 的问题,而是平台对样式的命名做了保留限制,比如不允许你用 body、head、html 这样的内置标签名作为自定义样式名。遇到这种提示,最简单的处理是换一个更具体的命名,比如 article-body、header-box,而不是强行用保留名,不然越改越乱,白白浪费时间。
在自定义样式时,我还建议遵循 BEM 这类命名规范,比如 .card__title、.card__desc。这套命名方式不是为了好看,而是为了让类名的语义清晰、层级明确,后续维护时不用靠猜。
5.4 动态样式与样式穿透的延伸思考
热搜词里经常出现“动态样式”和“样式穿透未生效”,这其实是 CSS 预处理器和组件化框架中的话题。在组件化开发里,比如 Vue 或 React 的单文件组件,为了避免样式互相污染,会给样式自动添加一个作用域标记,而“样式穿透”就是在这种约束下强行让内部组件应用外部样式的做法。
但要注意,这些都属于进阶话题。如果你还在 HTML 基础阶段,看到一个带 lang="zh-CN" 的骨架就以为自己已经落后于时代,完全没必要。先搞清楚基础标签和选择器优先级,再谈框架级样式方案,顺序才正确。特别是选择器优先级,优先级从高到低大致是:内联样式 > id 选择器 > class 选择器 > 标签选择器,!important 更是能打破一切规则。这个知识点我见过太多人栽跟头,但把它记牢之后,大部分样式覆盖问题都能在 10 秒内定位。
6. 格式化实操中容易踩的坑:HTML 实体、嵌套错误与编辑器格式化
最后一个部分,我想集中讲一讲我在实际教学和项目里反复遇到的几个坑。这些坑单独看都不大,但一旦踩中,排查起来特别费时间。很多初学者因为这些小问题,误以为自己“不是学编程的料”,其实只是缺少经验。如果你能把这一节的内容提前消化,后面的学习会顺畅很多。
6.1 HTML 实体转义:尖括号、引号和 & 符号
前面已经提到了 < 和 > 要转义成 < 和 >。完整地看,HTML 中有几个字符需要特别注意:
| 字符 | 实体写法 | 说明 |
|---|---|---|
< |
< |
小于号,必须转义 |
> |
> |
大于号,不一定必须转义,但建议转义 |
& |
& |
和号,必须转义,否则可能被解读为实体开始 |
" |
" |
双引号,在属性值中应转义 |
' |
' |
单引号,在属性值中应转义 |
最常见的错误是把 & 忘了转义。比如你要写 Tom & Jerry,如果不转义成 Tom & Jerry,在某些上下文中浏览器会尝试把 & 后面的内容解析为实体,导致显示异常。字符串拼接动态生成 HTML 时尤其容易踩这个坑。
6.2 标签嵌套与语义错误:块级元素和行内元素的边界
HTML 元素大体上分块级元素和行内元素两类。块级元素(如 <div>、<p>、<blockquote>)独占一行,宽度默认撑满父容器;行内元素(如 <span>、<a>、<code>、<strong>)不会换行,宽度由内容决定。比较经典的错误是:
html复制<p>
<div>这样写不合法</div>
</p>
<p> 标签内不能嵌套块级元素,因为 <p> 默认只能容纳行内内容。浏览器在解析时会自动把 <p> 截断,造成 DOM 结构错乱。还有一条规则是标题标签 <h1> 到 <h6> 内部不应该再套标题,行内元素不能包块级元素,这些都属于 HTML 规范的基础约束。
我见过一个比较隐蔽的错误是列表嵌套。有人写:
html复制<ul>
<li>项目一</li>
<li>项目二</li>
<ul>
<li>子项目</li>
</ul>
</ul>
这看起来合理,但实际上子列表没有放在 <li> 内部,浏览器解析时会自动纠正,但渲染结果可能不是你预期的。正确的写法是把子列表放在父子项 <li> 的内部:
html复制<ul>
<li>项目一</li>
<li>项目二
<ul>
<li>子项目</li>
</ul>
</li>
</ul>
6.3 VS Code 格式化为什么定位到页面最后
很多人在 VS Code 里写完 HTML,按保存或快捷键触发格式化,光标会突然跳到文件末尾。这个现象我初学时也疑惑过,后来搞明白了:这不是格式化坏了,而是格式化插件当前的设置在“格式化整个文档”时,会把文档重新解析一遍,如果文档中存在未闭合标签或语法错误,解析器自动修正后的内容会使得光标位置丢失,最终落在文档尾部。换句话说,与其纠结编辑器,不如先检查一下 HTML 结构有没有标签未闭合、属性值缺引号、注释未结束之类的问题。
如果这个行为频繁出现,可以试试右键选择“格式化所选内容”,只格式化一段代码,光标跳转的概率会小很多。还有一个实用技巧是对 HTML 文件禁用自动格式化,改用 Shift + Alt + F 手动触发,避免每次保存都在重排文档。
6.4 验证 HTML 有效性的简单方式
写完之后怎么确认标签写对了?有两个零成本的方法。第一个是直接用浏览器打开页面并开启开发者工具,查看 Elements 面板里的 DOM 树,如果浏览器自动“修正”了你的结构(比如自动闭合标签、移动节点位置),就说明原来的 HTML 有问题。第二个是用 W3C 提供的 Nu Html Checker 在线校验工具,把整段代码粘贴进去,它会列出所有错误和警告,比如属性写错、标签嵌套不合法、alt 属性缺失等。
我个人在实际操作中的体会是:新手阶段尽量多依赖浏览器开发者工具的 DOM 树展示,它能让你直观看到 HTML 被解析成了什么样子,比死记规范条文更有效。等你熟悉了浏览器解析规则,再配合在线校验工具,基本能把所有低级错误拦住。
如果要说一个最值得长期保持的习惯,那就是“语义优先”。写文本格式化标签时先想清楚这句内容在语义上是什么,再用标签表达;样式最终呈现交给 CSS 去调整。这样写的页面不仅结构干净,后续无论是项目交接还是自己回来维护,都能省下大把时间。等你开始学习 CSS 盒模型和布局时,会发现这些基础真的是越扎实,走得越远。
