Is it possible to style a select
element based on what option
is selected with CSS only? I am aware of existing JavaScript solutions.
I tried to style the option element itself, but this will give style only to the option element in the list of options, not to the selected element.
select[name="qa_contact"] option[value="3"] {
background: orange;
}
http://jsfiddle.net/Aprillion/xSbhQ/
If not possible with CSS 3, will CSS 4 subject selector help in the future - or will this stay a forbidden fruit to CSS?
Unfortunately, yes - this is something not currently possible with only CSS. As mentioned in the answers and comments to this question, there is currently no way to make the parent element receive styling based on its children.
In order to do what you're wanting, you would essentially have to detect which of the children (<option>
) is selected, and then style the parent accordingly.
You could, however, accomplish this with a very simple jQuery call, as follows:
HTML
<select>
<option value="foo">Foo!</option>
<option value="bar">Bar!</option>
</select>
jQuery
var $select = $('select');
$select.each(function() {
$(this).addClass($(this).children(':selected').val());
}).on('change', function(ev) {
$(this).attr('class', '').addClass($(this).children(':selected').val());
});
CSS
select, option { background: #fff; }
select.foo, option[value="foo"] { background: red; }
select.bar, option[value="bar"] { background: green; }
Here is a working jsFiddle.
Back to the question about the future of selectors. Yes - the "Subject" selectors are intended to do exactly what you mention. If/when they ever actually go live in modern browsers, you could adapt the above code to:
select { background: #fff; }
!select > option[value="foo"]:checked { background: red; }
!select > option[value="bar"]:checked { background: green; }
As a side-note, there is still debate about whether the !
should go before or after the subject. This is based on the programming standard of !something
meaning "not something". As a result, the subject-based CSS might actually wind up looking like this instead:
select { background: #fff; }
select! > option[value="foo"]:checked { background: red; }
select! > option[value="bar"]:checked { background: green; }