Token导航 LogoToken导航TokenDH.com
研究检索只读github未标认证来源可访问许可证需确认审计通过

web-accessibility网络可访问性

Agent Skill

用于辅助无障碍访问检查、页面可用性审计和前端可访问性改进。它适合让 Agent 检查语义标签、键盘操作、颜色对比、ARIA 属性和自动化检测结果。使用时需要结合真实页面和浏览器验证,不应只依赖静态文本判断;涉及修复建议时,应兼顾设计系统、组件复用和 WCAG 等通用无障碍规范。

总安装

380

周安装

16

GitHub Stars

1

下载量

133
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:web-accessibility(网络可访问性)
来源仓库:https://github.com/alexanderstephenthompson/claude-hub
仓库路径:skills/web-accessibility
安装命令:
npx skills add https://github.com/alexanderstephenthompson/claude-hub --skill web-accessibility
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/alexanderstephenthompson/claude-hub --skill web-accessibility

简介

用于辅助网页无障碍访问检查与前端可访问性改进,支持语义标签、键盘操作和 ARIA 属性分析。

  • 适合在 Codex、Claude、Cursor、Gemini CLI 中执行页面可用性审计或生成 WCAG 合规建议。
  • 使用时需结合真实浏览器预览验证结果,不应仅依赖静态文本判断修复效果。
  • 安装方式:通过 npx skills add 命令从指定 GitHub 仓库添加,适用于主流 AI 宿主平台。
  • 涉及设计系统调整时,应兼顾组件复用规范与通用无障碍标准如 WCAG 2.1 AA。

SKILL.md

Web Accessibility Skill

Version: 1.0 Standard: WCAG 2.1 Level AA

Accessibility is not optional. These patterns ensure all users can use your application.

The Problem

AI agents build interfaces that look correct but aren't accessible. Without explicit WCAG standards, each session skips alt text, uses divs instead of buttons, nests headings incorrectly, and omits keyboard navigation — not from intent but from path-of-least-resistance. Each session introduces slightly different accessibility gaps, making remediation a moving target. These standards ensure accessibility is built in from the first element.

Consumption

  • Builders: Read ## Builder Checklist before writing any HTML or component markup. Accessibility must be designed in, not patched via ARIA after the fact.
  • Refactorers: Use ## Enforced Rules to find accessibility violations. Read narrative sections for remediation patterns.
  • Both: Narrative sections are the authoritative standard. Checklist and rules table are compressed views of the same content.

Scope and Boundaries

This skill covers:

  • WCAG 2.1 Level AA compliance
  • POUR principles (Perceivable, Operable, Understandable, Robust)
  • Semantic HTML for accessibility (landmarks, headings, buttons vs links)
  • Keyboard navigation and focus management
  • Focus trapping for modals
  • ARIA usage patterns and roles
  • Form accessibility (labels, errors, required fields)
  • Color contrast requirements
  • Images and media alt text
  • Dynamic content and live regions
  • Reduced motion support
  • Screen reader testing

Defers to other skills:

  • design: Design token system, overall design principles, component states
  • web-css: CSS implementation details, file organization, responsive breakpoints

Use this skill when: You need WCAG compliance, screen reader support, focus management, or ARIA patterns. Use design when: You need design system principles, token enforcement, or layout philosophy. Use web-css when: You need CSS architecture or responsive implementation.


Core Principles (POUR)

  1. Perceivable — Users can perceive all content (see, hear, or feel it).
  2. Operable — Users can operate all controls (keyboard, mouse, voice, etc.).
  3. Understandable — Users can understand content and interface behavior.
  4. Robust — Content works with current and future assistive technologies.

Semantic HTML First

Use the Right Element

<!-- ✅ Good - Semantic elements -->
<header>Site header</header>
<nav>Navigation</nav>
<main>
  <article>
    <h1>Article Title</h1>
    <p>Content...</p>
  </article>
  <aside>Related content</aside>
</main>
<footer>Site footer</footer>

<!-- ❌ Bad - Div soup -->
<div class="header">Site header</div>
<div class="nav">Navigation</div>
<div class="main">
  <div class="article">
    <div class="title">Article Title</div>
    <div class="content">Content...</div>
  </div>
</div>

Buttons vs Links

// ✅ Button - Performs an action
<button onClick={handleSubmit}>Submit Form</button>
<button onClick={openModal}>Open Settings</button>

// ✅ Link - Navigates somewhere
<a href="/products">View Products</a>
<Link to="/checkout">Proceed to Checkout</Link>

// ❌ Bad - Wrong semantics
<div onClick={handleSubmit}>Submit Form</div>
<a onClick={openModal}>Open Settings</a>  {/* No href! */}
<button onClick={() => navigate('/products')}>View Products</button>

Heading Hierarchy

// ✅ Good - Proper hierarchy
<h1>Page Title</h1>
<section>
  <h2>Section Title</h2>
  <h3>Subsection</h3>
</section>
<section>
  <h2>Another Section</h2>
</section>

// ❌ Bad - Skipped levels
<h1>Page Title</h1>
<h3>Subsection</h3>  {/* Skipped h2! */}
<h5>Deep section</h5> {/* Skipped h4! */}

Keyboard Navigation

Focus Management

/* Visible focus indicator */
:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* Remove outline only for mouse users */
:focus:not(:focus-visible) {
  outline: none;
}

Tab Order

// ✅ Good - Logical tab order (follows DOM order)
<form>
  <label htmlFor="email">Email</label>
  <input id="email" type="email" />

  <label htmlFor="password">Password</label>
  <input id="password" type="password" />

  <button type="submit">Login</button>
</form>

// ❌ Bad - Jumpy tab order
<form>
  <button type="submit" tabIndex={1}>Login</button>
  <input tabIndex={3} />
  <input tabIndex={2} />
</form>

Skip Links

// At the very top of your app
function SkipLink() {
  return (
    <a href="#main-content" className="skip-link">
      Skip to main content
    </a>
  );
}

// CSS
.skip-link {
  position: absolute;
  top: -100%;
  left: var(--space-4);
  padding: var(--space-2) var(--space-4);
  background: var(--color-surface);
  z-index: var(--z-tooltip);
}

.skip-link:focus {
  top: var(--space-4);
}

Keyboard Shortcuts

// Listen for keyboard events
function SearchModal({ isOpen, onClose }) {
  useEffect(() => {
    function handleKeyDown(e) {
      if (e.key === 'Escape') {
        onClose();
      }
    }

    if (isOpen) {
      document.addEventListener('keydown', handleKeyDown);
      return () => document.removeEventListener('keydown', handleKeyDown);
    }
  }, [isOpen, onClose]);

  // ...
}

Focus Trapping (Modals)

Modal Pattern

import { useEffect, useRef } from 'react';
import { createPortal } from 'react-dom';

function Modal({ isOpen, onClose, title, children }) {
  const modalRef = useRef(null);
  const previousFocus = useRef(null);

  useEffect(() => {
    if (isOpen) {
      // Store current focus
      previousFocus.current = document.activeElement;

      // Focus the modal
      modalRef.current?.focus();

      // Trap focus inside modal
      const modal = modalRef.current;
      const focusableElements = modal?.querySelectorAll(
        'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
      );
      const firstElement = focusableElements?.[0];
      const lastElement = focusableElements?.[focusableElements.length - 1];

      function handleTab(e) {
        if (e.key !== 'Tab') return;

        if (e.shiftKey && document.activeElement === firstElement) {
          e.preventDefault();
          lastElement?.focus();
        } else if (!e.shiftKey && document.activeElement === lastElement) {
          e.preventDefault();
          firstElement?.focus();
        }
      }

      modal?.addEventListener('keydown', handleTab);
      return () => modal?.removeEventListener('keydown', handleTab);
    } else {
      // Restore focus when closing
      previousFocus.current?.focus();
    }
  }, [isOpen]);

  if (!isOpen) return null;

  return createPortal(
    <div className="modal-backdrop" onClick={onClose}>
      <div
        ref={modalRef}
        role="dialog"
        aria-modal="true"
        aria-labelledby="modal-title"
        className="modal"
        onClick={(e) => e.stopPropagation()}
        tabIndex={-1}
      >
        <h2 id="modal-title">{title}</h2>
        {children}
        <button onClick={onClose} aria-label="Close modal">
          ×
        </button>
      </div>
    </div>,
    document.body
  );
}

ARIA Usage

When to Use ARIA

First rule of ARIA: Don't use ARIA if you can use native HTML.

// ❌ Unnecessary ARIA
<div role="button" tabIndex={0} onClick={handleClick}>
  Click me
</div>

// ✅ Just use a button
<button onClick={handleClick}>Click me</button>

Essential ARIA Patterns

// Labeling
<button aria-label="Close menu">×</button>
<input aria-labelledby="name-label helper-text" />

// Descriptions
<button aria-describedby="delete-warning">Delete Account</button>
<p id="delete-warning">This action cannot be undone.</p>

// States
<button aria-pressed={isActive}>Toggle</button>
<button aria-expanded={isOpen} aria-controls="menu">Menu</button>
<div id="menu" aria-hidden={!isOpen}>Menu content</div>

// Live regions (for dynamic content)
<div aria-live="polite" aria-atomic="true">
  {statusMessage}
</div>

Common ARIA Roles

RoleUse Case
alertImportant messages (errors, warnings)
alertdialogModal requiring user response
dialogModal dialogs
navigationNavigation sections
searchSearch forms
tablist, tab, tabpanelTab interfaces
menu, menuitemDropdown menus
statusStatus updates (loading, saving)

Forms

Labels

// ✅ Explicit label association
<label htmlFor="email">Email Address</label>
<input id="email" type="email" />

// ✅ Implicit association (wrapped)
<label>
  Email Address
  <input type="email" />
</label>

// ❌ Bad - No association
<span>Email Address</span>
<input type="email" />

Error Messages

function FormField({ id, label, error, ...props }) {
  const errorId = `${id}-error`;

  return (
    <div className="form-field">
      <label htmlFor={id}>{label}</label>
      <input
        id={id}
        aria-invalid={!!error}
        aria-describedby={error ? errorId : undefined}
        {...props}
      />
      {error && (
        <p id={errorId} className="error-message" role="alert">
          {error}
        </p>
      )}
    </div>
  );
}

Required Fields

<label htmlFor="name">
  Name <span aria-hidden="true">*</span>
  <span className="visually-hidden">(required)</span>
</label>
<input id="name" required aria-required="true" />

Color and Contrast

Minimum Contrast Ratios

Text TypeRatioExample
Normal text (< 18px)4.5:1Body copy
Large text (≥ 18px or 14px bold)3:1Headings
UI components3:1Buttons, inputs

Don't Rely on Color Alone

// ❌ Bad - Color is only indicator
<span style={{ color: error ? 'red' : 'green' }}>
  {error ? 'Invalid' : 'Valid'}
</span>

// ✅ Good - Color + icon + text
<span className={error ? 'error' : 'success'}>
  {error ? (
    <>
      <ErrorIcon aria-hidden="true" /> Invalid: {error}
    </>
  ) : (
    <>
      <CheckIcon aria-hidden="true" /> Valid
    </>
  )}
</span>

Images and Media

Alt Text

// Informative image
<img src="chart.png" alt="Sales increased 40% from January to March" />

// Decorative image
<img src="divider.png" alt="" role="presentation" />

// Complex image
<figure>
  <img src="diagram.png" alt="Architecture diagram" aria-describedby="diagram-desc" />
  <figcaption id="diagram-desc">
    The system consists of three layers: presentation, business logic, and data.
    {/* Full description */}
  </figcaption>
</figure>

SVG Icons

// Decorative icon (with visible text)
<button>
  <SearchIcon aria-hidden="true" />
  Search
</button>

// Standalone icon (needs label)
<button aria-label="Search">
  <SearchIcon aria-hidden="true" />
</button>

// Icon with title
<svg role="img" aria-labelledby="icon-title">
  <title id="icon-title">Search</title>
  <path d="..." />
</svg>

Dynamic Content

Loading States

function ProductList() {
  const { data, loading, error } = useQuery(GET_PRODUCTS);

  if (loading) {
    return (
      <div role="status" aria-live="polite">
        <Spinner aria-hidden="true" />
        <span className="visually-hidden">Loading products...</span>
      </div>
    );
  }

  if (error) {
    return (
      <div role="alert">
        Error loading products. Please try again.
      </div>
    );
  }

  return (
    <ul aria-label="Products">
      {data.products.map(product => (
        <li key={product.id}>{product.name}</li>
      ))}
    </ul>
  );
}

Live Regions

// Polite - Waits for user to finish current task
<div aria-live="polite" aria-atomic="true">
  {saveStatus} {/* "Saving...", "Saved!", etc. */}
</div>

// Assertive - Interrupts immediately (use sparingly)
<div aria-live="assertive" role="alert">
  {errorMessage}
</div>

Reduced Motion

/* Respect user 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;
  }
}
// In React
function AnimatedComponent() {
  const prefersReducedMotion = window.matchMedia(
    '(prefers-reduced-motion: reduce)'
  ).matches;

  return (
    <motion.div
      animate={{ opacity: 1 }}
      transition={{
        duration: prefersReducedMotion ? 0 : 0.3,
      }}
    />
  );
}

Visually Hidden Text

.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;
}
// Use for screen reader only content
<button>
  <TrashIcon aria-hidden="true" />
  <span className="visually-hidden">Delete item</span>
</button>

<a href="/products">
  View all products
  <span className="visually-hidden"> in the catalog</span>
</a>

Testing Accessibility

Automated Testing

// jest + jest-axe
import { axe, toHaveNoViolations } from 'jest-axe';

expect.extend(toHaveNoViolations);

it('has no accessibility violations', async () => {
  const { container } = render(<ProductCard product={mockProduct} />);
  const results = await axe(container);
  expect(results).toHaveNoViolations();
});

Manual Testing Checklist

  • Navigate entire page with keyboard only
  • Use screen reader (VoiceOver, NVDA)
  • Zoom to 200% - still usable?
  • Check with browser accessibility inspector
  • Test with high contrast mode
  • Test with reduced motion enabled

Anti-Patterns

Anti-PatternProblemFix
Divs for everythingNo semantics for ATUse semantic HTML
tabIndex > 0Breaks natural tab orderRemove positive tabIndex
Outline: noneNo focus indicatorUse:focus-visible
ARIA overuseComplex, error-proneNative HTML first
Color-only meaningInvisible to colorblindAdd icons, text
Auto-playing mediaDisorienting, annoyingUser-initiated only
Mouse-only interactionsExcludes keyboard usersAdd keyboard handlers
Missing alt textImages invisible to SRDescribe or mark decorative
Non-descriptive links"Click here" is uselessDescriptive link text

Builder Checklist

Before writing UI code governed by this skill, verify your plan against these constraints. Builders read this section before writing code; refactorers use the Enforced Rules table and full narrative instead.

Semantic HTML

  • Correct heading hierarchy
  • Buttons for actions, links for navigation
  • Semantic landmarks (header, nav, main, footer)
  • Lists use ul/ol/li

Keyboard

  • All interactive elements focusable
  • Visible focus indicators
  • Logical tab order
  • Skip link present
  • Modals trap focus

Screen Readers

  • All images have alt text
  • Form inputs have labels
  • Error messages linked to inputs
  • Dynamic content uses live regions
  • Icons have accessible names

Visual

  • Color contrast meets 4.5:1
  • Color is not only indicator
  • Works at 200% zoom
  • Reduced motion respected

Forms

  • All inputs labeled
  • Required fields indicated
  • Errors clearly identified
  • Error messages helpful

Enforced Rules

These rules are deterministically checked by check.js (clean-team). When updating these standards, update the corresponding check.js rules to match — and vice versa.

Rule IDSeverityWhat It Checks
img-alt-requirederror<img> without alt attribute
title-requirederrorMissing <title> element
tabindex-no-positiveerrorPositive tabindex values (breaks tab order)
heading-orderwarnHeading levels that skip (h1 → h3)
single-h1warnMultiple <h1> elements per page
no-div-as-buttonwarn<div>/<span> with onclick handler

Resources

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

35.7%
按下载量换算47

Claude

29.1%
按下载量换算39

Cursor

18.99%
按下载量换算25

Gemini CLI

8.38%
按下载量换算11

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

只读

该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills