AnApprentice
AnApprentice

Reputation: 110950

CSS - How to Style a Selected Radio Buttons Label?

I want to add a style to a radio button's selected label:

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

Any ideas what I'm doing wrong?

Upvotes: 170

Views: 397409

Answers (9)

K. Yurii
K. Yurii

Reputation: 91

When the <input type="radio"> is a child element of the <label>, you can use CSS :has, which is now widely supported according to caniuse.com :has() CSS relational pseudo-class.

/* style for labels that have a checked radio inside */
label:has(input[type=radio]:checked) {
  color: #f00;
}
<div>
  <label>
    <input type="radio" name="test" />
    Test
  </label>
  <label>
    <input type="radio" name="test" />
    Test
  </label>
  <label>
    <input type="radio" name="test" />
    Test
  </label>
</div>

Upvotes: 2

stackersunited
stackersunited

Reputation: 9

As TimStieffenhofer mentioned in their answer, the easiest way is to have the input field as a child of the label and use the :focus-within pseudo-class on the label.

If you want to hide your radio button and set the input to hidden or display none, that will no longer work. The work around is to give the input field a z-index of -1 (or any z-index lower than the parent label).

Upvotes: 0

Tim Stieffenhofer
Tim Stieffenhofer

Reputation: 179

Just use label:focus-within {} to style a label with a checked radio or checkbox.

Upvotes: 4

WofWca
WofWca

Reputation: 676

Here's an accessible solution

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>

Upvotes: 1

Fanky
Fanky

Reputation: 1776

As there is currently no CSS solution to style a parent, I use a simple jQuery one here to add a class to a label with checked input inside it.

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

Don't forget to give the pre-checked input's label the class checkedlabel too

Upvotes: 0

Praveena Janakiraman
Praveena Janakiraman

Reputation: 31

You can add a span to your html and css .

Here's an example from my 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 to make standard radio button vanish on screen and superimpose custom button image:

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

Upvotes: 3

Šime Vidas
Šime Vidas

Reputation: 185883

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

First of all, you probably want to add the name attribute on the radio buttons. Otherwise, they are not part of the same group, and multiple radio buttons can be checked.

Also, since I placed the labels as siblings (of the radio buttons), I had to use the id and for attributes to associate them together.

Upvotes: 363

iainbeeston
iainbeeston

Reputation: 1901

If you really want to put the checkboxes inside the label, try adding an extra span tag, eg.

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

That will set the backgrounds for all siblings of the selected radio button.

Upvotes: 35

Quentin
Quentin

Reputation: 943126

You are using an adjacent sibling selector (+) when the elements are not siblings. The label is the parent of the input, not it's sibling.

CSS has no way to select an element based on it's descendents (nor anything that follows it).

You'll need to look to JavaScript to solve this.

Alternatively, rearrange your markup:

<input id="foo"><label for="foo">…</label>

Upvotes: 5

Related Questions