尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

HTML5语义标签实战指南:从页面骨架到SEO与可访问性

HTML5语义标签实战指南:从页面骨架到SEO与可访问性 很多人入门前端是从一个“好玩”的项目开始的。我看到热搜里躺着“html5 超级玛丽 同人复刻版”“html5 格斗游戏”“html5 马里奥”这些词一下就懂了——HTML5 最吸引人的地方就是能用纯网页技术做出能跑能跳、有动画、能交互的东西。但不管你是想做小游戏、交一份网页设计作业还是打算搞一个上线就能拿得出手的产品图册网站所有这一切的地基都不是花哨的 Canvas 粒子特效而是那一堆看起来平平无奇的“语义标签”。这篇笔记就是围绕 HTML5 语义标签写的。我会从“为什么要有语义化”讲起一个一个拆解常用标签的适用场景再给出一套可以直接抄的页面骨架最后把我在实际项目里踩过的坑和排查方法整理成速查表。不管你是刚学完基础标签的新手还是写了一段时间 div 套 div、想提升代码质量的前端开发者这篇笔记都能让你在看完之后立刻把页面结构写得更加专业。1. 语义标签到底解决什么问题1.1 先理解“语义”这两个字所谓语义简单说就是“这个标签自己会说话”。你写一个div浏览器和同事都只知道“这里有一块区域”至于这块区域是导航、是正文、还是广告完全看不出来。但你要是写nav任何人一看就知道“这是导航区域”写article不用注释别人也知道“这是独立的一篇文章”。我第一次真正理解它的价值是在帮朋友维护一个别人写的旧项目。那个项目从头部到尾部全是div为了定位每层 div 都绑着不同的 class什么.header-wrapper、.main-left-inner、.content-box-footer光看 class 名字根本猜不出层级关系。后来我花了两天时间做了一个当时看来最正确的决定把所有纯粹的布局 div 替换成语义标签。替换完再看代码哪怕删掉所有注释整个页面的结构也一目了然。用一个生活化的类比语义标签就像是给房间贴上了门牌号。没有门牌的旅馆你只能一间一间推开门看贴了“厨房”“洗手间”“卧室”的牌子之后客人自己就能找到地方服务员打扫起来也更快。网页也是一样语义标签让浏览器、搜索引擎、屏幕阅读器和开发者都能更快地理解页面结构。1.2 语义化的三个直接收益第一个收益是 SEO。搜索引擎的爬虫虽然很聪明但本质上也是在读 HTML。它看到一个article包裹的内容加权地认为这是页面主体内容看到nav就知道这里是站内导航不太会把它当成正文来收录。我以前做过一个测试同一个页面用语义标签重写结构后百度收录时对主体内容的抓取明显更干净摘要里不会莫名其妙出现导航链接的文字。第二个收益是可访问性。屏幕阅读器会把页面转换成一棵“可访问树”语义标签在这棵树上会暴露 role 属性。比如header会带有 banner 角色nav带有 navigation 角色main带有 main 角色。视力障碍用户可以通过快捷键在区域间跳转体验完全不同。全球越来越多的网站把无障碍作为合规要求这已经不是“加分项”而是“必做项”。第三个收益是代码可维护性。这个收益你可能要等到项目变大、或者换人接手时才会真正感激。语义化的 HTML 自带一份“结构注释”团队协作时沟通成本会低很多。哪怕过了半年再回头看自己写的代码你也能在三秒内定位到页面头部、导航、主体和页脚分别在哪里改。1.3 一个核心原则先语义后样式写页面的时候我建议你记住一句话“先想清楚每个区块是什么再想它长什么样。”换句话说结构上应该用语义标签表达“这个元素是什么”CSS 再去解决“这个元素看起来怎么样”。只要把这两层分开你的 HTML 就不会退化成 div 堆砌。不过这里要说清楚语义标签并不排斥 div。恰恰相反div和span本身也是合法的无语义元素它们的存在价值就是当“纯粹的容器”。语义标签解决的是“区块是什么”的问题div 解决的是“区块怎么分组”的问题。比如一个卡片组件内部可能需要一个 div 来包住图标和文字做纵向排列这完全合理。真正的问题在于不能用 div 代替所有本该语义化的元素把整个页面变成一棵看不懂的树。2. 结构化语义标签核心拆解2.1 页面的“骨架五件套”HTML5 里最常用、也最容易理解的结构化标签就是下面这五个我把它们称为“骨架五件套”标签作用典型使用场景header页面或区块的头部区域站点头部、文章头部、组件头部nav导航链接区域主导航、侧边栏导航、面包屑导航main页面主内容区域一个页面只允许一个文章主体、页面核心区域footer页面或区块的底部区域站点页脚、文章版权信息、组件底部aside与主体内容相关的附属信息侧边栏、广告位、补充说明、相关文章可能有人会问header和footer只能出现在页面级吗不是。它们是“可嵌套”的语义标签意思是article内部也可以有属于自己的header和footer。比如一篇文章里开头有标题、作者、发布时间这就可以放进article内部的header文末的标签、版权声明可以放进article内部的footer。这在 HTML5 里是合法且推荐的写法。使用header有一个比较容易忽略的细节它可以出现在多个区块里但如果在header内部再嵌套一个header或者footer那就不合法了。还有header和h1~h6不是一回事header是容器标题标签是内容header里面放不放标题都行它只管“封装头部区域”这个职责。2.2 main 标签的边界与踩坑main是最“专一”的语义标签一个页面只能出现一个。它代表文档的主体内容在可访问树里对应 main 角色很多读屏软件会提供“跳到主内容”的快捷键就是靠这个标签实现的。这里有几个必须注意的边界main不能是header、nav、aside、footer的后代因为这些区域本身就是页面级区块不应该被包进“主体内容”里。同时main内部可以包含article、section、div等任何内容但它自己不能重复出现。我见过不少初学者把main当容器用页面里写两三个main这会让读屏软件无所适从。更常见的一个问题是有人为了布局方便把整个页面内容包括导航和页脚都包进main里结果页脚在可访问树里被标记为主内容的一部分语义全乱了。记住main是页面内容的重心不是整张页面的容器。2.3 article 与 section最容易混淆的一对article和section是初学者最容易搞混的组合因为它们长得太像了。article表示“可以独立分发或复用的完整内容”。判断标准很简单如果把这块内容单独拿出来投递到另一个网站或者 RSS 订阅里它是否仍然成立文章当然成立一条评论、一条微博、一个论坛帖子、一个产品卡片也都成立。所以它们都可以用article包裹。section表示“文档中的一个区域”它强调主题分组通常带一个标题。一个article里可以按章节分成多个section每个section有自己的标题组成一个完整的逻辑链。比如一篇教程文章可以按“环境准备”“核心概念”“实操步骤”分成三个section这就是典型的用法。选型时我给自己定了一条决策链先看这个内容能不能独立分发能 →article不能独立但属于某个主题区域且需要标题 →section只是一个纯粹的分组容器没有任何语义 →div。这条决策链帮我解决了很多纠结的时刻。还要特别提醒一点section的规范里写明了“通常应该包含一个标题”。如果你的 section 里一个标题都放不下那它大概率就不该用section直接用div更合适。这是很多校验工具会提示警告的地方也是代码质量审查里的常见问题。2.4 页面级 aside 与区块级 asideaside意为“侧边栏”但它不只有“页面侧边栏”一种形态。规范里的定义是与周围内容仅间接相关的部分。放到实际场景里它可以是页面级的侧边栏推荐文章、广告、标签云也可以是一篇文章正文旁边的“名词解释”“引用说明”。页面级aside一般直接放在main外部与主体内容并列在典型的三栏布局里占据左侧或右侧。区块级aside则可以放在article内部辅助解释正文中的某个概念。用的时候要自问一句这块内容拿掉之后主体内容还完整吗如果完整那它的确可以算作 aside如果不完整那它应该是正文的一部分而不是附属信息。还有一个需要注意的点aside并没有让浏览器自动把它“推到侧面”的能力。它的本职是表达语义真正实现“靠左或靠右”的视觉效果需要搭配 CSS 的 Flexbox 或 Grid。新手的误区是以为加了aside就会出现侧边栏布局实际上布局是 CSS 的事别把它俩搞混。3. 文本级语义标签与进阶标签3.1 旧标签的新用法strong、em、small很多人以为语义标签只跟页面结构有关其实文本级的语义标签同样重要它们在搜索引擎和读屏软件的眼里也会有对应的强调权重。strong表示“内容的重要性”在可访问树里对应 strong 角色读屏软件会用不同的语调读出它。em表示“内容的强调”它表示语气上的着重读屏软件的朗读方式也会不一样。值得说的是它们默认的加粗和斜体效果只是“附带产物”不是本质。如果你只是想文字加粗、不想表达“重要”语义用 CSS 的 font-weight 更合适只是想文字倾斜用 CSS 的 font-style 更合适。small也是一个容易被误解的标签。HTML5 里重新定义了它表示“附属细则”比如免责声明、版权声明、法律限制等不一定指的是“小号字体”。所以页面底部那行小小的“Copyright © 2025”用它来包裹就很贴切。我写博客排版的时候一度纠结要不要把文章关键词都用strong包起来。后来想明白了语义标签不是用来做视觉强调的如果把整篇文章都标成 strong那和“全篇都是重点”等于“没有重点”是一个道理。真正重要的、需要读屏特别提示的关键词才值得使用 strong 或 em。3.2 时间标签 time 的超能力time是一个看着不起眼、但在 SEO 和机器可读性上有大用处的标签。它允许你用datetime属性给一个人类可读的时间配上机器可读的格式例如time datetime2025-06-012025年6月1日/time time datetime2025-06-01T14:30:00下午两点半/time有人会问明明页面上已经写了时间文字为什么还要加一个 datetime 属性因为人和机器对“时间”的理解不一样。人能从“明天下午三点”里读出时间但搜索引擎和浏览器不能。有了 datetime 属性机器才能精确地解析出这个时间是 2025-06-01T14:30:00这在结构化数据、事件日历、搜索结果展示里非常有用。使用 time 标签时不要把它包裹在没有任何时间语义的文本上。比如“这篇文章写了 3 小时”这里的“3 小时”不是一个可被日历化的具体时刻用它就不太合适。反过来凡是文章发布时间、活动开始时间、上下班时间点都值得用 time 包一层。它不会影响视觉呈现但对机器的友好度提升是实打实的。3.3 嵌入内容标签figure 与 figcaptionfigure用来包裹独立的、自包含的内容单元最常见的就是图片、图表、代码片段、音频或视频。它和figcaption配套使用后者提供图文标题或说明文字。这个组合的语义是“图和说明是一体的”而不是“图片下面随便写一句话”。对比一下旧式写法是pimg srcchart.png alt柱状图/p p classcaption图1年度销售趋势/p这种写法的最大问题是“图”和“图的说明”在语义上没有任何绑定关系读到后面一段的人才明白前面那张图是干嘛的。用 figure 包裹后figure img srcchart.png alt柱状图 / figcaption图1年度销售趋势/figcaption /figure这样图片和它的说明就成了一家人。图片加载失败、屏幕阅读器解析时说明文字都会和图片紧密关联。这在小游戏开发、产品图册网站里尤其好用——很多产品展示页的“产品图 产品名称 一句话卖点”用figurefigcaption来做语义质量比一张img加一个p高出不少。3.4 进阶标签 address、details、markaddress的字面意思是“地址”但它不是用来写你家收货地址的。它表示“联系信息”包括文档作者或组织的联系方式比如邮箱、电话、社交账号。放在footer里很合适但不要用它去包装一个旅游景点的地理坐标。如果页面上要展示公司实体经营地址那实际上属于“文章内容”用p更合适而不是address。details和summary是实现“折叠面板”的原生方案。summary显示标题点击后展开details里的内容。这个标签很实用尤其适合 FAQ 区块、隐私政策里的折叠说明。想知道当前是否展开还可以用 open 属性控制默认状态details summary为什么推荐语义标签/summary p因为它让机器和人都能更好地理解页面结构。/p /details用 details 做折叠菜单可以不写任何 JavaScript浏览器原生支持手机端体验也不错。mark表示“标记高亮”。它不是强调也不表示重要性而是表示“与当前上下文相关的部分”。比如搜索结果里用户输入的关键词可以用 mark 高亮显示这个语义比用一个span stylebackground: yellow要精确得多。4. 实操搭建一个语义化的完整页面骨架4.1 “语义化优先”的五步设计流程动手写代码之前我强烈建议你先建立一套设计流程而不是打开编辑器就堆标签。我自己的流程是第一步用线框图或文字列出一个页面的所有区块。比如一个博客首页可能有站点头部、主导航、文章列表、侧边栏热门文章、标签、页脚。第二步给每个区块定义一个“语义身份”问自己是独立文章、导航、附属内容还是纯容器。第三步确定嵌套层级形成一棵语义树。第四步再填充具体文本内容和图片。第五步最后才写 CSS让视觉样式服从于语义结构。这个流程看起来慢实际上比你边写边改要快得多。因为语义树一旦定型CSS 的布局方案也基本定型了。而且当你把区块职责说清楚之后会自然避免“为了对齐而多包一层 div”的设计债。4.2 完整示例一份可直接参考的页面骨架下面是一份博客文章页的语义化骨架可以直接拿去改!DOCTYPE html html langzh-CN head meta charsetUTF-8 / meta nameviewport contentwidthdevice-width, initial-scale1.0 / title语义标签学习笔记/title /head body header a href/ classlogo前端小站/a nav ul lia href/htmlHTML/a/li lia href/cssCSS/a/li lia href/jsJavaScript/a/li /ul /nav /header main article header h1HTML5 语义标签学习笔记/h1 p发布时间time datetime2025-06-012025年6月1日/time/p /header section h2为什么需要语义化/h2 p这一段是正文。/p /section section h2常用语义标签/h2 p这一段是正文。/p figure img srcsemantic-tree.png alt语义标签层级树状图 / figcaption图常见语义标签的层级关系/figcaption /figure /section footer p标签a href/tags/htmlHTML/a、a href/tags/semantic语义化/a/p /footer /article aside h2热门文章/h2 ul lia href#CSS Grid 布局入门/a/li lia href#Flexbox 完全指南/a/li /ul /aside /main footer p© 2025 前端小站/p address 联系邮箱a hrefmailto:helloexample.comhelloexample.com/a /address /footer /body /html注意上面示例里的几个细节。article内部的header是文章头部页面的header是站点头部它们互不冲突。main同时包含了文章主体和侧边栏因为侧边栏是“这个页面主体内容的一部分”它有 aside 的语义身份但没有跑到 main 外面去。页面底部的footer是整个文档的页脚它可以包含address的联系信息。4.3 给 HTML5 游戏和作品集页面加上语义结构咱们回到开头提到的那几个热搜词超级玛丽同人复刻版、格斗游戏、产品图册网站。这些项目的 HTML 结构其实比普通页面更适合用语义标签原因很简单一个游戏页面里通常包含“标题屏”“游戏画布区”“操作说明”“排行榜”这些相互独立的部分用语义标签可以把它们的职责分得清清楚楚。比如一个 HTML5 格斗游戏的页面骨架header h1街头格斗 HTML5 版/h1 nav ul lia href#game开始游戏/a/li lia href#help操作说明/a/li lia href#rank排行榜/a/li /ul /nav /header main section idgame h2游戏区域/h2 canvas idgameCanvas width800 height450/canvas /section section idhelp h2操作说明/h2 p方向键控制移动空格键攻击。/p /section aside idrank h2排行榜/h2 ol li玩家A12000分/li li玩家B9800分/li /ol /aside /main你再想想如果整个页面只有一大坨 div 和 canvas游戏逻辑以后要扩展、要给 canvas 加“全屏模式”或“重新开始”按钮代码得多难维护。语义化结构最大的价值就是让你后续迭代时能快速找到“排行榜该改哪里”“操作说明该加在哪里”。产品图册网站也是同理。每个产品卡片可以用article作为容器内部配figure包裹产品图再用h3写产品名。这样搜索引擎抓取页面时能清晰识别出“一个产品条目”的完整信息比一堆无法分辨边界的列表项强太多了。4.4 语义树自查写完结构后做的事一个页面写完我会花几十秒做一次“语义树自查”。方法很简单把页面里的 sectioning 标签body、header、nav、article、section、aside、footer全部列出来看它们的嵌套关系是不是一棵干净的树。如果发现某个 section 没有标题某个 header 出现在不该出现的位置或者 main 出现了两次就说明结构有问题。这种自查不需要什么高级工具浏览器开发者工具的 Elements 面板里把标签层级展开看一眼就够了。养成这个习惯之后你写出来的页面即使不经过 Lighthouse 检测也知道基本能拿高分。5. 常见问题、验证工具与经验避坑5.1 高频问题速查表我在带新人、审代码时见过太多重复踩坑的情况整理成一张表问题错误示例正确做法原因main 出现多次页面里有 2 个main一个页面只保留一个main读屏软件依赖 main 定位主内容多个 main 会让快捷键失效article 套 article 乱嵌套把产品列表整体包在 article 里每个产品也包在 article 里外层用section内层产品用article列表本身不是独立条目列表内的产品才可独立分发section 没有标题sectionp内容/p/section要么补一个标题要么改用divsection 规范要求有标题表示主题header 内嵌 headerheaderheader站点名/header/header合并或拆开header 没有嵌套语义属于结构错误用 div 做导航div classnava链接/a/div用nav包裹div 不暴露 navigation 角色读屏无法识别导航区域time 包没有时间语义的文本time3小时/time用span或ptime 只能表示日期、时间点或持续时间不能表达“3小时前”这种描述address 放普通地址address北京市朝阳区某街道/address用p等普通标签address 只表示作者/组织的联系方式这张表你可以收藏下来写页面的时候对照着扫一遍能避掉大部分语义化初期的低级错误。5.2 怎么验证你的语义标签写对了判断语义标签写没写对不能光靠肉眼“看起来合理”要用工具验证。第一个工具是 W3C 的 HTML 校验器validator.w3.org/nu。直接把页面 URL 或者代码贴进去它会告诉你标签嵌套是否合法、section 是否缺少标题、哪些属性写错了。这个工具没有玄学报错信息就是规范的标准解释值得认真读。第二个工具是浏览器 Lighthouse。打开 Chrome 开发者工具切到 Lighthouse 面板生成一份报告里面“Accessibility”和“SEO”两项会直接反映出语义化的问题。尤其值得关注的是“Document doesnt have a main landmark”这类提示它说明你的页面里缺少main或者main使用不当。第三个工具是浏览器的 accessibility tree。在 DevTools 的 Elements 面板里可以切到“Accessibility Tree”试图查看读屏软件实际能“看到”的树。如果这里呈现出来的结构清晰、有明确的 banner/navigation/main/contentinfo 角色基本就说明语义对了。5.3 语义标签与 ARIA 的正确关系提到可访问性就绕不开 ARIAAccessible Rich Internet Applications。ARIA 允许你给元素手动添加 role 属性弥补原生语义的不足。但这里有一条铁律能用原生 HTML 语义标签的就不要用 ARIA。为什么因为原生语义标签自带的行为、键盘交互和角色映射是经过浏览器多年打磨的比自己手工造的 role 可靠得多。比如一个导航用nav比div rolenavigation更地道。一个按钮用button比div rolebutton tabindex0 click...更不容易出问题。ARIA 真正发挥价值的场景是构建自定义组件的时候。比如一个手风琴菜单原生没有现成的“手风琴”标签你需要组合 details/summary或者用自定义实现并配合 aria-expanded、aria-controls 这些属性把展开状态告诉读屏软件。这个话题可以单独写一篇但结论很简单ARIA 是用来补位的不是用来替代语义标签的。5.4 兼容性语义标签在旧浏览器的表现HTML5 语义标签在现代浏览器里没有任何兼容性问题但如果你需要兼容 IE8 及更早版本就得注意了。那些老浏览器不认识header、nav这些标签会把它们当成未知内联元素导致没有默认的 display: block 样式布局直接崩掉。常规的兼容方案是用 HTML5shiv在页面 head 里引入一段脚本让旧浏览器把新标签识别为块级元素。另外还需要在 CSS 里给这些标签加上display: blockheader, nav, main, article, section, aside, footer { display: block; }不过到今天做新项目时我建议直接放弃对 IE 的兼容。原因很现实IE 的市场份额已经非常低维护兼容的成本远大于收益。如果你的项目还硬性要求兼容老 IE那说明业务本身需要重新评估技术选型了。5.5 经验心得从“用对”到“用好”最后分享几条我自己的经验心得每一条都是实操换来的。第一条搞不清标签就用“内容自问法”。问自己这段内容独立拿出去还能成立吗能用 article。这段内容属于某个主题但需要标题统领用 section。这段内容只是布局分组没有任何主题含义用 div。把这个问题问完大部分标签选择都有了答案。第二条不要为了语义化而语义化。见过一些项目一个只有一句话的小组件也套上 header/main/footer 三层标签这是过犹不及。语义标签是为内容服务的内容本身很轻的时候少一点嵌套反而更清晰。第三条语义标签要跟着内容走不是跟着设计稿走。设计稿上两个区块长得一模一样不等于它们在语义上也是同一种东西。一个区块是文章列表另一个是广告位它们就该分别用 article 和 aside哪怕视觉上一模一样。反过来两个长得完全不同的区块只要语义身份相同也可以都用 article 包裹。第四条多用.visually-hidden技术而不是滥用语义标签做“看不见的内容”。如果你确实需要提供一个供读屏用户阅读、但视觉上不显示的标题常见做法是加一个 CSS class把它定位为视觉隐藏而不是偷偷塞一个不可见的 h1。这属于无障碍细节但很能体现专业度。写 HTML 和写文章一样好的结构让人读起来行云流水坏的结构让人改一次骂一次。语义标签不是什么高深的技术它真正考验的是你对内容的理解、对用户的同理心以及写代码时的耐心。希望你从这篇笔记里拿到的不只是标签清单更是一套“先想清楚再动手”的思维方式。
返回列表