Nehmen wir an, Sie müssen dem Benutzer in einem Formular die Auswahl einer einzelnen, eindeutigen Option ermöglichen. Das ist das Reich entweder eines Dropdown-Menüs oder einer Gruppe von Radio-Buttons. Nun nehmen wir an, dass es nach jeder einzelnen Wahl eine direkte Folgefrage gibt. Zum Beispiel ein Bestellformular für eine wissenschaftliche Flüssigkeit. Sie kommt in Unzen, Tassen oder Pints, und sobald diese ausgewählt sind, muss die Anzahl der zu bestellenden Unzen, Tassen oder Pints angegeben werden. Das ist ein interessantes Designmuster, das auf verschiedene Weisen umgesetzt werden könnte.

Für tiefe Browserkompatibilität würden Sie wahrscheinlich etwas JavaScript verwenden, um bestimmte Formularelemente ein- und auszublenden. Aber zum Spaß machen wir es nur mit CSS.
Radio-Button und Zahlen-Input beide innerhalb des Labels
Für jede eindeutige Wahl haben wir ein Label, das sowohl den Radio-Button, den Text für das Label selbst als auch den Zahlen-Input für die Menge umschließt.
<label for="oz">
<input type="radio" name="choice" value="oz" id="oz" data-label="Ozs">
Ounces
<input type="number" name="oz-val">
</label>
Zahlen-Input standardmäßig ausblenden
Da der Radio-Button und der Zahlen-Input nun benachbarte Geschwisterelemente sind, können wir den Adjacent-Sibling-Selector verwenden, um diese Eingaben gezielt anzusprechen und sie standardmäßig auszublenden.
input[type='radio'] + input[type='number'] {
display: none;
}
Input anzeigen, wenn Radio-Button ausgewählt ist
Wir können den Zahlen-Input anzeigen, wenn der Radio-Button ausgewählt ist, indem wir fast denselben Selektor verwenden und nur den Pseudo-Class-Selector :checked zum Radio-Button hinzufügen. Dann positionieren wir ihn nach rechts.
input[type='radio']:checked + input[type='number'] {
display: inline; /* unhide */
float: right;
margin-right: 20px; /* space for "label" */
width: 100px;
}
Die Zahlen-Inputs „labeln“
Um genauer zu spezifizieren, was wir mit diesen Zahlen-Inputs meinen, können wir Text neben dem Input platzieren. Beachten Sie das „data-label“-Attribut bei den Radio-Buttons. Wir greifen darauf zu und fügen Text als Pseudo-Element hinzu.
input[type='radio']:after {
position: absolute;
right: 9px;
top: 9px;
}
input[data-label]:checked:after {
content: attr(data-label);
}
Hervorheben der gesamten ausgewählten Wahl/des gesamten Wertes
Um klar und deutlich anzuzeigen, welche Option wir ausgewählt haben und dass diese Auswahl mit dem Mengenwert zusammenhängt, wenden wir eine hervorgehobene Zeile an, die beide Bereiche abdeckt.
input[type='radio']:checked:before {
background: #ebdcad;
content: "";
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
border-radius: 8px;
z-index: -1;
}
Barrierefreiheit? Browserkompatibilität?
Ein Bestellformular ist eines dieser wichtigen Dinge, bei denen Sie so viel Barrierefreiheit und so tiefe Browserkompatibilität wie möglich wünschen würden. Dies war nur eine unterhaltsame CSS-Übung, die eines Tages großartig funktionieren könnte, aber wahrscheinlich ihrer Zeit voraus ist.
In Bezug auf die Barrierefreiheit könnte es in Ordnung sein. `display: none` bei den ungenutzten Inputs ist in Ordnung, da wir sie buchstäblich ausblenden wollen, bis eine Auswahl getroffen wird, aber ich bin mir nicht sicher, wie offensichtlich das Einblenden davon ist. Wenn jemand im Namen der Barrierefreiheits-Experten in den Kommentaren sprechen möchte, würde ich es gerne hören.
Browserkompatibilität ist etwas kniffliger. Um es überhaupt zum Laufen zu bringen, muss der Browser den Adjacent-Sibling-Selector unterstützen, über den wir sprechen, nur IE 8+. Wenn dieser Selektor fehlschlägt, werden alle Zahlen-Inputs angezeigt, was kein Showstopper wäre. Sie müssten die Formatierung auf einen Selektor verschieben, der nicht „+“ verwendet. Die Hervorhebung von Feldern und Pseudo-Labeling erfordern Pseudo-Elemente, daher hat dies seine eigene Kompatibilität. Last but not least ist es leicht ungewöhnlich, dass Pseudo-Elemente überhaupt auf Radio-Button-Elementen erlaubt sind. Inputs sind Elemente ohne Inhalt (sie schließen sich selbst, wie ein img-Element). Opera und WebKit unterstützen dies zwar, aber es ist nicht klar, ob sie es sollten oder nicht. Firefox nicht, also werden Sie in diesem Browser keine Hervorhebung oder Labels sehen.
Wenn Sie eine zu 100 % narrensichere Lösung benötigen, können Sie ein Wufoo-Formular verwenden und Field Rules verwenden, um zusätzliche Felder auszublenden/anzuzeigen.
Fertig
Demo ansehen Dateien herunterladen
Danke an Bradley Staples, der uns die Idee per E-Mail geschickt hat.
Schönes Beispiel und Tutorial, aber ist das gültig? Ich meine die Inputs innerhalb des Labels...:))
Yep.
Tatsächlich ist es nicht gültig, da sich mehr als ein Input innerhalb jedes Labels befindet. Die Spezifikation erlaubt nur einen.
Diese Technik scheint in Firefox 4.0.1 nicht zu funktionieren.
Wenn Sie versuchen, auf das Textfeld zu klicken, um darin zu tippen, wird dies nicht zugelassen. Stattdessen wird einfach erneut auf den Radio-Button geklickt.
Das Problem mit FF 4 ist, dass sie ein System implementiert haben, bei dem das Klicken auf das Label das Element auswählt, auf das es sich bezieht. Doppelklicken auf den Input ermöglicht die Auswahl, aber das ist nicht gerade benutzbar. Um dies zu beheben, können Sie einfach das `for`-Attribut aus dem Label entfernen. Wenn Sie die Möglichkeit behalten möchten, den Radio-Button durch Klicken auf den Text des Labels auszuwählen, können Sie beide Inputs aus dem Label herausnehmen und dann die Positionierung neu gestalten.
Funktioniert nicht in IE8.
Hier ist eine Version mit verbessertem HTML, die eine tiefere Unterstützung haben sollte.
http://jsfiddle.net/chriscoyier/3YdN4/7/
Keine doppelt verschachtelten Inputs mehr und keine Regel-Filter, um ältere IEs davon abzuhalten, es zu vermasseln.
@Ryan King
Ist das nicht wofür das Label + for-Attribut da ist? Klicken Sie auf das Label => wählen Sie (oder fokussieren Sie) den Input, der im for-Attribut erwähnt ist?
@Peter Ja, genau dafür ist das `for`-Attribut im Label da. Deshalb habe ich vorgeschlagen, den Zahlen-Input aus dem Label herauszunehmen, anstatt das `for`-Attribut zu entfernen, wenn Sie immer noch die Möglichkeit haben wollen, den Radio-Button durch Klicken auf den Text auszuwählen. Ich hätte meine Antwort vielleicht etwas klarer formulieren können :). Eine bessere Erklärung ist, dass das Klicken auf den Zahlen-Input (wenn er sich im Label befindet) einen Klick auf den Input auslöst, dann breitet sich die Aktion zum Label aus, löst den Klick auf das Label aus, was dann den Fokus auf den Radio-Button auslöst. Anscheinend erlaubt FF4 als Einziger die Weitergabe (oder erkennt sie zumindest).
Ich schätze, mehr als ein Input in einem Label ist ungültig ;-).
Usability-technisch gesehen, denke ich, es wäre in Ordnung, die klickbare Fläche der Checkboxen breiter zu machen. Warum sie nicht so groß machen, wie die farbige Box, in der sie sich befinden.
Ein interessantes Designmuster für ein häufig auftretendes Problem. Besonders wenn Sie genug Platz zum Arbeiten haben.
Der Geschwister-Selektor funktioniert auch unter IE7: http://msdn.microsoft.com/en-us/library/cc351024%28VS.85%29.aspx#combinators
Leider gibt es in IE<9 keine Möglichkeit, mit CSS zu erkennen, ob ein Radio-Button ausgewählt ist, aber hier kann das JS-Team helfen und einfach eine Klassenbezeichnung zum ausgewählten Radio-Button hinzufügen.
Aber CSS für grundlegende Verzweigungslogik zu verwenden, ist eine ziemlich coole Idee.
Warum sollten Sie Radio-Buttons verwenden, wenn Sie sowieso nur eine Option auswählen können? Wäre es nicht besser, ein Dropdown zu verwenden und viel Platz zu sparen? Sie zeigen auch die Maßeinheit doppelt an, was zusätzlichen Platz beansprucht.
Wenn der Benutzer beschließt, seine erste Eingabe zu ändern, muss er die zweite erneut vornehmen. Hier könnten Sie zusätzliche Benutzerfreundlichkeit hinzufügen, indem Sie automatisch in eine andere Maßeinheit oder was auch immer die erste Option ist, umrechnen.
Radio-Button: 1 Ansicht, 1 Klick
Dropdown: 1 Klick, Liste durchsuchen, noch ein Klick
Es ist benutzerfreundlicher.
Wofür würden Sie dann Radio-Buttons verwenden?
Ich vermeide Radio-Buttons, es sei denn, ich kann es mir wirklich leisten, Platz zu verschwenden. Hier funktioniert es, da es nur 3 Optionen und nur eine Gruppe von Buttons gibt. Wenn Sie mehrere Gruppen mit mindestens 5 Optionen haben, wird Ihre Seite schnell zu einer Scroll-Orgie.
Die meisten Formulare mit Radio-Buttons haben nicht die ausgewählte Option hervorgehoben, wie sie hier ist. Das ist wirklich ärgerlich, wenn Sie Ihre Auswahlmöglichkeiten nach dem Ausfüllen des gesamten Formulars überblicken möchten.
Ich werde nicht lügen, ich bin neu in CSS, aber jedes Mal, wenn ich Ihren Blog besuche, lerne ich etwas Neues, das ich implementieren/ausprobieren möchte – hier ist etwas Neues, das auf die Liste kommt.
Ich habe ein paar Eigenheiten gefunden
Wenn Sie die Buttons zum Erhöhen oder Verringern des Wertes verwenden und dieser noch leer ist, springt er auf +/- 1,7 oder so (ist das e oder eine andere spezielle Konstante?). Wenn Sie einen Wert eingeben, funktionieren die Buttons ordnungsgemäß und erhöhen sich um ganze Zahlen.
Wenn das Eingabefeld aktiv ist (mit blinkendem Cursor), können Sie kein anderes Radio-Button auswählen. Ich gehe davon aus, dass dies daran liegt, dass das Eingabefeld noch nicht „frei“ zum Ausblenden ist. Sobald Sie aus dem Eingabefeld „herausklicken“, können Sie problemlos einen anderen Radio-Button auswählen.
Der Wert des Eingabefeldes wird gespeichert, auch wenn Sie zu einem anderen Radio-Button wechseln und zurück. Würde sich das auf die Daten auswirken, die beim Absenden des Formulars gesendet werden? Ich weiß nicht genug darüber, wie Dinge wie GET oder POST funktionieren, aber es scheint, als müssten Sie eine zusätzliche serverseitige Logik einbauen, um sicherzustellen, dass nur der Wert, der mit dem ausgewählten Radio-Button übereinstimmt, verwendet wird, falls ein Benutzer seine Meinung geändert hat und Daten in einem anderen Eingabefeld hatte.
Ich benutze die Beta-Version von Reeder für Mac und gehe davon aus, dass sie nur eine WebKit-Ansicht verwendet, aber wenn das nicht der Fall ist, sind CSS-Usability-Probleme möglicherweise nicht so wichtig.
Das gefällt mir sehr gut, auch wenn es noch nicht produktionsreif ist.
Das seltsame Zahlen-Spinner-Ding hängt mit einem Safari 5.0.x-Bug zusammen (http://wufoo.com/html5/types/7-number.html).
Ja, es scheint ein wenig fehlerhaft zu sein. Ich denke, die Lösung wird darin bestehen müssen, den Zahlen-Input aus dem Label zu ziehen. Vielleicht.
Und ja, der ungenutzte Zahlenwert wird, wenn er ausgefüllt ist, mit dem Formular gesendet. Sie müssten den Wert der Radio-Button-Gruppe überprüfen und nur etwas mit dem zugehörigen Zahlen-Input-Wert tun. Das liegt in der Verantwortung des Programmierers, der mit dem Formular umgeht.
Das ist verdammt erstaunlich!
Ich liebe diese Chatbox lol.
Ich liebe all diese netten kleinen Tricks, über die Sie bloggen, Chris, obwohl es mich traurig macht, großartige wie diese zu sehen, die von vielen Browsern nicht unterstützt werden lol.
Um Ihren Code zu validieren, können Sie nicht den zweiten `input` aus dem `label` nehmen und ihn mit dem ~ Geschwister-Selektor ansprechen?
Ich würde auch JS für die Web-Barrierefreiheit (Screenreader) verwenden, neben dem Grund „tiefe Browserkompatibilität“, warum es in JS gemacht wird. Ich würde `display:none;` in CSS entfernen und nur das DOM manipulieren, um die Hintergrund- und Dropdown-Menü-Paare von nicht angekreuzten Radio-Buttons auszublenden. Auf diese Weise erhalten Menschen und Browser, die JS interpretieren können, die schicke Interaktion, ohne dass die Interaktion eine Barriere für den universellen Zugang darstellt; mit anderen Worten, progressive Verbesserung.