The bad news
In order to detect which option is currently selected with CSS, you would need to apply the :checked
pseudo-class to the option
element, not to the select
element. See the question "CSS :selected pseudo class similar to :checked, but for elements" for more info.
option:checked {
font-weight: bold;
}
<select>
<option>Choice 1</option>
<option>Choice 2</option>
</select>
Combining that with CSS combinators (the adjacent sibling selector +
, the general sibling selector ~
, the child selector >
, and the descendent selector) is frustratingly ineffectual. The combinators can be combined to select any sibling or descendant, but can never select a parent or cousin... and since the HTML spec for the select
element says that its allowed content is "zero or more option
or optgroup
elements", you simply can't affect a div using the value of a select element with CSS alone.
Using a drop-down with JavaScript
The example below monitors the select element for changes. When a change occurs, it grabs the newly-selected option element and reads the targets for that option from a data attribute (this is a nice convenience, because it allows you to specify the filter targets right in the HTML -- thereby keeping your model and control logic separate). Then it goes through all valid targets and either adds or removes the .hidden
class based on whether that target is in the list provided by the data attribute.
var filter = document.getElementById('filter');
filter.addEventListener('change', function() {
var option = this.options[this.selectedIndex];
var targets = option.dataset.targets.split(/(\s+)/);
for (var target of document.getElementsByClassName('target')) {
if (targets.indexOf(target.id) >= 0)
target.classList.remove('hidden');
else
target.classList.add('hidden');
}
});
.target {
display: block;
}
.target.hidden {
display: none;
}
<select id="filter">
<option data-targets="">Show no targets</option>
<option data-targets="t1">Show target 1</option>
<option data-targets="t2">Show target 2</option>
<option data-targets="t1 t2">Show targets 1 and 2</option>
</select>
<div class="target hidden" id="t1">Thsi is the first target.</div>
<div class="target hidden" id="t2">This is the second target.</div>
Using radio buttons without JavaScript
Unlike drop-down elements, radio buttons don't need to be nested inside a wrapping element. Because of this, you can structure your HTML so that the div
elements are general siblings of the radio buttons, and you can use the :checked
class to affect their visibility.
.target {
display: none;
}
#f1:checked ~ #t1 {
display: block;
}
#f2:checked ~ #t2 {
display: block;
}
#f3:checked ~ #t1,
#f3:checked ~ #t2 {
display: block;
}
<input type="radio" name="filter" id="f0" checked><label for="f0">Show no targets</label><br>
<input type="radio" name="filter" id="f1"><label for="f1">Show target 1</label><br>
<input type="radio" name="filter" id="f2"><label for="f2">Show target 2</label><br>
<input type="radio" name="filter" id="f3"><label for="f3">Show targets 1 and 2</label>
<div class="target" id="t1">This is the first target.</div>
<div class="target" id="t2">This is the second target.</div>