- Webブラウザに標準搭載されているラジオボタンは単純なHTML要素であるにもかかわらず、Shadcn UIライブラリではこれを複数階層のReactコンポーネントとして再構成している
- Shadcnの
<RadioGroup>と<RadioGroupItem>はRadix UIのコンポーネントをさらにラップし、lucide-reactアイコンと数十個のTailwindクラスを使用している
- Radixはアクセシビリティとカスタマイズ性のためにARIA属性を活用しているが、実際には基本の
<input type="radio">ではなくボタン要素を再利用している
- 単純なCSSだけでも同じスタイリングが可能であるにもかかわらず、この構造は数百行のコードと複数の依存関係を追加し、不必要な複雑さを招いている
- 基本のHTML要素を再利用しないことで性能低下と保守負担が大きくなり、Web開発の単純さが損なわれる
Shadcnのラジオボタン構造の分析
- Shadcnは
<RadioGroup>と<RadioGroupItem>の2つのコンポーネントを通じてラジオボタンを実装している
- 各コンポーネントは
@radix-ui/react-radio-groupから取り込んだプリミティブをラップし、lucide-reactのCircleIconを使用している
- 45行を超えるコードと3つの外部importを含み、30個を超えるTailwindクラスでスタイル指定している
- 単純な円形表示のためにSVGアイコンライブラリを読み込む構造
- CSSの
border-radiusや<circle>要素で代替できる機能である
Radix UIの役割
- Shadcnが使用するRadixはアクセシビリティとカスタマイズ性を重視した低レベルUIコンポーネントライブラリ
- Radixのラジオグループ実装は約215行のReactコードと7個のファイルをimportする
- Radixは
<button>要素にARIA属性を追加してラジオボタンのように動作するよう構成している
- しかし、W3CのARIA利用の第1原則では「可能な場合は標準のHTML要素を使うこと」と明記している
- Radixはこの原則に従わず、
<input>の代わりにボタンを再利用している
<form>内部でのみ隠された<input type="radio">を追加する構造になっており、一貫性に欠ける
CSSで可能な単純な代替案
- 標準のHTMLラジオボタンは
appearance: none、::before、:checked、border-radiusなどで容易にスタイリングできる
- 例示コードでは依存関係、JavaScript、ARIA属性なしで完全なカスタマイズを実現している
- 同じ効果はTailwindでも実装可能である
- 「ラジオボタンのスタイリングは難しい」という認識は過去の問題であり、現在では純粋なCSSだけで十分に制御可能
複雑さの蓄積という問題
- ShadcnとRadixを併用すると2つのライブラリと数百行のコードを理解しなければならない
- 単純なラジオボタン1つのために数KBのJavaScriptが追加で読み込まれる
- ユーザーはボタンの切り替えのためにJSの解析と実行を待たなければならない
- このような構造は認知負荷の増加、バグの可能性拡大、Web性能の低下につながる
単純さへの回帰
- ブラウザはすでにラジオボタンを標準提供しており、
<input type="radio" name="beverage" value="coffee" />の1行で十分
- 不必要な抽象化や入れ子になったライブラリの使用はWeb開発本来の単純さと効率を損なう
- 小さなUI要素であっても基本機能を再利用する設計が保守性と性能の両方に有利である
4件のコメント
退屈で衒学的:
すぐ終わるし、長く記憶に残る:
react aria のボタンコンポーネントを見たら気絶しそうww
私がフロントエンド分野だから長い間経験してきた問題なのですが、何というか本当に解決が難しい問題ではあります。実装は時代によってずっと変わっていますが、
input typeで解決しないのはどの時代でも同じですね...Webブラウザのラジオボタンやチェックボックスの動作をまねようとして、アクセシビリティ関連の仕様を別途実装するのはいったい何のためなのか... よく分かりません... 本文にあるようにCSSでも今は代案があるのに、どうしてもコンポーネントとして実装しようとするのを見ると、ちょっと笑ってしまいます。
Hacker Newsの意見
フロントエンドを頻繁に扱うわけではないが、Reactが主流になり始めた時点から複雑性が増す兆候は見えていた
他の抽象化レイヤーは単純化する傾向があるのに、Reactはその基盤技術よりはるかに複雑な抽象化を生み出している
Reactしか知らない開発者たちがますます高いレイヤーへ積み上げていき、過剰設計の結果を生んでいるように感じる
たとえば Shadcn や Radix はReact専用UIライブラリなのに、マーケティング文句だけ見ると一般的なUIライブラリのように見える
規模が大きくなると結局は自分専用のフレームワークを作るか、既存フレームワークに不満を抱くことになったが、Reactはその問題をある程度解決してくれる
React自体よりもエコシステムの過剰な複雑性が問題だと見ている。Reactさえうまく扱えれば、今でも楽しく使える
TailwindのようなツールでCSSを回避しようとしているだけだ。私はReactで状態管理はするが、スタイリングはCSSで直接やるほうを好む
チームメンバーにCSSを学ばせるよう説得するのがいちばん難しい
私はこうした「モダンな」フレームワークを避け、できるだけ基本技術を好む
Reactは単に「箱」を提供し、その中に何を入れるかは開発者が決める。それがReactの本当の力だ
このラジオボタンの例は笑えると同時に印象的だ
出来上がったものは標準CSSのラジオボタンと見分けがつかないのに、なぜここまで複雑にするのか疑問だ
大規模サイトの中で、こうした不要な複雑性なしに作られた事例があるのか気になる
今よりコード量は多かったが、インターフェースには即応性のあるスピード感があった
Takeoffプロジェクトのコード を参照できる
「Reactを選んでクビになった人はいない」という言葉のように、安全な選択になってしまっている
開発者は、デザイン要件にいつでも異議を唱えられることを覚えておくべきだ
React Nativeで単純なレイアウト問題に4時間を無駄にしていた開発者に「デザインを少し変えてもいいか聞いてみたら?」と言ったところ、10分で解決した
CSSさえしっかり書ければ十分に良い結果が得られる。こういうアプローチを使った人のおすすめがあれば知りたい
2025年最大の失敗はShadcnを選んだことだった
Radixを延々とimportしているのを見て最初の警告を感じ、radioコンポーネントを見て二度目の警告を感じた
すでにプロジェクトが進んでいたので諦めてCopilotで修正したが、結果としてAI依存になったことも気に入らなかった
以前のPOCのほうがずっと単純で効率的だった。いつか全部バニラHTMLで作り直したい
RemixやReact Router 7はそれでもWeb標準に近づけようとする試みがあった
Tailwindの時点で「これは違う」と感じたので、友人たちがリファクタリング後も良いと言うならそのとき見直すつもりだ
Reactにはpropsベースのスタイリングがあるのに、わざわざCSSクラスの塊を使う理由がない
アクセシビリティ重視ならRadix UIだけで十分だ
ブラウザの
<input>要素、とくにradioとselectはカスタマイズしにくいのが問題だ標準のラジオボタンはモバイルで使い勝手が悪い
モバイルでどんな問題があったのか、もっと具体的に知りたい
<label>で包んでパディングを与えれば、モバイルでも十分実用的だほとんどのプロジェクトは善意で始まるが、気づけば200行のラジオボタンコードと7つのimportで埋め尽くされる
こうしてコードの腐敗(code rot) が始まる
最近 daisyUI を使ってみたが、かなり気に入った
純粋なCSSベースなので、ブラウザの**新しい機能(dialogなど)**をうまく活用できる
たとえば Drawer はフォーカスを閉じ込められず、Accordion はラジオボタンをJS代替として乱用している
こうした理由でRadixのようなライブラリは複雑にならざるを得ない
記事の趣旨には共感するが、デザイナーがFigmaで作った正確なスタイルをすべてのブラウザで同一に実装するには、バニラCSSで可能なのか気になる
Radixのデモ のようなものを完全に再現できるだろうか?
CodePenの例 を参照できる
CSSだけ抜き出してシンプルなReactコンポーネントに貼れば十分だ
わずかな見た目の不一致を避けるために数十KBのコードと保守負担を追加することに、本当に価値があるのだろうか?
ナム・ジュン・パイクの言葉のように「完璧すぎると神が怒る」と感じる
本当のコストはコードではなくオンボーディング時間だ
新しく参加した開発者がRadixベースの47行のラジオボタンを理解するのに数週間かかる
一方、バニラ方式なら1日で作れ、20分で説明できる
もちろんFigmaやLinearのようにアクセシビリティとキーボードナビゲーションが重要な製品なら、その複雑性は正当化される
多くのコメントはShadcnを批判しているが、私はむしろコンポーネント構造と再利用性をうまく促進していると思う
Shadcnの核心は「コンポーネントを自分で所有し、自分で修正せよ」という哲学だ
これは既存のUIライブラリとは根本的に異なるアプローチだ