Communitygithub.com

karero/website-hero-carousel

网站英雄轮播:轮流展示的照片,以及确保它们始终如一的测试

website-hero-carousel 是什么?

这是一个面向 Astro 构建的网站英雄轮播组件。其核心特性在于“礼让”与“健壮性”:它确保页面高度不会因轮播照片变化而跳动,通过深色药丸形背景确保圆点指示器在任何颜色照片上都清晰可见;它尊重用户偏好(如减少动效),并在鼠标悬停、键盘聚焦或标签页隐藏时自动暂停。该技能不仅仅交付组件,更附带详尽的 Playwright 测试用例,用于捕捉常见的可访问性、布局和性能问题,例如:验证高度无跳动、测试 32px 最小点击目标、检查照片链接与圆点分离、以及针对所有轮播图片进行实时的对比度检测。该组件默认使用 Pause 按钮作为暂停机制(符合 WCAG 2.2.2),也提供圆点暂停选项。它内置英文和德文,无任何外部存储或网络请求,支持在 `templates/` 目录中一键安装。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/karero/croftweaver/tree/HEAD/skills/website-hero-carousel

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

网站英雄轮播:轮流展示的照片,以及确保它们始终如一的测试

页面顶部的一个照片展示区域,其中两张或多张照片每隔几秒轮流切换,每张照片对应一个圆点指示器。这看起来简单,实则不然:一张照片上的说明文字可能导致页面每次切换时跳动;白色圆点在浅色照片上会消失;手机需要比鼠标更大的点击目标;而移动内容本身也有自己的可访问性规则。本技能交付了组件,更重要的是,交付了能够捕捉所有这些问题的测试。

为什么这样构建?(请用自己的话对项目负责人说明)

  • 页面从不跳动。 所有照片共享一个位置,裁剪成统一形状,因此第一张照片的高度与最后一张相同。照片上没有说明文字或图片来源:它们正是导致原始网站页面跳动的原因。图片来源应归属到网站的图片版权页面。
  • 圆点在任何照片上都清晰可读。 它们位于一个小的深色药丸形背景上,因此在浅色天空和深色墙壁上都能显示。测试会通过测量浅色和深色照片上像素的实际对比度来验证这一点。
  • 无 JavaScript 也能工作。 此时照片会从上到下依次堆叠,且不显示任何控制按钮。
  • 保持礼貌。 当鼠标悬停、标签页隐藏、键盘焦点进入时,轮播会暂停;对于在设备上设置了“减少动效”的用户,轮播默认也不会启动。
  • 不存储、不发送任何信息。 无 Cookie、无本地存储、无跨站请求。

以及坦诚的弱点,让项目负责人首先从您这里听到:

  • 轮播照片并不总是更好的设计。 一张单一的强照片更安静、加载更快,且不会激怒任何人。请明确说明;由项目负责人决定。
  • 每一张额外的照片都会增加访客在手机上的下载时间。 三张照片各四种尺寸是可以的;十张则不行。请控制在少数几张。
  • “圆点暂停”模式用更简洁的照片展示换取了可见的控制按钮(请参见下方“暂停”部分)。

0. 这是正确的工具吗?(安装前请确认)

  1. 项目负责人是否确定要使用轮播? 一张照片不需要任何这些。请直接、坦诚地询问一次。
  2. 有多少张照片,并且它们的形状是否一致? 建议 2 到 5 张。任何形状都可行(每张照片会被裁剪成轮播的宽高比),但主体靠近边缘的照片在裁剪后可能会丢失部分内容:请用轮播的默认宽高比(16 / 9)和手机屏幕尺寸逐一查看每张照片。
  3. 照片是否链接到其他页面? 任何幻灯片都可以链接到一个页面(例如一个项目页面);混合链接和未链接的幻灯片也是可以的(CI 页面就是这样做的)。
  4. 选择哪种暂停模式? 请向项目负责人阅读下方的“暂停”部分,并让他们做出选择。默认为按钮模式。

1. 它为网站添加了什么

文件来自本技能的 templates/说明
src/components/HeroCarousel.astroHeroCarousel.astro标记、圆点、样式
src/components/hero-carousel-text.tshero-carousel-text.ts轮播显示的文本,包含英文和德文
public/js/hero-carousel.jshero-carousel.js脚本:将所有幻灯片放置在同一位置、旋转、处理控制按钮
tests/hero-carousel.spec.tshero-carousel.spec.ts从访客视角测试轮播(列表如下)

请安装所有四个文件。模板中不包含任何图片文件:照片是网站自己的资源,通过 props 传入。

一句话工作原理。 服务端会发送每一张幻灯片,一张接一张堆叠,控制按钮默认隐藏。脚本作为网站自己的一个文件存放在 public/js/ 目录下(而非内联脚本,这样严格的 script-src 'self' CSP 策略就能允许它运行),它会将幻灯片放置在一个网格单元格中,显示控制按钮,并标记当前显示的幻灯片。当前显示哪张幻灯片通过一个数据属性控制;CSS 负责剩下的所有工作,包括一秒钟的淡入效果。只有在其图片加载完成后,该幻灯片才会被显示,因此加载慢或加载失败的图片永远不会留下空白区域。

测试规格检查什么(从访客视角,测试构建好的实际页面):标记结构和每个圆点的名称;冻结时钟后精确到毫秒的切换间隔;Pause(暂停)按钮或圆点点击停止轮播,包括按钮标签和活动区域;键盘焦点(停止轮播、保持停止状态、Resume(恢复)按钮);鼠标悬停和移开后重新设定新间隔;减少动效;隐藏的标签页;延迟加载和加载失败的第二张图片;无 JavaScript 时的页面效果;在 1280、768 和 390 像素宽度下无高度跳动;确保未显示的幻灯片无法通过键盘焦点或辅助功能树访问;确保照片链接正常工作,且点击圆点永远不会打开链接;32 像素的点击目标(触屏设备为 44 像素);通过渲染像素检测圆点相对于每张照片上的药丸形背景的对比度;强制颜色模式;明暗两种主题下的 axe 可访问性测试;无存储和无网络请求;脚本是外部文件而非内联;淡入效果在动画中途和结束后进行验证,且在减少动效模式下不执行。

2. 安装(在分支上进行,并创建为 Pull Request:请参见 AGENTS.md §2)

  1. 将第 1 节中提到的四个文件复制到对应位置(先执行 mkdir -p public/js)。
  2. 将轮播组件放到页面上,位于该页面的 <Base> 组件内部,靠近顶部位置:
    ---
    import HeroCarousel from '../components/HeroCarousel.astro';
    import first from '../assets/hero-1.jpg';
    import second from '../assets/hero-2.jpg';
    ---
    <HeroCarousel label="作品照片" slides={[
      { image: first,  alt: '第一张照片展示的内容', label: '短名称', href: '/projects/one' },
      { image: second, alt: '第二张照片展示的内容',      label: '另一个名称' },
    ]} />
    
    • label:为屏幕阅读器说明轮播是什么。必填。
    • 每张幻灯片:image(导入的照片)、alt(描述图片内容的句子,至少 10 个字符:构建步骤会在少于 10 个字符时报错)、label(圆点的短名称)、href(可选)。
    • pause:"button"(默认)或 "dots"。swap:"instant"(默认)或 "fade"。intervalMs:默认 6000,不得低于 2000。ratio:默认 "16 / 9"。lang:页面自身的语言。 照片:JPEG 或 PNG 格式,宽度约为 2,400 像素,数量控制在页面所需范围内(构建步骤会为每张照片生成四种尺寸,AVIF 格式并带有 WebP 回退)。第一张照片会以高优先级加载;其余照片以低优先级加载并保持其位置。
  3. 语言。 组件内置英文和德文,并且会使用页面自身的语言(Base.astro 会将其作为 Astro.locals.lang 向下传递)。如需其他语言:请先按照下方的“添加语言”步骤操作。
  4. 在 tests/hero-carousel.spec.ts 中,将 PAGE(包含轮播的页面)、PAUSE 和 SWAP 设置为与页面传入的值一致(组件的默认值是 button 和 instant;测试规格需要显式写出这些值)。如果某个值为空,测试会失败。仅当页面传递了 lang 参数时才需要设置 LANG。 用于对比度测试的照片: 测试规格会使用轮播的真实照片,因此它反映的是项目负责人自己图片的实际情况。如果所有照片都是深色,那么“浅色照片上的白色圆点”测试就无法失败;为了观察测试失败的情况,可以手动添加一张浅色照片进行测试(第 3 节中的变更检查会这么做)。
  5. 运行 npm run check && npm test。

暂停(请在选择前向项目负责人说明)

自动启动、持续时间超过五秒且与其他内容相邻的移动内容,属于 WCAG 2.2.2,A 级标准,该标准要求“提供一种机制,让用户可以暂停、停止或隐藏它”(请阅读 https://www.w3.org/WAI/WCAG22/Understanding/pause-stop-hide.html)。同一页面将“暂停”定义为“由用户请求停止,且直到用户请求恢复之前不再继续”,并且并未要求该机制必须是可见的。该页面也没有讨论幻灯片指示器。

  • pause="button"(默认)。 在圆点旁边显示一个 Pause(暂停)按钮(暂停后变为 Resume(恢复))。可见、有名称,是公认且无争议的阅读方式,也是访客最易发现的方式。它的代价是:照片上会多出一个小小的文字。
  • pause="dots"。 没有按钮。点击一个圆点会显示对应照片并停止轮播,直到访客重新加载页面;键盘焦点进入时也会停止轮播;同时,“减少动效”模式下轮播会以停止状态启动。这很可能符合 2.2.2 标准的“机制”要求,但是没有任何方式告知访客点击圆点可以停止轮播,也没有任何方式可以恢复轮播。第一个使用此模式的网站是为了获得更干净的照片展示效果,并充分知晓这一取舍。

本技能不对其是否符合标准做出结论: “圆点暂停”模式是否被接受,由网站自己的审核者决定。 如果项目负责人选择了此模式,请在网站文档中写下一行说明,包含日期。

添加语言

当需要为网站添加新的语言,或者网站之后新增语言时。

  1. 首先阅读网站的语气指南(CONTENT_GUIDE.md;德文中需要注意使用“du”或“Sie”等尊称)。需要翻译的文本只有寥寥几个词:在语言允许的情况下,尽量不具体指向任何人。
  2. 在 src/components/hero-carousel-text.ts 中,将 TEXT 的 en 条目复制一份,将键名改为该语言的两位字母代码(例如 fr,而不是 fr-CA),并翻译每一个值;如果有任一值未翻译,npm run check 会失败。
  3. 按照第 2 节步骤 3 和 4 配置页面及其测试。

3. 试运行一次(供项目负责人查看),以及技能背后的检查机制

执行 npm run build && npm run preview 后,或者通过 Pull Request 的预览地址,项目负责人可以:

  1. 等待:照片会自动切换,当前显示的照片对应的圆点也会随之变化。
  2. 将鼠标悬停在轮播上:轮播会暂停。移开鼠标:经过一个完整间隔后,轮播继续。
  3. 在手机上:点击圆点(会显示对应照片);页面不会横向滚动;圆点易于点击。
  4. 在按钮模式下:按下“暂停”按钮,看到按钮变为“恢复”,再次按下。

本技能在构建时使用的检查清单,以便于评估模板的变更:每个检查点对应一个测试规格,当受保护的功能被移除时,对应的测试会失败。当模板发生变更时,手动执行一次验证(CI 作业会将这些模板安装到一个全新站点中,并在该站点使用的三种设置组合下运行测试规格):

从 HeroCarousel.astro 中移除以下内容对应的测试会失败
网格规则(display: grid, grid-area)“所有幻灯片共享一个位置…”
照片上的 aspect-ratio同一个测试(一张 4:3 的照片会更高)
药丸形背景的 background“在所有照片上渲染的对比度…”(浅色照片上的白色约为 1:1)
当前显示圆点的 border-width: 5px强制颜色测试
transition 规则淡入测试(“动画中途的一帧”)
未显示幻灯片上的 pointer-events: none“照片链接到其页面…”(正在渐出的幻灯片会接收点击)
脚本(hero-carousel.js)为未显示幻灯片设置的 inert 和 aria-hiddenTab 键和辅助功能树测试(正在移出的幻灯片的链接在淡出期间仍然可访问和可读)
脚本的 recover() 方法(当前正在显示的照片加载失败时,由第一张其他成功加载或即将加载的照片替换)“第一张图片加载失败…”

4. 隐私页面,以及如何回退

轮播不存储和不发送任何信息:无需在隐私页面中添加任何内容。

要移除轮播:删除四个文件,从页面中删除 <HeroCarousel> 代码块以及它使用的 import HeroCarousel 行(以及仅由它使用的图片导入);然后放回一张普通照片。系统中没有其他部分引用这些文件,除了受 PAGES 驱动的测试套件,但它们只会看到页面本身。

5. 本技能不包含的内容(以免造成误解)

上一张 / 下一张箭头、滑动手势、照片上的说明文字、照片上的来源信息、视频幻灯片、页面上多个轮播(其 ID 是固定的)、后续照片的懒加载。每一项都可以后续添加;但第一版中不需要任何这些功能。

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

相关技能