
平时我给朋友讲 HTML最常听到的一句话是能不能给我一份标签速查表我照着抄就行直接把标签列表甩过去当然容易但没过几天对方就会踩进同一个坑里——标签照抄了却不明白为什么那么写文档乱得一批表单提交了收不到数据图片显示不出来也不知道去查哪。所以这篇东西我打算换个玩法不给你做一张干巴巴的标签清单而是按照“一个网页从骨架到血肉再到交互”的顺序把 HTML 基础标签怎么用、为什么这么用、实际开发里怎么避免翻车全部串起来讲。HTML 本身不难但它是一切 Web 内容的底盘。你在任何地方看到写的网页底层都是这套标签体系在撑。这篇内容适合完全没写过代码的小白也适合那些会写两行标签但对语义化、表单规范、属性细节一知半解的人把它当成一本可以随时回来翻的“操作手册”。我会全程用实际代码片段说话所有示例都保证可以直接复制到本地保存成一个.html文件双击打开就能看效果。你不需要装任何复杂的开发工具记事本、VS Code、Sublime 都行。唯一的要求是每个标签都动手敲一遍不要偷懒只看不练。1. 网页的骨架从文档结构说起我们要拆的第一个东西不是某个具体标签而是整个 HTML 文档的骨架。只要你打开任何一个网页并查看源代码第一眼看到的几乎都是同一套模板。这套模板就是浏览器识别并渲染一个网页的基础协议看不懂它后面的一切都是空中楼阁。1.1 文档类型声明doctype 为什么必须写!doctype html这一行是整个 HTML 文件的第一行它不是标签而是给浏览器看的“声明”。它的作用是告诉浏览器请按现代标准模式来解析这个文档别用老掉牙的兼容模式。实际工作中最常见的坑就是少了这行之后页面在 Chrome、Edge 里看着正常但一到老版浏览器或者某些内置 WebView 里就开始“蹦迪”——布局错乱、CSS 不起作用、盒模型计算方式诡异。理由很简单浏览器遇到没有 doctype 的文档时会切换到“怪异模式”Quirks Mode用上世纪 IE 的那套盒模型算法来渲染页面。出现这种情况调试半天都找不到原因最后发现就是少了那一行声明真的能把人气笑。1.2 html 根标签与 lang 属性html langzh-cnhtml是文档的根标签页面上所有其他标签都必须包在它里面。lang 属性很多人会忽略但它对两个场景特别重要一是屏幕阅读器会依据 lang 判断该用哪种语言的语音合成方式读你的页面二是搜索引擎理解页面语言倾向时会参考它。中文站点写成langzh-cn即可英文站点写成langen。1.3 head 区域meta、title、link 与 stylehead里装的是页面的“元信息”它不直接显示在页面上却决定了页面的编码方式、标题、引入的资源。最常见的四个东西head meta charsetutf-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title我的第一个页面/title link relstylesheet hrefstyle.css /headmeta charsetutf-8是乱码问题的唯一答案。文件保存为 UTF-8 编码同时声明charsetutf-8就能保证中文不乱码。viewport标签是移动端适配的基础没有它手机浏览器会把页面当成桌面宽度缩放字小得跟蚂蚁一样。title是浏览器标签页上显示的文字也是 SEO 里权重最高的位置之一。link用来引入外部 CSSrelstylesheet表示这是样式表href写文件路径。顺带补充一个细节meta namedescription content页面描述可以设置搜索结果里显示的一段描述文字一个页面最多写 150 字左右超出的部分通常会被搜索引擎截断。1.4 body 区域所有可见内容的容器body标签内部的全部内容都会显示在浏览器窗口中。它的子结构怎么布局其实就是你页面设计的主战场。实际开发中body内部最外层的布局结构常常是一堆div但 HTML5 之后我们更推荐用语义化标签header、nav、main这些这一点我会在第 7 章专门展开。2. 标题、段落与文本页面上的第一个文字骨架搭好了接下来往里面填充内容。这一章讲的标签是日常使用频率最高的一组任何一个内容型页面都离不开它们。把这些玩明白了你就已经能写出一个像模像样的纯文本网页了。2.1 标题体系 h1 到 h6h1一级标题/h1 h2二级标题/h2 h3三级标题/h3标题标签一共六级h1权重最高字号最大h6最小。它们不只是“变大字”的工具更是页面内容结构的骨架。从 SEO 的角度看一个页面最好只有一个h1用来概括整页主题下面的内容层级依次使用h2、h3千万不要跳级比如h2下面直接接h4屏幕阅读器用户会把你的内容结构读得晕头转向。我在实际项目里见过最经典的标题错误是为了让某个字变大就把整段话塞进h1结果页面上一堆 h1搜索引擎根本分不清主次。如果只是想改变字号用 CSS 的font-size别乱用标题标签。2.2 段落、换行与分隔线p这是一个段落。/p p这是另一个段落。/p br hrp用来包裹一段独立的文字块浏览器会在段落前后自动加间距。br是强制换行适合用在地址、诗句这种需要手动断行的场景。hr是水平分隔线表示内容的主题切换比如一篇文章讲完一个大章节想再加一条视觉分隔用hr最合适。这里有一个新手高频翻车点用多个br去制造间距。正确做法是用 CSS 的margin或padding控制间距。如果你发现自己在代码里连续写了三个br停下来那几乎一定是用错了工具。2.3 文本格式化标签加粗、斜体、下划线、删除线与上下标strong重要内容/strong —— 加粗强调 b加粗/b —— 仅视觉加粗 em斜体强调/em —— 斜体语气强调 i斜体/i —— 仅视觉斜体 u下划线/u —— 下划线 del已删除内容/del —— 删除线 mark高亮标记/mark —— 高亮 sub下标/sub —— 下标 sup上标/sup —— 上标strong和b的区别值得单独拎出来说。strong在语义上表示“这个内容很重要”屏幕阅读器会加重朗读语气b则没有任何语义只是视觉上加粗。同理em是语义上的强调i是视觉上的斜体。日常写文章优先用strong和em既照顾了可访问性也对 SEO 更友好因为搜索引擎会认为强调内容更有价值。sub和sup常用于化学式H₂O、数学公式x²和脚注编号。del和mark在文档修订和笔记类页面里很实用比如标出打折前的原价、高亮一段话中的关键词。3. 链接与图片让页面真正联起来没有链接的网页是孤岛。这一章的两个标签a和img是所有网站流量流动的底层通道。它们看着简单属性却非常值得逐一说透。3.1 超链接 a 标签的全属性解析a hrefhttps://example.com target_blank relnoopener title示例站点访问示例/a a hrefabout.html站内页面/a a href#section2跳转到页内锚点/a a hreffile.pdf download下载文件/ahref是链接地址可以写完整 URL、相对路径、锚点、邮箱地址mailto:xxxexample.com甚至电话号码tel:10086。target_blank表示新标签页打开这个很常用。但它有一个安全隐患新页面里的 JavaScript 可以通过window.opener对象控制你原来的页面所以加上relnoopener是标准姿势。现在大部分浏览器默认把_blank当成noopener行为处理但为了兼容旧浏览器手写的时候加上总没错。页内锚点是我发现很多人不会用的功能。先给目标元素一个id比如h2 idsection2然后用a href#section2链接到它点击后就能平滑滚动到那个位置。配合scroll-behavior: smooth的 CSS 属性体验非常棒。3.2 图片标签 img 的完整参数img srcimages/photo.jpg alt海边日落 width800 height600 loadinglazysrc是图片路径alt是图片无法显示或屏幕阅读器朗读时的替代文本必须写。这不仅是为了无障碍体验也是 SEO 的要求——搜索引擎主要靠alt理解图片内容。图片加载失败时alt文字会直接展示在页面上很多新手以为这是 bug其实是浏览器在提示你忘写alt了。width和height建议显式声明浏览器可以在图片加载完成前就预留好位置避免页面布局跳动CLS 问题。loadinglazy是懒加载属性图片进入视口附近才开始加载长页面里给首屏以下的图片都加上它首屏加载速度会明显提升。关于响应式图片还有两个进阶属性srcset和sizes。它们允许你为不同屏幕宽度准备多张不同分辨率的图片由浏览器按需选择。格式类似img srcphoto-800.jpg srcsetphoto-400.jpg 400w, photo-800.jpg 800w sizes(max-width: 600px) 400px, 800px alt响应式图片示例这里w表示图片的内在宽度sizes告诉浏览器在不同视口下图片占据多大宽度浏览器据此选出最合适的资源。3.3 图片的容器问题多人会有疑问一张图片要不要用div包一层这取决于需求。纯展示图片img本身足够了。但如果你要给图片加说明文字HTML5 提供了figure和figcaption这对组合figure img srcchart.png alt年度销售趋势图 figcaption图12024年度销售趋势/figcaption /figurefigcaption图文说明文字会跟图片形成语义上的关联比随便在旁边放一个p更规范。4. 列表与表格结构化展示数据的利器原始的文本信息一多就需要组织。列表负责把并列关系讲清楚表格负责把多维数据呈现在网格里。这两个东西在页面里出现的频率极高但很多人写的时候只求“看着像”不求规范。4.1 有序列表、无序列表与自定义列表ul li苹果/li li香蕉/li li橙子/li /ul ol li第一步打开编辑器/li li第二步写代码/li li第三步保存并预览/li /ol dl dtHTML/dt dd超文本标记语言用于描述网页结构。/dd dtCSS/dt dd层叠样式表用于描述网页外观。/dd /dlul是无序列表各项顺序不重要时用它默认前面是圆点符号。ol是有序列表各项有先后顺序时用它默认前面是数字。ol还可以通过start属性指定起始编号通过type属性切换编号形式1、A、a、I、i比如typeI会显示罗马数字。嵌套列表也很常见比如多级菜单。注意嵌套时li里面再放一个ul或ol而不是把列表直接平铺在另一个列表同一级。写多了你会发现合理嵌套的列表也是网页信息层级的一部分。4.2 表格标签别再只用 table 行不行table caption员工信息表/caption thead tr th姓名/th th部门/th th工龄/th /tr /thead tbody tr td张三/td td研发部/td td3年/td /tr tr td李四/td td市场部/td td5年/td /tr /tbody tfoot tr td colspan2平均工龄/td td4年/td /tr /tfoot /tablethead放表头行tbody放数据行tfoot放表尾汇总行。这个结构不只是分类方便更关键的是打印长表格时浏览器可以在每页重复打印表头屏幕阅读器也能准确关联表头与数据单元格。th默认加粗居中表示表头单元格td是普通数据单元格。colspan让单元格横向合并rowspan纵向合并。上面例子中colspan2表示这个单元格横跨两列。新手用表格最常见的错误用表格来布局整个页面。早年间没有 CSS 布局时大家确实这么干但今天再这么写就是给自己找麻烦。表格布局的页面代码冗长、修改困难、搜索引擎解读效率低。现代网页布局用 Flexbox 或 Grid表格只负责展示真正的表格数据。这个理念必须从一开始就建立。4.3 表格进阶内容溢出与响应式表格在手机上很容易撑破布局。解决思路是给表格的外层容器加一个包裹层并允许横向滚动div styleoverflow-x: auto; table.../table /div这样小屏幕上表格可以在容器内左右滑动而不是撑裂整个页面布局。5. 表单标签收集用户信息的核心组件表单是 HTML 里跟用户交互最直接的部分注册、登录、搜索、问卷调查、订单提交全靠它。但它也是新手翻车率最高的领域因为表单涉及前端与后端的数据对接任何一个属性没配对数据就过不来。5.1 form 标签的三个关键属性form actionhttps://api.example.com/submit methodpost namecontact-form ... /formaction指定表单数据提交到的服务器地址method指定提交方式get或post。get会把数据拼在 URL 后面适合搜索一类的操作post把数据放在请求体里适合提交敏感或大量数据。原则很简单涉及修改服务器数据的一律用post只做查询的可以用get。5.2 input 标签类型定天下input typetext nameusername placeholder请输入用户名 required input typepassword namepassword placeholder请输入密码 input typeemail nameemail required input typenumber nameage min1 max150 input typetel namephone input typeurl namewebsite input typedate namebirthday input typecolor namefavcolor input typerange namevolume min0 max100 value50 input typecheckbox nameagree valueyes 我已阅读协议 input typeradio namegender valuemale 男 input typeradio namegender valuefemale 女 input typefile nameavatar input typehidden nameuser_id value12345 input typesubmit value提交 input typereset value重置type属性决定了输入框的表现形式和自带校验规则。email类型会在提交时校验邮箱格式number类型会在移动端弹起数字键盘。name属性是提交给服务器的字段名没有它数据不会随表单提交。placeholder是输入框里的灰色提示文字required标记必填项。radio单选按钮实现互斥的关键是name必须相同不同name的 radio 之间不会互斥。checkbox常用于多选或同意协议。file类型用于上传文件配合accept属性可以限制文件类型比如acceptimage/*只允许图片。hidden类型不显示在页面上但会随表单一起提交常用于传递用户 ID、令牌之类的隐藏数据。5.3 下拉选择、多行文本与按钮select namecity option valuebeijing北京/option option valueshanghai selected上海/option option valueguangzhou广州/option /select textarea namemessage rows5 cols30 placeholder请输入留言内容/textarea button typesubmit提交/button button typebutton onclickalert(点了)普通按钮/buttonselect是下拉选择框option的value是实际提交的值selected属性可以设置默认选中项。textarea是多行文本输入rows和cols控制可见行数与列数。button的type有三种submit提交表单、reset重置表单、button纯按钮需要手动绑定 JavaScript 事件。5.4 label 标签容易被忽略的可用性功臣label forusername用户名/label input typetext idusername nameusernamelabel的for属性绑定输入框的id点击 label 文字时焦点会自动跳到对应的输入框。这个细节大大提升表单可用性尤其是手机端的输入体验——点击范围变大了误触率会明显降低。很多人不写 label觉得有 placeholder 就够了。但 placeholder 会在输入时消失而且屏幕阅读器依赖 label 来朗读字段含义for和id必须严格一致才能生效。5.5 表单自带校验与前端校验的配合HTML5 内置了一批校验属性required必填、minlength/maxlength长度限制、min/max数值范围、pattern正则匹配。比如给手机号字段加一个 patterninput typetel namephone pattern1[3-9]\d{9} placeholder请输入11位手机号 required这个正则要求以 1 开头第二位是 3-9后面 9 位数字。浏览器原生就会拦截不符合格式的提交并弹出提示。实际开发中前端校验只是用户体验层面的提示真正可靠的校验必须由后端完成因为任何人都可以绕过前端直接提交请求。6. 多媒体与嵌入让页面不再只是文字现代网页很少是纯文本的。音频播放器、视频播放器、第三方地图、外部页面嵌入这些都是增强用户体验的重要组成部分。HTML 原生支持的音频视频标签已经非常成熟比直接用 Flash 之类的插件方案强太多。6.1 audio 与 video 标签audio controls autoplay loop source srcmusic.mp3 typeaudio/mpeg 您的浏览器不支持 audio 标签。 /audio video width640 height360 controls preloadmetadata posterposter.jpg source srcmovie.mp4 typevideo/mp4 您的浏览器不支持 video 标签。 /videocontrols属性显示播放控件播放/暂停按钮、进度条、音量。autoplay自动播放但大部分浏览器会限制带声音的自动播放必须用户交互后才能播放。loop循环播放。muted静音播放不少浏览器允许带着muted属性的自动播放。preload控制加载行为none不预加载、metadata只加载元信息、auto自动加载全部视频。source标签可以同时声明多个不同格式的源文件浏览器会使用它支持的第一个格式。这就是解决格式兼容问题的标准方案视频准备 MP4 和 WebM 两种格式老浏览器不认 MP4 就尝试 WebM。6.2 iframe嵌入外部世界iframe srchttps://www.openstreetmap.org/export/embed.html?bbox116.3,39.9,116.5,40.1 width600 height450 title地图嵌入示例 loadinglazy/iframeiframe用于在页面内嵌入另一个文档。常见用途有嵌入地图、嵌入视频播放器如 B 站、YouTube 的分享代码、嵌入第三方支付页面。实际开发中要注意两点一是尽量给iframe设置title方便屏幕阅读器用户理解嵌入内容是什么二是不必要的iframe会拖慢页面加载因为浏览器要额外加载一份文档能不用就不用。7. 语义化标签与页面布局写给人看也写给机器看这一章是这个主题里最有“进阶感”的部分。同样的视觉效果用div堆出来的页面和用语义化标签写出来的页面短期看着没区别长期维护起来天差地别。7.1 区块标签角色对照header页面头部通常放 logo、标题、导航入口/header nav主导航菜单/nav main页面主内容区一个页面只能有一个 main/main article独立的内容单元比如一篇博客、一条新闻/article section内容分区通常带一个标题/section aside侧边栏放相关推荐、广告、作者信息/aside footer页脚放版权信息、联系方式、备案号/footer这些标签的作用是告诉浏览器和搜索引擎“这一块内容在页面里扮演什么角色”。比如main只能有一个它标记的是页面最核心的内容nav标记导航链接区域article标记独立且完整的文章内容aside标记与主内容关系不太紧密的补充信息。用语义化标签布局代替满屏div的好处有三个可访问性更好屏幕阅读器可以直接跳转到 main 区域、跳转到 nav 区域SEO 更友好搜索引擎能准确识别页面结构给主内容更高的权重维护性更强几个月后回来看代码一眼就能明白每一块是干什么的。实际项目布局往往长这样body header h1我的博客/h1 nav ul lia href/首页/a/li lia href/about关于/a/li /ul /nav /header main article h2文章标题/h2 p正文内容……/p /article aside h3相关阅读/h3 ulli……/li/ul /aside /main footer p© 2025 某某博客/p /footer /body7.2 更细的语义标签figure、details、time、addressdetails summary点击展开查看详情/summary p这里是默认隐藏的详细信息。/p /details time datetime2025-06-012025年6月1日/time address北京市海淀区某街某号/addressdetails和summary是一对原生折叠面板不需要任何 JavaScript 就能实现展开收起。time给时间加上机器可读的datetime属性方便搜索引擎理解时间信息。address专门放联系方式、地址信息浏览器会斜体显示。7.3 div 和 span最后的选择不是唯一的选择div是没有任何语义的块级容器span是没有任何语义的行内容器。它们的目的纯粹是给 CSS 和 JavaScript 提供“挂点”。当没有任何一个语义化标签适合你的内容时才用它们而不是一上来就用 div 包一切。判断标准很简单先想清楚这块内容是什么。如果是导航用nav如果是文章主体用article或main如果只是想把一组文字包起来加个颜色那用span就对了。8. 常见问题速查与避坑指南写 HTML 没有不踩坑的。这一章我把日常开发里出现频率最高的几个问题集中列出来每一条都是前人拿头发换来的经验。8.1 标签闭合与嵌套错误HTML 里大部分标签需要成对出现p必须配/pdiv必须配/div。漏掉闭合标签浏览器不会报错因为它会自动帮你补全但补全的位置往往不是你预期的地方页面就会乱。另一个常见问题是嵌套错误。块级元素里套行内元素没问题比如divspan文字/span/div。但行内元素里套块级元素就是非法嵌套比如spandiv文字/div/span浏览器解析时会强行拆分导致布局错乱。记住一个口诀块级可以套块级和行内但行内不能套块级。8.2 中文乱码问题meta charsetutf-8如果发现页面中文全部变成“锟斤拷”一类的乱码先检查两件事文件保存的编码是不是 UTF-8head 里有没有声明charsetutf-8。很多编辑器默认保存编码是 ANSI 或 GBK需要手动改成 UTF-8。8.3 图片路径问题图片不显示时按这个顺序排查文件名有没有拼错包括扩展名路径对不对相对路径是从当前 HTML 文件所在位置出发的alt是不是没有导致你以为出问题了。常见的路径写法参考!-- 当前目录下的图片 -- img srclogo.png altlogo !-- 上级目录的 images 文件夹 -- img src../images/logo.png altlogo !-- 网络图片绝对 URL -- img srchttps://example.com/logo.png altlogo8.4 表单提交后收不到数据这是表单开发最让人崩溃的问题。提交后页面跳转到 action 地址但服务端 say 没收到字段。排查顺序每个要提交的输入框有没有name属性没有 name 的字段不会提交radio 同组 name 是否一致method 到底用的 get 还是 post跟后端约定的是否一致button 的 type 是不是 submit如果用 typebutton 点了根本没反应。8.5 浏览器差异带来的样式问题同一份 HTML 在不同浏览器里可能长得不太一样。这不是 HTML 标签的问题是浏览器默认样式差异。解决方案是引入一份 reset 或 normalize CSS把浏览器默认的 margin、padding 统一清零再从头定义自己的样式。最简单粗暴的 reset 是style * { margin: 0; padding: 0; box-sizing: border-box; } /style这段代码把所有元素的 margin 和 padding 全部清零再统一设置盒模型。实际项目通常会做得更精细化但新手起步用这段就够解决问题了。结束语把标签用熟才算真正入门写了这么多年 HTML我最大的感受是标签本身从来不是门槛门槛在于你有没有把每个标签当成有“身份”的组件来理解。对 HTML 基础标签的熟悉程度决定了你后面学 CSS 时定位问题的速度也决定了你写出来的页面在别人维护时是噩梦还是享受。我建议你把这篇文章作为一份“跟练手册”每看一章就在本地建一个 HTML 文件亲手敲一遍。初期不需要急着背下所有标签只需要在遇到问题时知道“这个东西应该用什么标签”查得到、用得上就是进步。我个人还有一个坚持了很久的习惯写页面之前先在纸上简单画出区块结构图标好哪些地方用 header、哪里用 article、哪里用 aside再动手写代码。这样写出来的 HTML 几乎是天然规范化且结构清晰的页面。这个习惯推荐给你。