1

I tried to change a label's color depending on the checked radio button, but couldn't reach it using CSS syntax because of the hierarchy of the HTML.

    <div class="sliderContainer">
      <div class="slides">
          <input type="radio" name="radio-btn" id="radio1" checked>
          <input type="radio" name="radio-btn" id="radio2">
          <input type="radio" name="radio-btn" id="radio3">
      </div>
    </div>

    <div class="navigation">
        <label for="radio1" class="btnbar" id="label1"></label>
        <label for="radio2" class="btnbar" id="label2"></label>
        <label for="radio3" class="btnbar" id="label3"></label>
    </div>

I'd tried to use ~ to reach the element and change a label's colors, but it only works with siblings. Is there a way to call an..."uncle" element? >,+, space and classes didn't work either

    #radio1:checked ~ #label1 {
        background: #6ab534;
    }

    #radio2:checked ~ #label2 {
        background: #6ab534;
    }

    #radio3:checked ~ #label3 {
        background: #6ab534;
    }
  • 1
    does not work without JS. CSS has no parent selector which you need here. The only parent selector is the `:has` which has very limited support so far. – tacoshy Oct 26 '22 at 19:14

1 Answers1

1

Since CSS has limited support for a parent selector (:has()), you need to use JS for it.

In JS you simply listen to change events for the inputs. Then you remove a class from all labels and add it to the element that matches the checked id of the input:

document.querySelectorAll('input[name="radio-btn"]').forEach(el =>
  el.addEventListener('change', function(e) {
    const labels = document.querySelectorAll('label.btnbar');
    
    // removes class from all elements  
    labels.forEach(ele => ele.classList.remove('checked'));
    
    // get the id of the checked input
    let input_id = e.target.id;
    
    // adds class to checked label
    let label = document.querySelector(`label[for="${input_id}"]`);
    label.classList.add('checked');
  })
);
.checked {
  background: #6ab534;
}


/* for visualization purpose only */
label {
  display: block;
}
<div class="sliderContainer">
  <div class="slides">
    <input type="radio" name="radio-btn" id="radio1" checked>
    <input type="radio" name="radio-btn" id="radio2">
    <input type="radio" name="radio-btn" id="radio3">
  </div>
</div>

<div class="navigation">
  <label for="radio1" class="btnbar" id="label1">Label 1</label>
  <label for="radio2" class="btnbar" id="label2">Label 2</label>
  <label for="radio3" class="btnbar" id="label3">Label 3</label>
</div>
tacoshy
  • 10,642
  • 5
  • 17
  • 34