この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:6
ページ更新者:guest
更新日時:2026-06-11 07:10:02

タイトル: リンク・ボタン
SEOタイトル: HTML のリンク(<a>)とボタン(<button>)の使い分けとアクセシブル実装

この記事の要点
  • ナビゲーション(別ページに移動)= <a href>アクション(送信・モーダル等)= <button>
  • <button>type 必須。フォーム内は既定 submit、それ以外は type="button"
  • <input type="submit"> もボタンだが、現代は <button type="submit"> が主流(中に HTML 入れられる)
  • <a> をボタン風に見せるのは OK(クラスで装飾)。ただし遷移しない処理には使わない(アクセシビリティ違反)
  • ARIA: role="button" + tabindex="0" + キーボード(Enter/Space)対応。可能なら素直に <button> を使う

リンクとボタンの正しい使い分け

HTML には別ページや別位置に「移動」させる <a> と、「何かを実行」させる <button> があります。この 2 つは見た目が似ていても、ユーザ・支援技術・SEO 視点では別物です。

判断使う要素
別 URL(または同一ページ内アンカー)に移動<a href>「商品詳細」「目次へ戻る」「外部サイト」
フォーム送信<button type="submit">「送信」「保存」
モーダル開閉・タブ切替・JS で何かを実行<button type="button">「開く」「コピー」「削除」
フォーム内容のリセット<button type="reset">「リセット」
新規タブで開きたい<a target="_blank" rel="noopener">外部リンク

基本構文

<!-- リンク:別ページへ移動 -->
<a href="/products/123">商品詳細を見る</a>

<!-- 外部リンク(noopener + 視覚ヒント) -->
<a href="https://example.com" target="_blank" rel="noopener noreferrer">
  外部サイト
  <span aria-hidden="true">↗</span>
</a>

<!-- ボタン:フォーム送信 -->
<form action="/login" method="post">
  <input name="email" type="email" required>
  <button type="submit">ログイン</button>
</form>

<!-- ボタン:JS でアクション -->
<button type="button" onclick="openModal()">モーダルを開く</button>

<!-- ボタン内に画像・アイコン -->
<button type="button" aria-label="検索">
  <svg width="20" height="20"><!-- 虫眼鏡 --></svg>
</button>

との違い

<!-- 古典: input -->
<input type="submit" value="送信">

<!-- 現代: button -->
<button type="submit">送信</button>

<!-- button の利点: HTML をネスト可能 -->
<button type="submit">
  <svg class="icon-send"></svg>
  <span>送信</span>
</button>

<input> はテキストしか入れられませんが、<button> はアイコン・改行・複数要素を入れられるので、現代では <button type="submit"> が主流です。

「リンクをボタン風」「ボタンをリンク風」の罠

見た目はクラスで自由に切り替えられますが、意味(セマンティクス)は要素そのもので決まります。

<!-- ✅ OK: リンクをボタン風に装飾(遷移する処理) -->
<a href="/signup" class="btn btn-primary">無料登録する</a>

<!-- ❌ NG: 遷移しない処理をリンクで実装 -->
<a href="javascript:void(0)" onclick="deleteUser()">削除</a>
<a href="#" onclick="openModal()">開く</a>
<!-- → 右クリックで「新規タブで開く」できてしまう
     → スクリーンリーダーは「リンク」と読み上げる
     → 遷移しないので混乱 -->

<!-- ✅ 修正: button を使う(クラスで見た目はリンク風に) -->
<button type="button" class="link-style" onclick="deleteUser()">
  削除
</button>

アクセシビリティ(ARIA・キーボード操作)

最良はネイティブ要素を使うことです。<button> は最初から:

  • Tab フォーカス可能
  • Enter / Space で発火
  • スクリーンリーダーが「ボタン」と読み上げ
  • 無効化 (disabled) 対応

どうしても <div><span> をボタンにしたい場合(既存デザインシステム等):

<!-- 全部自前で実装する必要がある -->
<div
  role="button"
  tabindex="0"
  onclick="doIt()"
  onkeydown="if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); doIt(); }"
  aria-label="保存"
  aria-disabled="false"
>
  保存
</div>

これだけ書くより、素直に <button> をスタイルした方が圧倒的に楽です。

主要 CSS フレームワークでの実装

フレームワーク典型コード
Tailwind CSS<button class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
Bootstrap 5<button class="btn btn-primary">
Material UI<Button variant="contained" color="primary">
shadcn/ui<Button variant="default">
Chakra UI<Button colorScheme="blue">

セキュリティ:target="_blank" の落とし穴

外部リンクを新規タブで開くとき、リンク先 JS から window.opener 経由で元ページを操作される(タブナビング攻撃)リスクがあります。必ず rel を付けます:

<!-- ❌ NG -->
<a href="https://external.com" target="_blank">外部</a>

<!-- ✅ OK -->
<a href="https://external.com" target="_blank" rel="noopener noreferrer">外部</a>

<!-- 注: モダンブラウザは target="_blank" で暗黙的に noopener を有効化
   しているが、互換性のため明示推奨 -->

無効化(disabled)の挙動の違い

要素無効化方法クリックフォーカス
<button disabled>属性無効飛ばす
<a>disabled 属性は無効常に発火飛ばさない
<a> 無効化したい場合href を外す or aria-disabled="true" + CSS pointer-events:none + tabindex="-1"無効飛ばす

UX のベストプラクティス

  • 主要 CTA(Call To Action)は1 ページに 1 つだけ強調色。すべてを目立たせると優先度が伝わらない
  • テキストは具体的に。「クリック」ではなく「資料をダウンロード」「無料体験を始める」
  • ボタンの最小タップサイズは 44×44 px(WCAG / iOS HIG / Material 共通)
  • ローディング中は disabled + 「送信中…」表示で二重送信防止
  • 破壊的操作(削除等)は確認ダイアログを挟むか、警告色 + アンドゥ可能に

FAQ

Q: type を書かない <button> の挙動は?
A: フォーム内では submit 扱いになります。これが原因でモーダル開くつもりがフォーム送信される事故が多発。必ず type="button" を明示してください。

Q: アイコンだけのボタンに aria-label は必要?
A: 必須です。スクリーンリーダー利用者にはアイコンが見えません。<button aria-label="検索"> で必ず代替テキストを。

Q: <a><button> でフォーカスリングが違う
A: ブラウザの既定スタイルが異なります。:focus-visible でデザインシステムに合わせ統一しましょう。