关于 semantic-html-and-seo
这是一项指导团队编写语义化、易访问 HTML 和利于搜索的页面的开发技能,涵盖元数据、结构化数据、渐进增强及 SPA 的无障碍与 SEO。
主要功能
- 01语义化 HTML 结构
- 02图片替代文本指导
- 03SEO 元数据与结构化数据
- 04渐进增强实践
- 05SPA 无障碍与 SEO 检查
适用场景
- 01检查页面标题和文档结构
- 02完善元数据与社交分享卡片
- 03改进 SPA 的无障碍性和搜索收录
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dembrandt/ dembrandt-skills --skill semantic-html-and-seo安装后在 Claude Code 中输入/semantic-html-and-seo确认已加载。
详细介绍
语义化 HTML 和 SEO
优秀的 HTML 不只是标记——它是内容、搜索引擎、辅助技术与浏览器之间的契约。语义化 HTML、正确的元数据和渐进增强,能让 UI 默认具备韧性、易于发现且易于访问。
语义化 HTML5
使用能够描述内容含义的元素,而不只是描述其外观的元素。
文档结构
<header>
<nav>
<main>
<article>
<section>
<aside>
<footer>
标题
每页使用一个 <h1>,表示主要主题。标题会形成大纲:不要跳过级别(从 h1 直接跳到 h3,中间没有 h2)。
<h1>Product name</h1>
<h2>Features</h2>
<h3>Feature detail</h3>
<h2>Pricing</h2>
交互元素
<button>
<a href>
<input>
<select>
<details> / <summary>
除非完整添加 ARIA 注解,否则不要将 <div> 或 <span> 用作交互元素;即使添加了注解,也应优先使用原生元素。
图片和替代文本
每个 <img> 都需要 alt 属性。具体内容取决于上下文。
| 图片类型 | 替代文本 |
|---|---|
| 信息性(产品照片、图表) | 描述内容:alt="Red leather sofa, three-seater" |
| 功能性(图标按钮、徽标链接) | 描述功能:alt="Go to homepage" |
| 装饰性 | 留空:alt=""——屏幕阅读器会跳过它 |
| 复杂(图表、示意图) | 简短的替代文本 + 附近或 <figcaption> 中的较长描述 |
<img src="sofa.jpg" alt="Red leather sofa, three-seater">
<img src="divider.svg" alt="">
<figure>
<img src="chart.png" alt="Bar chart showing revenue growth Q1–Q4 2025">
<figcaption>Revenue grew 42% year-on-year in Q4 2025.</figcaption>
</figure>
SEO 基础知识
标题和描述
<title>Product Name — Short descriptor | Brand</title>
<meta name="description" content="One or two sentences. What this page is, who it is for, what they will find.">
- 标题:50–60 个字符。最重要的关键词放在前面。
- 描述:120–160 个字符。会显示在搜索结果中——为读者而写,而不是为算法而写。
规范 URL
<link rel="canonical" href="https://example.com/the-definitive-url">
当同一页面可通过多个 URL 访问时,可防止因重复内容受到惩罚。
Open Graph(社交分享)
<meta property="og:title" content="Page title">
<meta property="og:description" content="Page description">
<meta property="og:image" content="https://example.com/og-image.jpg">
<meta property="og:url" content="https://example.com/page">
<meta property="og:type" content="website">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Page title">
<meta name="twitter:image" content="https://example.com/og-image.jpg">
OG 图片:1200×630px。在 Slack、LinkedIn、Twitter、iMessage 上分享 URL 时会显示。
卡片标题应该是读者会使用的说法,而不是文章的洞见。 信息流不会提供上下文,因此需要依赖文章才能理解的句子,在匆匆浏览的陌生人看来就像胡言乱语。卡片上应使用他们正在寻找的直白承诺,采用所在平台的表达方式,并把巧妙的说法留给页面。
根据平台调整卡片时,应改变模式,而不是色调。 在浅色信息流中,深色卡片看起来像广告横幅;正确的做法是在该平台自身的背景上使用浅色卡片,而不是换成更暖的藏青色或更柔和的蓝色。与平台的界面元素相比,色相的细微调整难以察觉,只会白费一次往返。先选对模式,再调整色调。
结构化数据(JSON-LD)
机器可读的内容有助于展示丰富的搜索结果。
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Product Name",
"description": "Product description",
"image": "https://example.com/product.jpg",
"offers": {
"@type": "Offer",
"price": "49.00",
"priceCurrency": "EUR"
}
}
</script>
常见类型:Product、Article、BreadcrumbList、FAQPage、Organization、SiteLinksSearchBox。
渐进增强
分层构建。核心内容和功能必须在没有 JavaScript 的情况下正常工作。使用 CSS 增强,再使用 JS 进一步增强。
Layer 1: HTML — content is readable, links work, forms submit
Layer 2: CSS — layout, typography, visual design
Layer 3: JS — interactivity, animations, dynamic content
实践中:
- 表单必须无需 JS 即可通过原生
<form action>提交——JS 可以拦截提交并使用 fetch 增强功能 - 导航链接必须是实际的
<a href>——JS 可以添加过渡效果 - 内容必须包含在 HTML 中——JS 可以通过延迟加载或个性化进行增强
- 图片必须有
src——JS 可以通过loading="lazy"添加延迟加载(现已原生支持)
SPA 注意事项
单页应用会破坏 SEO 和无障碍功能所依赖的浏览器默认行为。请明确修复这些问题。
服务端渲染或静态生成
客户端渲染的 HTML 无法确保被搜索引擎索引。对于任何需要被发现的内容,请使用 SSR(Next.js、Nuxt、SvelteKit)或静态生成。
更新标题和 meta
每次路由变化时都要更新 document.title 和 meta 标签。使用框架的 <Head> 组件或同等功能。
焦点管理
路由变化时,将焦点移至新页面的 <h1> 或 <main>——屏幕阅读器不会自动检测 SPA 导航。
// After route change
document.querySelector('h1')?.focus();
滚动位置恢复
导航时将滚动位置恢复到顶部,或在返回导航时恢复到已保存的位置。SPA 中浏览器默认的滚动位置恢复功能已禁用。
History API
使用 pushState / replaceState,确保前进/后退导航和书签功能正常。
设备能力和用户情境
设计和代码应适应设备和用户的实际能力。
将客户端存储用作个性化工具
localStorage、sessionStorage 和其他浏览器能力(Cookie、IndexedDB、媒体/权限查询)都是调整体验的正当工具——例如上次查看模式、选定的语言区域、已关闭的横幅、正在编辑的草稿,以及回访用户的情境。
注意事项:
- 基于真实了解进行个性化,而非猜测。 要安全地持久化和预填哪些内容,通常需要通过客户测试来确定——存储状态中的错误假设比中性默认值更糟。
- 限定范围并征求同意。
sessionStorage用于单次会话,localStorage用于跨会话;绝不要在客户端存储敏感信息;遵守用户的同意选择。 - 每隔 2–3 年重新验证。 需求会变化;发布时合适的个性化设置,后来可能变成阻碍。应重新评估,最好进行新一轮测试。
输入方式检测
@media (hover: hover) {
/* hover states — mouse or trackpad */
.btn:hover { background: var(--color-primary-hover); }
}
@media (hover: none) {
/* touch device — no hover, larger targets */
.btn { min-height: 44px; }
}
指针精度
@media (pointer: coarse) {
/* fat-finger touch — increase target sizes */
.interactive { min-height: 44px; min-width: 44px; }
}
@media (pointer: fine) {
/* mouse — precise, can use smaller targets */
}
指针精度可以用于选择默认行为,而不只是确定目标大小。可通过 JavaScript 使用 matchMedia('(pointer: fine)') 读取同一个媒体查询,但如果交互模型因输入方式而异,应使用每个事件的 pointerType:例如,鼠标点击用于切换、指针用于平移,触屏则使用捏合和双击。切勿根据视口宽度推断输入类型;混合设备会让这种猜测失效。图片缩放场景请参阅 [[modal-and-overlay-patterns]]。
网络状况
<img src="product.jpg" loading="lazy" alt="...">
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="...">
</picture>
用户偏好
@media (prefers-reduced-motion: reduce) { /* disable animations */ }
@media (prefers-color-scheme: dark) { /* dark mode tokens */ }
@media (prefers-contrast: more) { /* increase contrast */ }
@media (forced-colors: active) { /* Windows high contrast mode */ }
审核清单
- 每个页面有一个
<h1>,标题构成合理的层级结构 - 使用语义化元素:
<main>、<nav>、<header>、<footer>、<article>、<section> - 每个
<img>都有有意义的alt;装饰性图片使用alt="" - 每个页面的
<title>都是唯一的,长度为 50–60 个字符,关键词置于开头 - 包含
<meta name="description">,长度为 120–160 个字符 - 所有可分享页面都包含 Open Graph 标签
- 可通过多个 URL 访问的页面包含
<link rel="canonical"> - 产品、文章和 FAQ 页面包含结构化数据(JSON-LD)
- 表单无需 JavaScript 也能正常使用
- SPA 在路由切换时更新
document.title和 meta 标签 - SPA 在路由切换时移动焦点
- 悬停状态限定在
@media (hover: hover)内 - 在
@media (pointer: coarse)下,触控目标尺寸至少为 44px - 首屏以下的图片使用
loading="lazy" - 遵循
prefers-reduced-motion设置