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?

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.


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.


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>

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

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


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>

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.