Accessibility Wiki

コミュニティ・ウィキ & フォーラム

カテゴリー

フロントエンド開発

最終更新

2024年1月

投稿者

アクティブな投稿者 42人

関連トピック

HTMLJavaScriptWeb Design

Build inclusive web experiences for everyone

Semantic HTML

Use semantic HTML elements to provide meaning and structure to your content for screen readers and assistive technologies.

<!-- Bad: Non-semantic -->
<div class="header">
  <div class="nav">
    <div class="nav-item">Home</div>
  </div>
</div>

<!-- Good: Semantic -->
<header>
  <nav>
    <a href="/">Home</a>
  </nav>
</header>

<main>
  <article>
    <h1>Article Title</h1>
    <p>Article content...</p>
  </article>
</main>

<footer>
  <p>&copy; 2025 Site Name</p>
</footer>

ARIA Attributes

Use ARIA attributes to enhance accessibility when semantic HTML isn't enough.

<!-- Button with ARIA label -->
<button aria-label="Close dialog" onClick={closeDialog}>
  <X className="icon" aria-hidden="true" />
</button>

<!-- Custom dropdown -->
<div role="listbox" aria-label="Select option">
  <div role="option" aria-selected="true">Option 1</div>
  <div role="option" aria-selected="false">Option 2</div>
</div>

<!-- Loading state -->
<div aria-live="polite" aria-busy="true">
  Loading content...
</div>

<!-- Form with error -->
<input
  type="email"
  aria-label="Email address"
  aria-invalid="true"
  aria-describedby="email-error"
/>
<span id="email-error" role="alert">
  Please enter a valid email
</span>

Keyboard Navigation

Ensure all interactive elements are keyboard accessible and have visible focus states.

/* Visible focus indicators */
button:focus-visible,
a:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* Skip to main content link */
.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: var(--primary);
  color: white;
  padding: 8px;
  text-decoration: none;
}

.skip-link:focus {
  top: 0;
}

/* Keyboard trap for modals */
function Modal({ onClose, children }) {
  const modalRef = useRef(null);
  
  useEffect(() => {
    const focusableElements = modalRef.current.querySelectorAll(
      'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
    );
    const firstElement = focusableElements[0];
    const lastElement = focusableElements[focusableElements.length - 1];
    
    firstElement?.focus();
    
    const trapFocus = (e) => {
      if (e.key === 'Tab') {
        if (e.shiftKey && document.activeElement === firstElement) {
          lastElement?.focus();
          e.preventDefault();
        } else if (!e.shiftKey && document.activeElement === lastElement) {
          firstElement?.focus();
          e.preventDefault();
        }
      }
    };
    
    document.addEventListener('keydown', trapFocus);
    return () => document.removeEventListener('keydown', trapFocus);
  }, []);
  
  return <div ref={modalRef} role="dialog">{children}</div>;
}

ディスカッション (0)

自分のアバター

感想を共有してください

まだコメントはありません。最初のディスカッションを始めましょう!