On a Sunday afternoon, while sitting in my study, I suddenly wondered: if an element, such as a <label> element, could respond to the state changes of a radio button or checkbox no matter where it is on the page, wouldn’t that make it possible to handle almost every click interaction on the page in one shot? That would be seriously awesome!

This page turns the idea into small, inspectable demos: radios and checkboxes keep their native behavior, while any element with a matching for attribute receives an .active state.

1. The Classic :checked Limitation

Pure CSS can already build click interactions, but sibling selectors require the controlled panels to come after the inputs in a shared structure.

Code:
<div class="limited-root">
  <input type="radio" id="limitOne" name="limited" checked>
  <input type="radio" id="limitTwo" name="limited">

  <div class="limited-layout">
    <div class="limited-controls">
      <label for="limitOne">Sibling rule</label>
      <label for="limitTwo">DOM restriction</label>
    </div>

    <div class="limited-panels">
      <section class="limited-panel panel-one">Panel one is visible.</section>
      <section class="limited-panel panel-two">Panel two is visible.</section>
    </div>
  </div>
</div>

<style>
/* Only following siblings can be selected. */
#limitOne:checked ~ .limited-panels .panel-one,
#limitTwo:checked ~ .limited-panels .panel-two {
  display: block;
}
</style>
Result:
Panel one is visible because the checked input is before this panel in the same controlled structure.
Panel two is visible. The technique works, but layout and source order are tightly coupled.

2. Parent Element Responds to Radio State

The smart-for rule is simple: when an input is checked, every element whose for value matches that input’s id receives .active.

Code:
<ul class="option-list">
  <li for="item1"><input type="radio" id="item1" name="item" checked>Option 1</li>
  <li for="item2"><input type="radio" id="item2" name="item">Option 2</li>
  <li for="item3"><input type="radio" id="item3" name="item">Option 3</li>
  <li for="item4"><input type="radio" id="item4" name="item">Option 4</li>
  <li for="item5"><input type="radio" id="item5" name="item">Option 5</li>
</ul>

<style>
.option-list li.active {
  color: white;
  background: #0f766e;
}
</style>
Result:
  • Option 1
  • Option 2
  • Option 3
  • Option 4
  • Option 5

3. Sidebar with One Checkbox

A checkbox represents open or closed. Labels provide native toggling, while .aside.active controls visibility.

Code:
<label class="ui-button">
  <input type="checkbox" id="zxxAside" hidden>
  Click me to show the sidebar
</label>

<aside class="aside" for="zxxAside">
  <label for="zxxAside" class="aside-overlay"></label>
  <div class="aside-content">Click the black overlay to collapse</div>
</aside>

<style>
.aside { visibility: hidden; }
.aside.active { visibility: visible; }
</style>
Result:

The overlay is a label for the same checkbox, so clicking it unchecks the control.

4. Dropdown List

The menu can live inside the dropdown wrapper here, but the same for/id association would still work if it moved elsewhere.

Code:
<div class="dropdown-demo">
  <label class="dropdown-toggle">
    <input type="checkbox" id="cityMenu" hidden>
    Choose a city
  </label>

  <div class="dropdown-menu" for="cityMenu">
    <label for="cityMenu">Shanghai</label>
    <label for="cityMenu">Hangzhou</label>
    <label for="cityMenu">Shenzhen</label>
  </div>
</div>

<style>
.dropdown-menu {
  opacity: 0;
  visibility: hidden;
}
.dropdown-menu.active {
  opacity: 1;
  visibility: visible;
}
</style>
Result:

5. Tab Switching Without Strange Hierarchy

Tab buttons and tab panels can be organized normally. Each visual element listens to the radio id it cares about.

Code:
<input class="tab-radios" type="radio" id="tabIdea" name="tabs" checked>
<input class="tab-radios" type="radio" id="tabDemo" name="tabs">
<input class="tab-radios" type="radio" id="tabCaveat" name="tabs">

<nav class="tab-nav">
  <label for="tabIdea">Idea</label>
  <label for="tabDemo">Demo</label>
  <label for="tabCaveat">Caveat</label>
</nav>

<section class="tab-panel" for="tabIdea">The label and panel both become active.</section>
<section class="tab-panel" for="tabDemo">No sibling selector is needed.</section>
<section class="tab-panel" for="tabCaveat">This is powerful, but not semantic magic.</section>
Result:

Idea

The label and panel both become active because they point to the checked radio.

Demo

No sibling selector is needed, so the source structure can stay readable.

Caveat

This is powerful for interaction glue, but it still needs thoughtful HTML and accessibility decisions.

6. The Synchronization Engine

The helper watches native clicks, scripted .checked assignments, attribute changes, radio-group changes, and newly inserted associated elements.

Code:
<script>
(function () {
  var selector = 'input[type="radio"], input[type="checkbox"]';

  function sync(input) {
    if (!input || !input.id || !input.matches(selector)) return;

    if (input.type === 'radio' && input.name) {
      document.querySelectorAll('input[type="radio"][name="' + CSS.escape(input.name) + '"]').forEach(syncOne);
    } else {
      syncOne(input);
    }
  }

  function syncOne(input) {
    if (!input.id) return;
    document.querySelectorAll('[for="' + CSS.escape(input.id) + '"]').forEach(function (node) {
      if (node !== input) node.classList.toggle('active', input.checked);
    });
  }

  document.addEventListener('click', function (event) {
    var target = event.target.closest(selector + ', [for]');
    if (!target) return;
    requestAnimationFrame(function () {
      sync(target.matches(selector) ? target : document.getElementById(target.getAttribute('for')));
    });
  });

  var checked = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'checked');
  Object.defineProperty(HTMLInputElement.prototype, 'checked', {
    get: checked.get,
    set: function (value) {
      checked.set.call(this, value);
      sync(this);
    }
  });

  new MutationObserver(function (records) {
    records.forEach(function (record) {
      if (record.type === 'attributes') sync(record.target);
      document.querySelectorAll(selector).forEach(sync);
    });
  }).observe(document.documentElement, {
    childList: true,
    subtree: true,
    attributes: true,
    attributeFilter: ['checked', 'for', 'id', 'name']
  });

  document.querySelectorAll(selector).forEach(sync);
})();
</script>
Result:
This status block follows #engineBox.