Como estilizar um rótulo de botões de opção selecionado?

139

Quero adicionar um estilo ao rótulo selecionado de um botão de opção:

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;
}

Alguma idéia do que estou fazendo de errado?

Um aprendiz
fonte

Respostas:

295

.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>

Primeiro de tudo, você provavelmente deseja adicionar o nameatributo nos botões de opção. Caso contrário, eles não fazem parte do mesmo grupo e vários botões de opção podem ser verificados.

Além disso, desde que coloquei os rótulos como irmãos (dos botões de opção), tive que usar os atributos ide forpara associá-los.

Šime Vidas
fonte
2
@ Johncl Isso é verdade. O IE8 não implementa o :checkedseletor.
Šime Vidas 7/12/12
Se eu desejar selecionar nem input [type = "radio"] ou input [type = "checkbox"]. Que é a sintaxe correta para fazê-lo em apenas uma regra e evitar fazer: input [type = "radio"], input [type = "checkbox"]
fabregas88
@ fabregas88 Você pode adicionar uma classe CSS para esses elementos, e depois.foo { ... }
Šime Vidas
4
Você acabou de matar o acesso ao teclado! espero que todos os seus usuários sejam capazes. ... agora, se você mantiver o botão de opção, sem usar display:none;, os navegadores farão com que o teclado funcione perfeitamente.
gcb
1
@gcb A questão era como ocultar os botões de opção padrão. Eu criei esse protótipo jsbin.com/miwati/edit?html,css,output . Os botões de opção estão absolutamente posicionados atrás das etiquetas. Provavelmente não é a melhor abordagem.
Šime Vidas
29

Se você realmente deseja colocar as caixas de seleção dentro da etiqueta, tente adicionar uma tag de extensão extra, por exemplo.

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;
}

Isso definirá os planos de fundo para todos os irmãos do botão de opção selecionado.

iainbeeston
fonte
2
Eu preferia esta abordagem, embora eu usei um seletor diferente ( '+', como mencionado abaixo e nesta questão . Como eu queria estilo apenas o item selecionado Isto permitiu-me para não se preocupar com os foratributos.
brichins
6

Você está usando um seletor de irmão adjacente ( +) quando os elementos não são irmãos. O rótulo é o pai da entrada, não o irmão.

O CSS não tem como selecionar um elemento com base em seus descendentes (nem em nada que se segue).

Você precisará procurar no JavaScript para resolver isso.

Como alternativa, reorganize sua marcação:

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

Você pode adicionar uma extensão ao seu html e css.

Aqui está um exemplo do meu código ...

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 para fazer com que o botão de opção padrão desapareça na tela e sobreponha a imagem do botão personalizado:

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
fonte
0

Como atualmente não existe uma solução CSS para estilizar um pai, uso uma simples jQuery aqui para adicionar uma classe a um rótulo com entrada marcada dentro dele.

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

Não se esqueça de dar checkedlabeltambém à classe do rótulo da entrada pré-verificada

Fanky
fonte
0

Aqui está uma solução acessível

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
fonte