CSS - Comment styliser une étiquette de boutons radio sélectionnés?

141

Je souhaite ajouter un style à l'étiquette sélectionnée d'un bouton radio:

HTML:

<div class="radio-toolbar">
 <label><input type="radio" value="all" checked>All</label>
 <label><input type="radio" value="false">Open</label>
 <label><input type="radio" value="true">Archived</label>
</div>

CSS

.radio-toolbar input[type="radio"] {display:none;}
.radio-toolbar label {
    background:Red;
    border:1px solid green;
    padding:2px 10px;
}
.radio-toolbar label + input[type="radio"]:checked { 
    background:pink !important;
}

Des idées sur ce que je fais mal?

Un apprenti
la source

Réponses:

296

.radio-toolbar input[type="radio"] {
  display: none;
}

.radio-toolbar label {
  display: inline-block;
  background-color: #ddd;
  padding: 4px 11px;
  font-family: Arial;
  font-size: 16px;
  cursor: pointer;
}

.radio-toolbar input[type="radio"]:checked+label {
  background-color: #bbb;
}
<div class="radio-toolbar">
  <input type="radio" id="radio1" name="radios" value="all" checked>
  <label for="radio1">All</label>

  <input type="radio" id="radio2" name="radios" value="false">
  <label for="radio2">Open</label>

  <input type="radio" id="radio3" name="radios" value="true">
  <label for="radio3">Archived</label>
</div>

Tout d'abord, vous souhaitez probablement ajouter l' nameattribut sur les boutons radio. Sinon, ils ne font pas partie du même groupe et plusieurs boutons radio peuvent être cochés.

De plus, depuis que j'ai placé les étiquettes en tant que frères et sœurs (des boutons radio), j'ai dû utiliser les attributs idet forpour les associer.

Šime Vidas
la source
2
@Johncl C'est vrai. IE8 n'implémente pas le :checkedsélecteur.
Šime Vidas
Si je ne souhaite sélectionner ni l'entrée [type = "radio"] ni l'entrée [type = "checkbox"]. Quelle est la syntaxe correcte pour le faire dans une seule règle et éviter de faire: input [type = "radio"], input [type = "checkbox"]
fabregas88
@ fabregas88 Vous pouvez ajouter une classe CSS à ces éléments, puis.foo { ... }
Šime Vidas
4
Vous venez de tuer l'accès au clavier! espérons que tous vos utilisateurs sont valides. ... maintenant, si vous gardez simplement le bouton radio là, sans utiliser, display:none;les navigateurs le feront fonctionner avec le clavier très bien.
gcb du
1
@gcb La question était de savoir comment masquer les boutons radio standard. J'ai fait ce prototype jsbin.com/miwati/edit?html,css,output . Les boutons radio sont absolument positionnés derrière les étiquettes. Ce n'est probablement pas la meilleure approche cependant.
Šime Vidas
29

Si vous voulez vraiment mettre les cases à cocher à l'intérieur de l'étiquette, essayez d'ajouter une balise span supplémentaire, par exemple.

HTML

<div class="radio-toolbar">
 <label><input type="radio" value="all" checked><span>All</span></label>
 <label><input type="radio" value="false"><span>Open</span></label>
 <label><input type="radio" value="true"><span>Archived</span></label>
</div>

CSS

.radio-toolbar input[type="radio"]:checked ~ * { 
    background:pink !important;
}

Cela définira les arrière-plans de tous les frères et sœurs du bouton radio sélectionné.

Iainbeeston
la source
2
J'ai préféré cette approche, même si j'ai utilisé un sélecteur différent («+» comme mentionné ci-dessous et dans cette question car je voulais for
styliser
6

Vous utilisez un sélecteur de frère adjacent ( +) lorsque les éléments ne sont pas des frères. L'étiquette est le parent de l'entrée, pas son frère.

CSS n'a aucun moyen de sélectionner un élément en fonction de ses descendants (ni de tout ce qui le suit).

Vous devrez vous tourner vers JavaScript pour résoudre ce problème.

Vous pouvez également réorganiser votre balisage:

<input id="foo"><label for="foo"></label>
Quentin
la source
1

Vous pouvez ajouter une étendue à votre html et css.

Voici un exemple de mon code ...

HTML (JSX):

<input type="radio" name="AMPM" id="radiostyle1" value="AM" checked={this.state.AMPM==="AM"} onChange={this.handleChange}/>  
<label for="radiostyle1"><span></span> am  </label>

<input type="radio" name="AMPM" id="radiostyle2" value="PM" checked={this.state.AMPM==="PM"} onChange={this.handleChange}/>
<label for="radiostyle2"><span></span> pm  </label>

CSS pour faire disparaître le bouton radio standard à l'écran et superposer l'image du bouton personnalisé:

input[type="radio"] {  
    opacity:0;                                      
}

input[type="radio"] + label {
    font-size:1em;
    text-transform: uppercase;
    color: white ;  
    cursor: pointer;
    margin:auto 15px auto auto;                    
}

input[type="radio"] + label span {
    display:inline-block;
    width:30px;
    height:10px;
    margin:1px 0px 0 -30px;                       
    cursor:pointer;
    border-radius: 20%;
}


input[type="radio"] + label span {
    background-color: #FFFFFF 
}


input[type="radio"]:checked + label span{
     background-color: #660006;  
}
Praveena Janakiraman
la source
0

Comme il n'y a actuellement aucune solution CSS pour styliser un parent, j'utilise ici une simple jQuery pour ajouter une classe à une étiquette avec une entrée cochée à l'intérieur.

$(document).on("change","input", function(){
 $("label").removeClass("checkedlabel");
 if($(this).is(":checked")) $(this).closest("label").addClass("checkedlabel");
});

Ne pas oublier de donner l'étiquette de l'entrée vérifiée pré-classe checkedlabeltrop

Fanky
la source
0

Voici une solution accessible

label {
  position: relative;
}

label input {
  position: absolute;
  opacity: 0;
}

label:focus-within {
  outline: 1px solid orange;
}
<div class="radio-toolbar">
  <label><input type="radio" value="all" checked>All</label>
  <label><input type="radio" value="false">Open</label>
  <label><input type="radio" value="true">Archived</label>
</div>

WofWca
la source