mcpField
S
semantic-html-and-seo

semantic-html-and-seo

github.com/dembrandt开发174916 次安装1 周前更新
代码仓库

关于 semantic-html-and-seo

这是一项指导团队编写语义化、易访问 HTML 和利于搜索的页面的开发技能,涵盖元数据、结构化数据、渐进增强及 SPA 的无障碍与 SEO。

主要功能

  1. 01语义化 HTML 结构
  2. 02图片替代文本指导
  3. 03SEO 元数据与结构化数据
  4. 04渐进增强实践
  5. 05SPA 无障碍与 SEO 检查

适用场景

  1. 01检查页面标题和文档结构
  2. 02完善元数据与社交分享卡片
  3. 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 设置

评论

支持 Markdown