Die übermäßige Komplexität der Radio-Buttons von Shadcn
(paulmakeswebsites.com)- Obwohl Radio-Buttons als grundlegend im Webbrowser eingebaute HTML-Elemente eigentlich simpel sind, werden sie in der Shadcn-UI-Bibliothek als mehrere Schichten von React-Komponenten neu aufgebaut.
- Shadcns
<RadioGroup>und<RadioGroupItem>umschließen wiederum Komponenten von Radix UI und verwenden lucide-react-Icons sowie Dutzende von Tailwind-Klassen. - Radix nutzt für Barrierefreiheit und Anpassbarkeit ARIA-Attribute, verwendet in der Praxis jedoch statt des nativen
<input type="radio">wiederverwendete Button-Elemente. - Obwohl sich dasselbe Styling auch mit einfachem CSS erreichen ließe, fügt diese Struktur Hunderte Zeilen Code und mehrere Abhängigkeiten hinzu und verursacht unnötige Komplexität.
- Weil native HTML-Elemente nicht wiederverwendet werden, nehmen Leistungseinbußen und Wartungsaufwand zu, und die Einfachheit der Webentwicklung wird untergraben.
Analyse der Struktur der Shadcn-Radio-Buttons
- Shadcn implementiert Radio-Buttons über die beiden Komponenten
<RadioGroup>und<RadioGroupItem>.- Jede Komponente umschließt Primitives aus
@radix-ui/react-radio-groupund verwendet das CircleIcon auslucide-react. - Enthalten sind mehr als 45 Zeilen Code, 3 externe Imports und ein Styling mit mehr als 30 Tailwind-Klassen.
- Jede Komponente umschließt Primitives aus
- Für die Darstellung eines einfachen Kreises wird sogar eine SVG-Icon-Bibliothek eingebunden.
- Eine Funktion, die sich auch durch
border-radiusin CSS oder ein<circle>-Element ersetzen ließe.
- Eine Funktion, die sich auch durch
Die Rolle von Radix UI
- Das von Shadcn verwendete Radix ist eine niedrigstufige UI-Komponentenbibliothek mit Fokus auf Barrierefreiheit und Anpassbarkeit.
- Die Implementierung der Radio-Gruppe in Radix umfasst rund 215 Zeilen React-Code und importiert 7 Dateien.
- Radix ergänzt ein
<button>-Element mit ARIA-Attributen, damit es sich wie ein Radio-Button verhält.- Das erste Grundprinzip der ARIA-Nutzung des W3C besagt jedoch: „Wenn möglich, verwende native HTML-Elemente.“
- Radix folgt diesem Prinzip nicht und verwendet statt
<input>einen wiederverwendeten Button.
- Innerhalb eines
<form>wird zusätzlich ein verstecktes<input type="radio">eingefügt, was die Konsistenz weiter verringert.
Eine einfache Alternative mit CSS
- Native HTML-Radio-Buttons lassen sich mit
appearance: none,::before,:checked,border-radiususw. problemlos stylen.- Im Beispielcode wird eine vollständige Anpassung ohne Abhängigkeiten, JavaScript oder ARIA-Attribute umgesetzt.
- Derselbe Effekt lässt sich auch mit Tailwind umsetzen.
- Die Vorstellung, dass „das Styling von Radio-Buttons schwierig ist“, ist ein Problem der Vergangenheit; heute ist mit reinem CSS eine ausreichende Kontrolle möglich.
Das Problem der aufaddierten Komplexität
- Wer Shadcn und Radix zusammen verwendet, muss zwei Bibliotheken und Hunderte Zeilen Code verstehen.
- Für einen einzigen simplen Radio-Button werden mehrere KB JavaScript zusätzlich geladen.
- Nutzer müssen auf das Parsen und Ausführen von JS warten, nur um einen Button umzuschalten.
- Eine solche Struktur führt zu höherer kognitiver Belastung, mehr Fehlermöglichkeiten und schlechterer Web-Performance.
Zurück zur Einfachheit
- Der Browser stellt Radio-Buttons bereits nativ bereit, und eine einzelne Zeile wie
<input type="radio" name="beverage" value="coffee" />reicht aus. - Unnötige Abstraktionen und der Einsatz verschachtelter Bibliotheken schaden der ursprünglichen Einfachheit und Effizienz der Webentwicklung.
- Selbst bei kleinen UI-Elementen ist ein Design, das Basisfunktionen wiederverwendet, sowohl für Wartbarkeit als auch für Performance vorteilhafter.
4 Kommentare
Wenn man sich die Button-Komponente von React Aria ansieht, fällt man wohl in Ohnmacht, lol
Da ich im Frontend-Bereich arbeite, ist das ein Problem, das ich seit Langem erlebe. Wie soll ich sagen: Es ist wirklich ein schwer zu lösendes Problem. Die Implementierung ändert sich zwar mit der Zeit ständig, aber dass man es nicht mit dem Input-Typ löst, bleibt in jeder Ära gleich ...
Was soll es eigentlich, die Spezifikationen rund um Barrierefreiheit separat umzusetzen, nur um das Verhalten von Radio- und Checkbox-Buttons im Webbrowser nachzuahmen ... ich weiß es nicht ... Wie im Artikel steht, gibt es inzwischen sogar Alternativen mit CSS, und wenn man dann sieht, dass manche es um jeden Preis als Komponente implementieren wollen, ist das schon ein bisschen lächerlich.
Langweilig und pedantisch:
Schnell erledigt, bleibt lange im Gedächtnis:
Hacker-News-Kommentare
Ich arbeite nicht oft im Frontend, aber schon als React zum Mainstream wurde, zeichnete sich ab, dass die Komplexität wachsen würde.
Andere Abstraktionsschichten neigen zur Vereinfachung, aber React erzeugt eine viel komplexere Abstraktion als die zugrunde liegende Technologie.
Ich habe das Gefühl, dass Entwickler, die nur React kennen, immer höhere Layer darauf stapeln und so zu überengineerten Ergebnissen führen.
Zum Beispiel sind Shadcn oder Radix UI-Bibliotheken nur für React, aber wenn man nur die Marketingtexte liest, wirken sie wie allgemeine UI-Bibliotheken.
Wenn ein Projekt größer wurde, endete es entweder damit, dass ich mein eigenes Framework baute, oder damit, dass ich mit bestehenden Frameworks unzufrieden war; React löst dieses Problem zumindest teilweise.
Nicht React selbst ist das Problem, sondern die übermäßige Komplexität des Ökosystems. Wenn man nur gut mit React umgehen kann, lässt es sich noch immer angenehm nutzen.
Stattdessen versuchen sie, CSS mit Tools wie Tailwind zu umgehen. Ich verwalte State mit React, bevorzuge für das Styling aber direkt CSS.
Das Schwierigste ist, Teammitglieder davon zu überzeugen, CSS zu lernen.
Ich meide solche „modernen“ Frameworks und bevorzuge nach Möglichkeit Basistechnologien.
React liefert nur die „Box“, und der Entwickler entscheidet, was hineinkommt. Genau das ist die eigentliche Stärke von React.
Dieses Radio-Button-Beispiel ist zugleich lustig und beeindruckend.
Das Ergebnis ist von einem normalen CSS-Radio-Button nicht zu unterscheiden, also frage ich mich, warum man es so kompliziert macht.
Ich frage mich, ob es Beispiele für große Websites gibt, die ohne solche unnötige Komplexität gebaut wurden.
Es war mehr Code als heute, aber die Oberfläche hatte ein unmittelbar reaktionsschnelles Gefühl.
Siehe den Code des Takeoff-Projekts.
Wie man sagt: „Noch niemand wurde entlassen, weil er React gewählt hat“ — es ist zu einer sicheren Wahl geworden.
Entwickler sollten daran denken, dass sie Designanforderungen immer hinterfragen können.
Ein Entwickler hatte in React Native vier Stunden mit einem simplen Layoutproblem verschwendet; als ich ihm sagte, er solle fragen, ob man das Design leicht ändern dürfe, war es in 10 Minuten gelöst.
Mit gutem CSS kann man schon völlig ausreichende Ergebnisse erzielen. Mich würden Empfehlungen von Leuten interessieren, die so einen Ansatz ausprobiert haben.
Mein größter Fehler im Jahr 2025 war, Shadcn gewählt zu haben.
Das ständige Importieren von Radix war das erste Warnsignal, die Radio-Komponente das zweite.
Das Projekt lief bereits, also habe ich es zähneknirschend mit Copilot angepasst, aber am Ende gefiel mir auch diese Abhängigkeit von AI nicht.
Ein früherer POC war viel einfacher und effizienter. Irgendwann würde ich am liebsten alles wieder in Vanilla-HTML neu bauen.
Remix oder React Router 7 haben immerhin versucht, näher an Webstandards zu bleiben.
Bei Tailwind dachte ich: „Das ist es nicht“, und wenn meine Freunde es nach dem Refactoring immer noch gut finden, schaue ich es mir vielleicht noch einmal an.
React hat bereits props-basiertes Styling, also gibt es keinen guten Grund, ganze Blöcke von CSS-Klassen zu verwenden.
Wenn Barrierefreiheit im Vordergrund steht, reicht Radix UI allein völlig aus.
Das Problem ist, dass sich die
<input>-Elemente des Browsers, besonders radio und select, nur schwer anpassen lassen.Standard-Radio-Buttons sind auf Mobilgeräten wenig benutzerfreundlich.
Ich würde gern konkreter wissen, welche Probleme es auf Mobilgeräten gab.
<label>umschließt und Padding gibt, sind sie auch auf Mobilgeräten gut benutzbar.Die meisten Projekte beginnen mit guten Absichten, aber irgendwann bestehen sie aus 200 Zeilen Radio-Button-Code und sieben Imports.
So beginnt Code Rot.
Ich habe kürzlich daisyUI ausprobiert und es gefällt mir ziemlich gut.
Weil es auf reinem CSS basiert, kann es neue Browser-Features (wie dialog) gut nutzen.
Zum Beispiel kann der Drawer den Fokus nicht einschließen, und das Accordion missbraucht Radio-Buttons als JS-Ersatz.
Aus solchen Gründen müssen Bibliotheken wie Radix zwangsläufig komplexer werden.
Ich stimme der Kernaussage des Artikels zu, frage mich aber, ob man mit Vanilla-CSS den exakten Stil, den Designer in Figma erstellt haben, in allen Browsern identisch umsetzen kann.
Lässt sich so etwas wie die Demo von Radix wirklich vollständig nachbauen?
Siehe dieses CodePen-Beispiel.
Es reicht, das CSS zu extrahieren und an eine einfache React-Komponente zu hängen.
Ist es wirklich sinnvoll, zig KB Code und Wartungsaufwand hinzuzufügen, nur um kleine visuelle Unterschiede zu vermeiden?
Wie in dem Spruch von Paik Nam-june: „Wenn etwas zu perfekt ist, wird Gott zornig.“
Die eigentlichen Kosten sind nicht der Code, sondern die Onboarding-Zeit.
Ein neu dazukommender Entwickler braucht Wochen, um einen 47-zeiligen Radio-Button auf Radix-Basis zu verstehen.
Eine Vanilla-Variante baut man dagegen an einem Tag und erklärt sie in 20 Minuten.
Natürlich ist die Komplexität gerechtfertigt, wenn man Produkte wie Figma oder Linear baut, bei denen Barrierefreiheit und Tastaturnavigation wichtig sind.
Viele Kommentare kritisieren Shadcn, aber ich finde eher, dass es Komponentenstruktur und Wiederverwendbarkeit gut fördert.
Der Kern von Shadcn ist die Philosophie: „Besitze und ändere deine Komponenten selbst.“
Das ist ein grundlegend anderer Ansatz als bei herkömmlichen UI-Bibliotheken.