Binding an Input's Pseudo-Class States to Sibling Elements with CSS
In the article Build an Accessible Toggle Switch with React and SVG, I used a technique to bind the focus, checked, and disabled states of a hidden checkbox to adjacent html (or SVG) elements.
This is accomplished using the general sibling combinator in conjunction with the :checked
, :disabled
and :focus
pseudo-class selectors.
There are other input and form-related pseudo-class selectors, all of which will work will work with this technique:
:checked, :default, :disabled, :enabled, :focus, :indeterminate, :in-range, :invalid, :optional, :out-of-range, :placeholder-shown, :read-only, :read-write, :required, :valid
I thought it was worth saving an example of how to do this for quick future reference.
For simplicity, this example simply affects the appearance of an adjacent
<span class="label">
element.
Note: Nesting the
input
inside thelabel
element is a valid way of associating the input's events (click, touch, etc.) to the label text (or other elements) without needing uniqueid
attributes for your inputs and correspondingfor
attributes for your labels.
Example
This example illustrates how the concept works. The checked state of the
input
controls the style of the sibling span
, changing the font style and
adding a potato emoji using the
:after
pseudo-class:
Here's the code for making it work:
HTML:
<label>
<input
class="checkbox"
type="checkbox"
ariaLabel="check this box to receive a potato"
/>
<span class="label">Potato</span>
</label>
CSS:
.checkbox:checked ~ .label {
font-style: italic;
}
.checkbox:checked ~ .label:after {
content: '🥔';
}
That's it! If you have any questions, let me know.