应使用 main 标签包裹内容区,且每个页面仅有一个、作为 body 直接子元素;标签页内容用带唯一 id 和 role="tabpanel" 的 section 包裹,并通过 aria-hidden 控制可访问性。

用 main 包裹内容区,别用 div 硬套
标签页切换时,只有主体内容变化,这部分必须语义清晰、结构独立。浏览器和读屏器靠 main 标签识别“这是用户真正要看的内容”,搜索引擎也据此加权。如果写成 <div class="tab-content">,等于主动放弃可访问性与 SEO 优势。<p>常见错误现象:<code>main 被嵌套在 section 或多个 div 里;或一个页面出现两个 main —— HTML5 规范明确要求每个文档只能有一个 main。
-
main应是body的直接子元素,或紧接在header/nav之后 - 每个标签页对应的内容块,用
section包裹,并设role="tabpanel"(增强无障碍) - 初始隐藏非激活态的
section,用hidden属性比display: none更语义化且兼容 JS 切换逻辑
section 加 aria-hidden 和 id 是切换前提
纯 CSS 实现标签页切换时,section 必须能被 JS 或锚点精准定位。没有 id,a[href="#products"] 就无法滚动并激活对应面板;没有 aria-hidden,屏幕阅读器会一次性读出所有标签页内容。
使用场景:单页应用式静态标签页、服务端渲染后由 JS 补充交互、或配合 :target 伪类做无 JS 方案。
立即学习“前端免费学习笔记(深入)”;
- 每个
section必须有唯一id,且与导航链接的href值完全一致(如href="#service"→<section id="service"></section>) - 非当前页的
section设aria-hidden="true",当前页设为"false";不要只依赖 CSS 隐藏,否则辅助技术不可见 - 若用
:target控制显隐,需配section:target { display: block; },但注意 Safari 对:target在section上的支持较弱,建议 fallback 到 JS
Flex 布局下 main 内容区别设 width 或 flex
main 本身是块级元素,默认占满父容器宽度。但当它作为 Flex 容器的子项(比如 header + main + footer 用 Flex 垂直排列),若给 main 设了 width: 100% 或 flex: 0 0 auto,反而可能破坏高度自适应,导致内容被截断或留白异常。
性能影响:过度约束 main 的尺寸会触发额外重排,尤其在标签页频繁切换、内容高度差异大时更明显。
- 让
main自然流式伸展,不设固定宽高;需要横向限制时,用max-width+margin: 0 auto - 如果
main是 Flex 容器(例如内部放左右分栏),子元素用flex: 1即可,避免同时设width和flex - 移动端需注意:某些安卓 WebView 对
main的默认min-height处理异常,可加min-height: calc(100vh - header高度 - footer高度)防空白
响应式下 section 内容别依赖固定高度
标签页内容长短不一,一旦给 section 设了 height: 500px 或 min-height 过大,小屏下会出现横向滚动或文字溢出。这不是样式问题,而是布局假设失效。
容易踩的坑:为“视觉统一”强行拉平所有标签页高度;或用 JS 动态同步高度——这在内容异步加载、字体未就绪时极易错判。
- 用
padding和gap控制内容呼吸感,而非height - 图片/视频等媒体元素务必设
max-width: 100%和height: auto - 表格类内容加
overflow-x: auto容器,防止窄屏撑破布局
复杂点在于:内容区不是孤立模块,它和导航的 aria-controls、焦点管理、历史记录(pushState)强耦合。很多团队只调样式,却漏掉 tabindex="-1" 和 focus() 的衔接,导致键盘用户切到新标签页后焦点丢失——这才是真实场景中最常被忽略的一环。



















