跳到正文
cccskills
免费在 GitHub 公开

accessibility

Audit and improve web accessibility following WCAG 2.2 guidelines. Use when asked to "improve accessibility", "a11y audit", "WCAG compliance", "screen reader support", "keyboard navigation", or "make accessible".

中文简介正在准备中。当前显示原文说明。

ever-works/ever-works星标 182(GitHub 182 + cccskills 0)

实测评分 未实测

查看安装方法

包含的文件(3)

  • SKILL.md12.4 KB
  • references/A11Y-PATTERNS.md5.9 KB
  • references/WCAG.md14.6 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Accessibility (a11y)

Comprehensive accessibility guidelines based on WCAG 2.2 and Lighthouse accessibility audits. Goal: make content usable by everyone, including people with disabilities.

WCAG Principles: POUR

PrincipleDescription
PerceivableContent can be perceived through different senses
OperableInterface can be operated by all users
UnderstandableContent and interface are understandable
RobustContent works with assistive technologies

Conformance levels

LevelRequirementTarget
AMinimum accessibilityMust pass
AAStandard complianceShould pass (legal requirement in many jurisdictions)
AAAEnhanced accessibilityNice to have

Perceivable

Text alternatives (1.1)

Images require alt text:

<!-- ❌ Missing alt -->
<img src="chart.png" />

<!-- ✅ Descriptive alt -->
<img src="chart.png" alt="Bar chart showing 40% increase in Q3 sales" />

<!-- ✅ Decorative image (empty alt) -->
<img src="decorative-border.png" alt="" role="presentation" />

<!-- ✅ Complex image with longer description -->
<figure>
	<img src="infographic.png" alt="2024 market trends infographic" aria-describedby="infographic-desc" />
	<figcaption id="infographic-desc">
		<!-- Detailed description -->
	</figcaption>
</figure>

Icon buttons need accessible names:

<!-- ❌ No accessible name -->
<button>
	<svg><!-- menu icon --></svg>
</button>

<!-- ✅ Using aria-label -->
<button aria-label="Open menu">
	<svg aria-hidden="true"><!-- menu icon --></svg>
</button>

<!-- ✅ Using visually hidden text -->
<button>
	<svg aria-hidden="true"><!-- menu icon --></svg>
	<span class="visually-hidden">Open menu</span>
</button>

Visually hidden class:

.visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

Color contrast (1.4.3, 1.4.6)

Text SizeAA minimumAAA enhanced
Normal text (< 18px / < 14px bold)4.5:17:1
Large text (≥ 18px / ≥ 14px bold)3:14.5:1
UI components & graphics3:13:1
/* ❌ Low contrast (2.5:1) */
.low-contrast {
	color: #999;
	background: #fff;
}

/* ✅ Sufficient contrast (7:1) */
.high-contrast {
	color: #333;
	background: #fff;
}

/* ✅ Focus states need contrast too */
:focus-visible {
	outline: 2px solid #005fcc;
	outline-offset: 2px;
}

Don't rely on color alone:

<!-- ❌ Only color indicates error -->
<input class="error-border" />
<style>
	.error-border {
		border-color: red;
	}
</style>

<!-- ✅ Color + icon + text -->
<div class="field-error">
	<input aria-invalid="true" aria-describedby="email-error" />
	<span id="email-error" class="error-message">
		<svg aria-hidden="true"><!-- error icon --></svg>
		Please enter a valid email address
	</span>
</div>

Media alternatives (1.2)

<!-- Video with captions -->
<video controls>
	<source src="video.mp4" type="video/mp4" />
	<track kind="captions" src="captions.vtt" srclang="en" label="English" default />
	<track kind="descriptions" src="descriptions.vtt" srclang="en" label="Descriptions" />
</video>

<!-- Audio with transcript -->
<audio controls>
	<source src="podcast.mp3" type="audio/mp3" />
</audio>
<details>
	<summary>Transcript</summary>
	<p>Full transcript text...</p>
</details>

Operable

Keyboard accessible (2.1)

All functionality must be keyboard accessible:

// ❌ Only handles click
element.addEventListener('click', handleAction);

// ✅ Handles both click and keyboard
element.addEventListener('click', handleAction);
element.addEventListener('keydown', (e) => {
	if (e.key === 'Enter' || e.key === ' ') {
		e.preventDefault();
		handleAction();
	}
});

No keyboard traps. Users must be able to Tab into and out of every component. Use the modal focus trap pattern for dialogs—the native <dialog> element handles this automatically.

Focus visible (2.4.7)

/* ❌ Never remove focus outlines */
*:focus {
	outline: none;
}

/* ✅ Use :focus-visible for keyboard-only focus */
:focus {
	outline: none;
}

:focus-visible {
	outline: 2px solid #005fcc;
	outline-offset: 2px;
}

/* ✅ Or custom focus styles */
button:focus-visible {
	box-shadow: 0 0 0 3px rgba(0, 95, 204, 0.5);
}

Focus not obscured (2.4.11) — new in 2.2

When an element receives keyboard focus, it must not be entirely hidden by other author-created content such as sticky headers, footers, or overlapping panels. At Level AAA (2.4.12), no part of the focused element may be hidden.

/* ✅ Account for sticky headers when scrolling to focused elements */
:target {
	scroll-margin-top: 80px;
}

/* ✅ Ensure focused items clear fixed/sticky bars */
:focus {
	scroll-margin-top: 80px;
	scroll-margin-bottom: 60px;
}

Skip links (2.4.1)

Provide a skip link so keyboard users can bypass repetitive navigation. See the skip link pattern for full markup and styles.

Target size (2.5.8) — new in 2.2

Interactive targets must be at least 24 × 24 CSS pixels (AA). Exceptions: inline text links, elements where the browser controls the size, and targets where a 24px circle centered on the bounding box does not overlap another target.

/* ✅ Minimum target size */
button,
[role='button'],
input[type='checkbox'] + label,
input[type='radio'] + label {
	min-width: 24px;
	min-height: 24px;
}

/* ✅ Comfortable target size (recommended 44×44) */
.touch-target {
	min-width: 44px;
	min-height: 44px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

Dragging movements (2.5.7) — new in 2.2

Any action that requires dragging must have a single-pointer alternative (e.g., buttons, inputs). See the dragging movements pattern for a sortable-list example.

Timing (2.2)

// Allow users to extend time limits
function showSessionWarning() {
	const modal = createModal({
		title: 'Session Expiring',
		content: 'Your session will expire in 2 minutes.',
		actions: [
			{ label: 'Extend session', action: extendSession },
			{ label: 'Log out', action: logout }
		],
		timeout: 120000
	});
}

Motion (2.3)

/* Respect reduced motion preference */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

Understandable

Page language (3.1.1)

<!-- ❌ No language specified -->
<html>
	<!-- ✅ Language specified -->
	<html lang="en">
		<!-- ✅ Language changes within page -->
		<p>The French word for hello is <span lang="fr">bonjour</span>.</p>
	</html>
</html>

Consistent navigation (3.2.3)

<!-- Navigation should be consistent across pages -->
<nav aria-label="Main">
	<ul>
		<li><a href="/" aria-current="page">Home</a></li>
		<li><a href="/products">Products</a></li>
		<li><a href="/about">About</a></li>
	</ul>
</nav>

Consistent help (3.2.6) — new in 2.2

If a help mechanism (contact info, chat widget, FAQ link, self-help option) is repeated across multiple pages, it must appear in the same relative order each time. Users who rely on consistent placement shouldn't have to hunt for help on every page.

Form labels (3.3.2)

Every input needs a programmatically associated label. See the form labels pattern for explicit, implicit, and instructional examples.

Error handling (3.3.1, 3.3.3)

Announce errors to screen readers with role="alert" or aria-live, set aria-invalid="true" on invalid fields, and focus the first error on submit. See the error handling pattern for full markup and JS.

Redundant entry (3.3.7) — new in 2.2

Don't force users to re-enter information they already provided in the same session. Auto-populate from earlier steps, or let users select from previously entered values. Exceptions: security re-confirmation and content that has expired.

<!-- ✅ Auto-fill shipping address from billing -->
<fieldset>
	<legend>Shipping address</legend>
	<label>
		<input type="checkbox" id="same-as-billing" checked />
		Same as billing address
	</label>
	<!-- Fields auto-populated when checked -->
</fieldset>

Accessible authentication (3.3.8) — new in 2.2

Login flows must not rely on cognitive function tests (e.g., remembering a password, solving a puzzle) unless at least one of:

  • A copy-paste or autofill mechanism is available
  • An alternative method exists (e.g., passkey, SSO, email link)
  • The test uses object recognition or personal content (AA only; AAA removes this exception)
<!-- ✅ Allow paste in password fields -->
<input type="password" id="password" autocomplete="current-password" />

<!-- ✅ Offer passwordless alternatives -->
<button type="button">Sign in with passkey</button>
<button type="button">Email me a login link</button>

Robust

ARIA usage (4.1.2)

Prefer native elements:

<!-- ❌ ARIA role on div -->
<div role="button" tabindex="0">Click me</div>

<!-- ✅ Native button -->
<button>Click me</button>

<!-- ❌ ARIA checkbox -->
<div role="checkbox" aria-checked="false">Option</div>

<!-- ✅ Native checkbox -->
<label><input type="checkbox" /> Option</label>

When ARIA is needed, use the correct roles and states. See the ARIA tabs pattern for a complete tablist example.

Live regions (4.1.3)

Use aria-live regions to announce dynamic content changes without moving focus. See the live regions pattern for markup and a showNotification() helper.


Testing checklist

Automated testing

# Lighthouse accessibility audit
npx lighthouse https://example.com --only-categories=accessibility

# axe-core
npm install @axe-core/cli -g
axe https://example.com

Manual testing

  • Keyboard navigation: Tab through entire page, use Enter/Space to activate
  • Screen reader: Test with VoiceOver (Mac), NVDA (Windows), or TalkBack (Android)
  • Zoom: Content usable at 200% zoom
  • High contrast: Test with Windows High Contrast Mode
  • Reduced motion: Test with prefers-reduced-motion: reduce
  • Focus order: Logical and follows visual order
  • Target size: Interactive elements meet 24×24px minimum

See the screen reader commands reference for VoiceOver and NVDA shortcuts.


Common issues by impact

Critical (fix immediately)

  1. Missing form labels
  2. Missing image alt text
  3. Insufficient color contrast
  4. Keyboard traps
  5. No focus indicators

Serious (fix before launch)

  1. Missing page language
  2. Missing heading structure
  3. Non-descriptive link text
  4. Auto-playing media
  5. Missing skip links

Moderate (fix soon)

  1. Missing ARIA labels on icons
  2. Inconsistent navigation
  3. Missing error identification
  4. Timing without controls
  5. Missing landmark regions

References

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

ai-sdk

免费

Answer questions about the AI SDK and help build AI-powered features. Use when developers: (1) Ask about AI SDK functions like generateText, streamText, ToolLoopAgent, embed, or tools, (2) Want to build AI agents, chatbots, RAG systems, or text generation features, (3) Have questions about AI providers (OpenAI, Anthropic, Google, etc.), streaming, tool calling, structured output, or embeddings, (4) Use React hooks like useChat or useCompletion. Triggers on: "AI SDK", "Vercel AI SDK", "generateText", "streamText", "add AI to my app", "build an agent", "tool calling", "structured output", "useChat".

中文简介正在准备中。当前显示原文说明。

ever-works/ever-works1822026年10月24日 更新

Configure Better Auth server and client, set up database adapters, manage sessions, add plugins, and handle environment variables. Use when users mention Better Auth, betterauth, auth.ts, or need to set up TypeScript authentication with email/password, OAuth, or plugin configuration.

中文简介正在准备中。当前显示原文说明。

ever-works/ever-works1822026年10月24日 更新

Deploy applications and websites to Vercel. Use when the user requests deployment actions like "deploy my app", "deploy and give me the link", "push this live", or "create a preview deployment".

中文简介正在准备中。当前显示原文说明。

ever-works/ever-works1822026年10月24日 更新

Configure email verification, implement password reset flows, set password policies, and customise hashing algorithms for Better Auth email/password authentication. Use when users need to set up login, sign-in, sign-up, credential authentication, or password security with Better Auth.

中文简介正在准备中。当前显示原文说明。

ever-works/ever-works1822026年10月24日 更新

Repo-specific guide to the Ever Works monorepo (ever-works/ever-works) — its pnpm + Turborepo layout, the per-workspace test runners (Jest vs Vitest vs Playwright), file-naming and import-alias conventions, the commit/branch model, and the real build/lint/type-check commands. Use this whenever working anywhere in this repository so changes match the codebase's actual conventions and pass CI.

中文简介正在准备中。当前显示原文说明。

ever-works/ever-works1822026年10月24日 更新

Use when a Task asks you to change an App Work — a running open-source application the owner forked, copied or linked into Ever Works — for example "add an SMS reminder", "fix the failed deployment of 3f9c2ab", or a Goal iteration or Mission Task filed on that App Work. Covers planning within the app's size guidance, respecting its protected paths and human-merge paths, running its declared checks, and writing a reviewable pull request against the branch the app deploys from.

中文简介正在准备中。当前显示原文说明。

ever-works/ever-works1822026年10月24日 更新

查看 ever-works 的全部技能

报告此技能的问题