概要
- 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」という無料の単語パズルゲームの紹介