← Back to list

accessibility
by CeamKrier
Browser-based tool to combine and format multiple files for optimal use with AI language models (ChatGPT, Claude, etc.).
⭐ 2🍴 0📅 Jan 17, 2026
SKILL.md
name: accessibility description: Implement web accessibility (a11y) patterns including ARIA attributes, keyboard navigation, focus management, and screen reader support. Use for any UI component or interactive element.
Accessibility (a11y)
When to Use This Skill
Use when:
- Building interactive components (modals, dropdowns, tabs)
- Implementing keyboard navigation
- Adding screen reader support
- Ensuring color contrast compliance
Semantic HTML First
// ❌ Non-semantic
<div onClick={handleClick}>Click me</div>
// ✅ Semantic
<button onClick={handleClick}>Click me</button>
ARIA Attributes
Common ARIA Patterns
// Button with loading state
<button
aria-busy={isLoading}
aria-disabled={isLoading}
>
{isLoading ? 'Loading...' : 'Submit'}
</button>
// Expandable section
<button
aria-expanded={isOpen}
aria-controls="panel-1"
>
Toggle Panel
</button>
<div id="panel-1" hidden={!isOpen}>
Panel content
</div>
// Live regions (for dynamic updates)
<div aria-live="polite" aria-atomic="true">
{statusMessage}
</div>
Dialog/Modal Pattern
function Modal({ isOpen, onClose, title, children }: ModalProps) {
const modalRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (isOpen) {
modalRef.current?.focus();
}
}, [isOpen]);
return isOpen ? (
<div
ref={modalRef}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
tabIndex={-1}
>
<h2 id="modal-title">{title}</h2>
{children}
<button onClick={onClose}>Close</button>
</div>
) : null;
}
Keyboard Navigation
Focus Trap for Modals
function useFocusTrap(isActive: boolean) {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!isActive) return;
const container = containerRef.current;
if (!container) return;
const focusableElements = container.querySelectorAll<HTMLElement>(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
const firstElement = focusableElements[0];
const lastElement = focusableElements[focusableElements.length - 1];
const handleKeyDown = (e: KeyboardEvent) => {
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();
}
};
container.addEventListener('keydown', handleKeyDown);
firstElement?.focus();
return () => container.removeEventListener('keydown', handleKeyDown);
}, [isActive]);
return containerRef;
}
Arrow Key Navigation
function useArrowNavigation(items: HTMLElement[]) {
const handleKeyDown = useCallback((e: KeyboardEvent) => {
const currentIndex = items.findIndex(
item => item === document.activeElement
);
let nextIndex = currentIndex;
switch (e.key) {
case 'ArrowDown':
case 'ArrowRight':
nextIndex = (currentIndex + 1) % items.length;
break;
case 'ArrowUp':
case 'ArrowLeft':
nextIndex = (currentIndex - 1 + items.length) % items.length;
break;
case 'Home':
nextIndex = 0;
break;
case 'End':
nextIndex = items.length - 1;
break;
default:
return;
}
e.preventDefault();
items[nextIndex]?.focus();
}, [items]);
return handleKeyDown;
}
Focus Management
// Skip link pattern
<a href="#main-content" className="sr-only focus:not-sr-only">
Skip to main content
</a>
// Focus visible styling (Tailwind)
<button className="focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500">
Click me
</button>
Screen Reader Only Content
/* Tailwind: sr-only */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
<button>
<Icon name="trash" />
<span className="sr-only">Delete item</span>
</button>
Color Contrast
- Normal text: 4.5:1 contrast ratio minimum
- Large text (18px+): 3:1 contrast ratio minimum
- UI components: 3:1 contrast ratio minimum
Accessibility Checklist
- All interactive elements are keyboard accessible
- Focus order is logical and visible
- Images have alt text (or alt="" for decorative)
- Form inputs have associated labels
- Color is not the only way to convey information
- Modals trap focus and can be closed with Escape
- Dynamic content updates are announced to screen readers
Score
Total Score
65/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
○LICENSE
ライセンスが設定されている
0/10
✓説明文
100文字以上の説明がある
+10
○人気
GitHub Stars 100以上
0/15
✓最近の活動
1ヶ月以内に更新
+10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
✓タグ
1つ以上のタグが設定されている
+5
Reviews
💬
Reviews coming soon

