はじめに
「このタブ切り替え、アコーディオン、モーダル……全部JavaScriptで実装しなきゃ」と、条件反射的にstateやイベントリスナーを書き始めていませんか。実はその多くが、CSSだけで十分に実現できます。
You-Dont-Need-JavaScript は、まさにその発想を体現したリソース集です。:checked や :target、隣接セレクタといったCSSの機能を駆使することで、JavaScriptなしでもインタラクティブなUIが作れることを、実例とともに示してくれます。バンドルサイズを減らしたい、シンプルな実装で済ませたいと考えているフロントエンドエンジニアにとって、発想の引き出しを増やしてくれる一冊ならぬ「一リポジトリ」です。
You-Dont-Need-JavaScriptとは
You-Dont-Need-JavaScript は、GitHub上で公開されているオープンソースのリソース集で、「CSS is powerful, you can do a lot of things without JS.」というコンセプトのもと、CSSのみで実装したUIコンポーネントのサンプル集をまとめています。npmパッケージとして配布されているライブラリではなく、コードスニペットとデモを集めたリファレンスという位置づけです。
主な特徴
- 豊富なコンポーネント例 - アコーディオン、タブ、ドロップダウンメニュー、モーダル、カルーセル、ツールチップなど、実務でよく使うUIパターンが網羅されています
- コピペで使えるコード - 各サンプルは単体のHTML/CSSとして完結しており、そのままプロジェクトに組み込めます
- JS依存を減らす発想の学習 -
:checked、:target、:hover、隣接セレクタといったCSSセレクタの応用力を学べる教材としても優秀です
なお、READMEにも明記されている通り、ここで紹介されているテクニックはあくまで「CSSでもここまでできる」という概念実証(Proof of Concept)です。キーボード操作やスクリーンリーダーへの対応など、アクセシビリティ面で課題が残るサンプルも含まれているため、実プロダクトに導入する際はその点を補強する必要があります。
インストール
You-Dont-Need-JavaScript はnpmパッケージではなく、GitHub上のリポジトリとして公開されているコードスニペット集です。インストールというよりは、必要な部分を確認してコードを取り込む形で利用します。
# リポジトリをクローンしてローカルで確認する場合
git clone https://github.com/you-dont-need/You-Dont-Need-JavaScript.git
各サンプルはHTMLとCSSのみで完結しているため、READMEやデモページから該当箇所をコピーし、自分のプロジェクトのマークアップとスタイルに合わせて調整するだけで使い始められます。
基本的な使い方
代表的な例として、JavaScriptなしでタブ切り替えを実装してみましょう。ポイントは、非表示のradio要素とlabelを組み合わせ、:checked状態に応じて表示を切り替えるところです。
<div class="tabs">
<input type="radio" name="tab-group" id="tab1" checked class="tab-input" />
<label for="tab1" class="tab-label">概要</label>
<input type="radio" name="tab-group" id="tab2" class="tab-input" />
<label for="tab2" class="tab-label">使い方</label>
<input type="radio" name="tab-group" id="tab3" class="tab-input" />
<label for="tab3" class="tab-label">FAQ</label>
<div class="tab-content" id="content1">CSSだけでタブを実装できます。</div>
<div class="tab-content" id="content2">radioとlabelを組み合わせるのがコツです。</div>
<div class="tab-content" id="content3">JavaScriptは一切使っていません。</div>
</div>
.tabs {
display: flex;
flex-wrap: wrap;
}
.tab-input {
display: none;
}
.tab-label {
padding: 0.5rem 1rem;
cursor: pointer;
border-bottom: 2px solid transparent;
}
.tab-content {
display: none;
width: 100%;
padding: 1rem 0;
}
/* チェックされたタブに対応するコンテンツだけを表示 */
#tab1:checked ~ #content1,
#tab2:checked ~ #content2,
#tab3:checked ~ #content3 {
display: block;
}
.tab-input:checked + .tab-label {
border-bottom-color: currentColor;
font-weight: bold;
}
radioのname属性を揃えることで排他選択になり、:checkedの状態が変わるたびに、隣接する要素の表示・非表示がCSSだけで切り替わります。クリックイベントを拾ってstateを更新する処理は一切不要です。
実践的なユースケース
続いて、実務でよく使うアコーディオンをCSSのみで実装する例です。checkboxを使えば、複数の項目を独立して開閉できます。
<div class="accordion">
<input type="checkbox" id="acc1" class="accordion-input" />
<label for="acc1" class="accordion-header">利用規約について</label>
<div class="accordion-body">
ここに詳細な説明文が入ります。checkboxの状態に応じて開閉します。
</div>
<input type="checkbox" id="acc2" class="accordion-input" />
<label for="acc2" class="accordion-header">プライバシーポリシーについて</label>
<div class="accordion-body">
こちらも同様に、CSSだけで開閉アニメーションを実現しています。
</div>
</div>
.accordion-input {
display: none;
}
.accordion-header {
display: block;
padding: 0.75rem 1rem;
background: #f5f5f5;
cursor: pointer;
}
.accordion-body {
max-height: 0;
overflow: hidden;
padding: 0 1rem;
transition: max-height 0.3s ease, padding 0.3s ease;
}
.accordion-input:checked + .accordion-header + .accordion-body {
max-height: 200px;
padding: 0.75rem 1rem;
}
max-heightをtransitionさせることで、開閉時になめらかなアニメーションもつきます。ちょっとしたFAQページやサイドバーのメニュー開閉であれば、これだけでReactやVueのコンポーネントを1つ書かずに済んでしまいます。バンドルサイズを気にする軽量なランディングページや、静的サイトジェネレーターで生成したページに組み込む際に特に相性が良いテクニックです。
まとめ
You-Dont-Need-JavaScript は、タブやアコーディオン、モーダルといった「JavaScriptが必須」だと思い込みがちなUIの多くが、実はCSSの:checkedや隣接セレクタだけで実装できることを教えてくれるリソース集でした。すべてのケースでJSを置き換えるべきというわけではありませんが、「本当にJSが必要か」を一度立ち止まって考える良いきっかけになります。
まずはリポジトリのデモをいくつか眺めて、自分のプロジェクトで使えそうなパターンを探してみてください。CSSセレクタへの理解が深まると同時に、より軽量でシンプルな実装の引き出しが増えるはずです。