Shadcnラジオボタンの過剰な複雑さ
概要
- ShadcnとRadixのReactコンポーネントを使ったラジオボタンの実装事例
- ネイティブHTML要素とカスタムUIライブラリの比較
- ARIA属性やTailwind CSSによる複雑化の指摘
- CSSだけでのシンプルなカスタマイズ方法の紹介
- Web開発の複雑化とパフォーマンス低下への懸念
ShadcnとRadixによるラジオボタン実装の現状
- 仕事でWebアプリのラジオボタンのデザイン更新を依頼された体験談
- 伝統的な**<input type="radio">**要素のシンプルさの強調
- 実際のコードベースではShadcnのReactコンポーネント(RadioGroup, RadioGroupItem)を使用
- Shadcnは従来のUIフレームワークと異なり、npm installではなくコードを直接プロジェクトにコピーする運用
- コード内でRadixやLucide Reactなど複数の外部ライブラリ、30以上のTailwindクラスを利用
- SVGアイコンや複雑なクラス指定による肥大化と依存性の増加
- 例:CircleIconのためだけに外部アイコンライブラリを導入
Radixの仕組みと複雑化の原因
- ShadcnはRadix Primitivesをベースにスタイルを追加
- Radix自体はアクセシビリティやカスタマイズ性重視の「素の」UI部品群を提供
- 実際にはボタン要素+SVG+ARIA属性でラジオボタンを再実装
- ARIA属性で「ボタンをラジオボタンとして解釈させる」手法
- First Rule of ARIA(ネイティブ要素を優先)の原則に反する設計
- <form>内でのみ**隠し<input type="radio">**を追加する特殊な挙動
ラジオボタンのスタイリングは本当に難しいのか
- Radixがカスタム実装を選ぶ理由は「スタイリングの簡便化」と推測
- 近年はappearance: noneや**:checked**、::beforeなどのCSSだけで十分なカスタマイズが可能
- 例:CSSのみで丸いラジオボタン+選択時のドット表示を実現
- 依存ライブラリ・JS・ARIA不要
- Tailwindでも同様の実装が可能
- Shadcnのコンポーネントも結局は大量のクラス指定が必要
シンプルなHTML+CSSの例
- ネイティブの**<input type="radio">**とシンプルなCSSで十分な表現力
- 追加の依存や複雑なロジック不要
- 例:
input[type="radio"] { appearance: none; margin: 0; border: 1px solid black; background: white; border-radius: 50%; display: inline-grid; place-content: center; } input[type="radio"]::before { content: ""; width: 0.75rem; height: 0.75rem; border-radius: 50%; } input[type="radio"]:checked::before { background: black; }
ライブラリ利用の是非とWeb開発の複雑化
- コンポーネントライブラリ利用の動機は「手軽さ」と「問題解決への集中」
- ただし「できるだけネイティブ要素を使う」ことの重要性を強調
- 小さな最適化でも積み重なると複雑化・パフォーマンス低下・バグ増加の要因
- JS依存による初期表示遅延やファイルサイズ増加の懸念
- 結論:「ラジオボタンはシンプルでいい」「過剰な抽象化・ライブラリ依存は慎重に」
まとめ:本質を見失わないWeb開発
- ラジオボタンのような基本UIはブラウザの機能を活用
- 理解しやすさ・保守性・パフォーマンスを重視
- 小さな選択の積み重ねが全体の品質に影響
- シンプルなHTMLが持つ美しさと合理性
おまけ
- 「Tiled Words」という無料の単語パズルゲームの紹介