frontend-accessibility-best-practices
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAccessibility Best Practices
无障碍设计最佳实践
Accessibility patterns for building inclusive React applications following WCAG standards. Contains 7 rules across 4 categories focused on semantic HTML, screen reader support, keyboard navigation, and user preferences.
遵循WCAG标准,构建包容性React应用的无障碍设计模式。包含4个类别下的7条规则,聚焦语义化HTML、屏幕阅读器支持、键盘导航和用户偏好设置。
When to Apply
适用场景
Reference these guidelines when:
- Creating new UI components
- Building forms and interactive elements
- Adding dynamic content or notifications
- Implementing navigation patterns
- Reviewing code for accessibility
在以下场景中参考本指南:
- 创建新的UI组件
- 构建表单与交互元素
- 添加动态内容或通知
- 实现导航模式
- 审查代码的无障碍合规性
Rules Summary
规则摘要
Semantic HTML & Structure (HIGH)
语义化HTML与结构(高优先级)
semantic-html-landmarks - @rules/semantic-html-landmarks.md
semantic-html-landmarks - @rules/semantic-html-landmarks.md
Use semantic HTML elements for page structure.
tsx
// Bad: divs with class names
<div className="header">...</div>
<div className="nav">...</div>
<div className="content">...</div>
// Good: semantic elements
<header>...</header>
<nav aria-label={t("Primary")}>...</nav>
<main>...</main>
<footer>...</footer>使用语义化HTML元素构建页面结构。
tsx
// 不良示例:使用带类名的div
<div className="header">...</div>
<div className="nav">...</div>
<div className="content">...</div>
// 良好示例:使用语义化元素
<header>...</header>
<nav aria-label={t("Primary")}>...</nav>
<main>...</main>
<footer>...</footer>Screen Readers (MEDIUM)
屏幕阅读器支持(中优先级)
screen-reader-sr-only - @rules/screen-reader-sr-only.md
screen-reader-sr-only - @rules/screen-reader-sr-only.md
Use sr-only class for visually hidden text.
tsx
// Icon-only buttons need accessible labels
<Button variant="icon" onPress={onClose}>
<XMarkIcon aria-hidden="true" />
<span className="sr-only">{t("Close")}</span>
</Button>
// Visually hidden section headings
<section>
<h2 className="sr-only">{t("Search results")}</h2>
<SearchResultsList />
</section>使用sr-only类实现视觉隐藏但屏幕阅读器可识别的文本。
tsx
// 仅含图标的按钮需要无障碍标签
<Button variant="icon" onPress={onClose}>
<XMarkIcon aria-hidden="true" />
<span className="sr-only">{t("Close")}</span>
</Button>
// 视觉隐藏的章节标题
<section>
<h2 className="sr-only">{t("Search results")}</h2>
<SearchResultsList />
</section>aria-live-regions - @rules/aria-live-regions.md
aria-live-regions - @rules/aria-live-regions.md
Announce dynamic content changes to screen readers.
tsx
// Error messages - announced immediately
{
error && (
<p role="alert" className="text-failure-600">
{error}
</p>
);
}
// Status updates - announced politely
<div role="status" aria-live="polite">
{t("{{count}} results found", { count })}
</div>;向屏幕阅读器播报动态内容的变化。
tsx
// 错误信息 - 立即播报
{
error && (
<p role="alert" className="text-failure-600">
{error}
</p>
);
}
// 状态更新 - 礼貌播报
<div role="status" aria-live="polite">
{t("{{count}} results found", { count })}
</div>;Keyboard & Focus (HIGH)
键盘与焦点管理(高优先级)
keyboard-navigation - @rules/keyboard-navigation.md
keyboard-navigation - @rules/keyboard-navigation.md
Use semantic elements for built-in keyboard support.
tsx
// Bad: div with onClick not keyboard accessible
<div onClick={handleClick}>Click me</div>
// Good: button has Enter/Space support
<button onClick={handleClick}>Click me</button>
// Good: react-aria Button handles everything
import { Button } from "react-aria-components";
<Button onPress={handlePress}>Click me</Button>使用语义化元素获得内置的键盘支持。
tsx
// 不良示例:带onClick的div不支持键盘访问
<div onClick={handleClick}>Click me</div>
// 良好示例:button支持Enter/Space键
<button onClick={handleClick}>Click me</button>
// 良好示例:react-aria Button处理所有细节
import { Button } from "react-aria-components";
<Button onPress={handlePress}>Click me</Button>focus-management - @rules/focus-management.md
focus-management - @rules/focus-management.md
Show visible focus indicators and trap focus in modals.
tsx
// Always use focus-visible for focus styles
<button className="focus-visible:ring-2 focus-visible:ring-teal-600">
Click me
</button>;
// react-aria Modal handles focus trapping automatically
import { Modal, Dialog } from "react-aria-components";
<Modal isOpen={isOpen}>
<Dialog>{/* Focus automatically trapped here */}</Dialog>
</Modal>;显示可见的焦点指示器,并在模态框中捕获焦点。
tsx
// 始终使用focus-visible设置焦点样式
<button className="focus-visible:ring-2 focus-visible:ring-teal-600">
Click me
</button>;
// react-aria Modal自动处理焦点捕获
import { Modal, Dialog } from "react-aria-components";
<Modal isOpen={isOpen}>
<Dialog>{/* 焦点自动在此处捕获 */}</Dialog>
</Modal>;User Preferences (MEDIUM)
用户偏好设置(中优先级)
reduced-motion - @rules/reduced-motion.md
reduced-motion - @rules/reduced-motion.md
Respect prefers-reduced-motion setting.
tsx
import { usePrefersReducedMotion } from "~/hooks/use-prefers-reduced-motion";
// CSS approach
<div className="animate-bounce motion-reduce:animate-none">
Bouncing content
</div>;
// JS approach
function AnimatedCounter({ value }) {
let prefersReducedMotion = usePrefersReducedMotion();
if (prefersReducedMotion) return <span>{value}</span>;
return <CountUp target={value} />;
}尊重prefers-reduced-motion设置。
tsx
import { usePrefersReducedMotion } from "~/hooks/use-prefers-reduced-motion";
// CSS实现方式
<div className="animate-bounce motion-reduce:animate-none">
Bouncing content
</div>;
// JS实现方式
function AnimatedCounter({ value }) {
let prefersReducedMotion = usePrefersReducedMotion();
if (prefersReducedMotion) return <span>{value}</span>;
return <CountUp target={value} />;
}touch-targets - @rules/touch-targets.md
touch-targets - @rules/touch-targets.md
Ensure 44x44px minimum touch targets.
tsx
// Icon buttons need explicit sizing
<Button variant="icon" className="h-11 w-11">
<XMarkIcon className="h-5 w-5" />
<span className="sr-only">{t("Close")}</span>
</Button>
// Links need padding for tappable area
<Link to={href} className="block py-3 px-4">
{label}
</Link>确保触摸目标的最小尺寸为44x44px。
tsx
// 图标按钮需要明确设置尺寸
<Button variant="icon" className="h-11 w-11">
<XMarkIcon className="h-5 w-5" />
<span className="sr-only">{t("Close")}</span>
</Button>
// 链接需要内边距来增加可点击区域
<Link to={href} className="block py-3 px-4">
{label}
</Link>Key Files
关键文件
- - Region, Heading, Main components
app/components/heading.tsx - - Reduced motion hook
app/hooks/use-prefers-reduced-motion.ts - - Accessible form field component
app/components/field/field.tsx
- - 区域、标题、主内容组件
app/components/heading.tsx - - 减少动画钩子
app/hooks/use-prefers-reduced-motion.ts - - 无障碍表单字段组件
app/components/field/field.tsx