ラジオボタンを実装してみた

こんにちは！
新卒1年目の小川です。

ウェブサイトでラジオボタンを使って「YES」か「NO」の選択を求めるシーンはよく見かけますが、一般的なラジオボタンでは視覚に頼った表現が多く、キーボードでの操作やスクリーンリーダー対応が不足している場合があります。
そこで今回は、アクセシビリティを意識した、シンプルで操作しやすいラジオボタンを実装してみました。
この記事では、その実装例をHTML、CSS、JavaScriptに分け、それぞれのポイントについても紹介していきたいと思います。

# ラジオボタンとは？
**ラジオボタン**とは、複数の選択肢の中から1つだけを選択するためのボタンの一種です。

# ラジオボタンの利用シーン

* 「はい」「いいえ」など、二択から選ぶ質問
* 「年齢層」「性別」など、複数の選択肢の中から1つのみを選ぶアンケート
* フィルタリングや条件指定などで、1つのオプションしか選べない場合

# 作成したコード
以下がアクセシビリティに配慮したラジオボタンのコードです。このコードでは、見た目をカスタマイズしながらも、キーボード操作やスクリーンリーダー対応を考慮しています。
実装したコードと実装のポイントをhtml、css、javascriptの３つに分けげ紹介します。

# html

## 実装例

```:html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>アクセシビリティ対応の選択ボタン</title>
</head>
<body>
    <div class="button-container">
        <button class="button" role="radio" aria-checked="false" aria-label="YES" tabindex="0">
            YES
        </button>
        <button class="button" role="radio" aria-checked="false" aria-label="NO" tabindex="0">
            NO
        </button>
    </div>
</body>
</html>
```

## 実装のポイント

* <button> 要素に role="radio" を追加し、これによりスクリーンリーダーがラジオボタンとして認識できるようにしています。
* aria-checked 属性で選択状態を示し、スクリーンリーダーでの読み上げをサポートしています。
* tabindex="0" を設定してキーボード操作が可能な要素にしています。

# css

## 実装例

```:css
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f4f8;
            font-family: Arial, sans-serif;
        }
        .button-container {
            display: flex;
            gap: 1rem;
        }
        .button {
            background-color: #e2e8f0;
            border: 2px solid black;
            border-radius: 0.5rem;
            padding: 2rem 6rem;
            font-weight: bold;
            font-size: 2rem;
            cursor: pointer;
            transition: background-color 0.3s, border-color 0.3s;
            outline: none;
            text-align: center;
            position: relative;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .button:focus {
            border-color: #4a90e2;
            box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.5);
        }
        .button.selected {
            background-color: #159fcf;
            color: black;
            border-color: #4a90e2;
        }
```

## 実装のポイント

* CSSボタンの選択状態やフォーカス状態にスタイルを設定しており、視覚的に選択されたことがわかるようにしています。
* :focus 擬似クラスでフォーカスリングを追加し、キーボードユーザーにも操作中であることを視覚的に示しています。
* .selected クラスで選択されたボタンに色を変更することで、選択が一目でわかるようにしています。
* フォントサイズを大きくし、文字の視認性を高めています。


# javascript

## 実装例

```:JavaScript
        document.addEventListener('DOMContentLoaded', function() {
            const buttons = document.querySelectorAll('.button');
            
            buttons.forEach(button => {
                button.addEventListener('click', function() {
                    buttons.forEach(btn => btn.classList.remove('selected'));
                    this.classList.add('selected');
                    this.setAttribute('aria-checked', 'true');
                    buttons.forEach(btn => {
                        if (btn !== this) {
                            btn.setAttribute('aria-checked', 'false');
                        }
                    });
                });

                button.addEventListener('keydown', function(event) {
                    if (event.key === 'Enter' || event.key === ' ') {
                        event.preventDefault(); // Prevent default action
                        this.click(); // Trigger click event
                    }
                });
            });
        });
```

## 実装のポイント

* DOMContentLoaded イベントでボタンにクリックイベントとキーボードイベントを設定しています。
* ボタンがクリックされた際、選択状態を切り替え、aria-checked 属性を更新することでスクリーンリーダーも選択を認識します。
* Enter キーと Space キーでボタンが押されるようにし、キーボード操作にも対応させています。

# 最後に
今回は、ラジオボタンを実際に作成してみました。
アクセシビリティに対応したものになるように調べながら作成を進めてきましたが、WCAGなどの基準にはまだ達成していない部分も多くあると思います。
少しずつでもアクセシビリティに対応したものが作れるように引き続き勉強していきたいと思います。
ここまで読んでいただきありがとうございました。