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;


If not possible with CSS 3, will CSS 4 subject selector help in the future - or will this stay a forbidden fruit to CSS?

  • I can dispute your selected awnser, stay tuned. It is very "hacky"
    – Justin
    May 2 '13 at 18:56
  • @Justin - i will change the accepted answer if there is a better one. but it's good enough for me at the moment.
    – Aprillion
    May 2 '13 at 19:14
  • Check out my anwser and let me know if it actually anwsered your question lol.
    – Justin
    May 2 '13 at 20:05
  • 1
    both subject selector and :has() pseudo-class are still not supported yet in any browser :(
    – Aprillion
    Feb 14 '16 at 9:55

Impossible? Hold my beer.

All we do here is make the select element aware of the current option. CSS can handle the rest. (Don't worry about the js one-liner, it has no dependencies, it's all working out of the box.) With a little more effort you can also initialize the <select> tag by its original value; not included below but it's super easy, just give it a "data-chosen" property when composing the markup.

    <select onchange=" this.dataset.chosen = this.value; ">

And now you can easily target & style it:

select[data-chosen='opt3'] { 
    border: 2px solid red;

See on CodePen.

Side note: "chosen" is no magic word, just a descriptive name - it could be "SantaClaus". It would also look better that way.

  • 1
    THANK YOU! Was scouring the internet for something like this. This EXACTLY did the trick!!!! Your CodePen was awesome too :) You rock!
    – Ken
    Jan 7 '20 at 3:17
  • @Ken Thanks :) Happy to help a fellow programmer!
    – dkellner
    Jan 7 '20 at 6:12
  • 1
    Most elegant solution :)
    – Emanuel
    Feb 7 at 9:16
  • 1
    Hold my beer, SantaClaus, made my day twice <3
    – Fanky
    Apr 15 at 17:35
  • 1
    A problem with this solution is that if the user navigates away and then comes back through the history, the selection is preserved but the data attribute is not. :(
    – A. Donda
    Jun 19 at 20:41

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:


  <option value="foo">Foo!</option>
  <option value="bar">Bar!</option>


var $select = $('select');
$select.each(function() {
}).on('change', function(ev) {
    $(this).attr('class', '').addClass($(this).children(':selected').val());


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; }
  • for the jQuery part - it should check the pre-selected option as well as onchange event
    – Aprillion
    May 2 '13 at 19:23
  • I have modified this select.foo, option[value="foo"] { background: red; } in jsFiddle to change background color when value="" with this select.foo, option[value=""] { background: red; } but it doesn't work. How can I change background color when value is empty?
    – VansFannel
    Jun 14 '16 at 11:24
  • 1
    @VansFannel - that's what the first line is for: select, option { background: red; } will set the default background color of the box (which typically maps to the option with no value). Jun 14 '16 at 15:35
  • I do not like this variant in that it is (miss-)using class-names. What if an option has the same name like an existing class-name? I would recommend to write the selected value in a data-attribute, which is by now supported in, I guess, all browsers and it is easy to write selectors for it. So "data"- and "style"-layers are seperated.
    – K.S.
    Nov 28 '16 at 8:32
  • Yes - probably better today. The answer was from 2013, however. Nov 28 '16 at 16:00

So here is what I found on it being possible. The biggest issue is that after you have selected an element, the background color doesn't change because the select element isn't actually redrawn (seems more prevailant in IE - go figure). So even though you select a different option, that option isn't hightlighted in the list when you click the select element again.

To fix the redrawing issues in IE, it required changing the font-size by a minimal amount, +-.1. The other thing, which doesn't seem to be documented well, is that the pseudo class :checked does also work on select controls.

The fiddler to show the added css that makes it possible.

I only briefly played with it on Chrome and IE9, fyi.

EDIT: Obviously, you will need to set the [value="x"] to your desired value for specific option highlighting.

  • this is useful - for IE and Chrome. Does not work in Firefox nor Opera at all.
    – Aprillion
    May 2 '13 at 21:58
  • 1
    @deathApril I didn't look at opera, but it not working in Firefox is actually a bug in Firefox. If you look at the applied CSS, it is actually there lol. Javascript would be required in this case.
    – Justin
    May 3 '13 at 14:09
  • thanks for the bug link, if it wasn't fixed since 2001, I don't believe in will work in Firefox any time soon :(
    – Aprillion
    May 3 '13 at 14:38
  • 2
    update: no longer works in Chrome 48.0 nor IE 11 - background of <select> is not influenced by the css for <option> at all
    – Aprillion
    Feb 14 '16 at 9:39
  • @Aprillion I just tried the fiddler on Chrome 48.0.2564.109 m and IE 11.0.9600.17239 it still worked. Can you confirm you don't have so other CSS or JS influencing the select element?
    – Justin
    Feb 15 '16 at 14:04

Pure CSS Method:-

You can style it if you want to apply style if empty value selected using :valid selector like the following code

Display in Red If Selected value is Empty

select > option {
  color: black;
select option[value=""] {
  color: red;
select[required]:invalid {
  color: red;
<select required name="fontSize">
<option value="9">9 px</option>
<option value="10">10 px</option>
<option value="11">11 px</option>
<option value="12">12 px</option>
<option value="13">13 px</option>
<option value="14">14 px</option>
<option value="15">15 px</option>
<option value="16">16 px</option>
<select required name="fontColor">
<option value="red" selected>Red</option>

  • That does not answer the question exactly. The problem becomes apparent as the form is attempted submitted with the above required control with the placeholder (value="") option chosen -- it won't submit because according to HTML 5 the placeholder label option does not make the control valid when chosen. Effectively you're just styling a select element based on validity, and even though it worked for you and is a useful answer, it should be made clear this does not really answer the original question.
    – amn
    Jun 23 at 14:59
  • @amn the original question is to "style a select element based on what option" not about form get submitted or not. he has clearly indicated it as a css question.
    – jafarbtech
    Jun 24 at 4:04
  • You must have misinterpreted the question -- it asks "based on what option is selected". What your answer explains instead is how to style the select element based on its validity (use of :valid pseudo-class). Styling a control based on validity is not the same as styling it based on what option is selected. Whether this is a CSS question is of no significance and not something I specifically argued.
    – amn
    Jun 24 at 11:02
  • @amn true. in CSS this is the maximum thing one can style based on the value. because select element doesn't even support pattern. that is why I have indicated the maximum CSS styling
    – jafarbtech
    Jun 25 at 2:09

Your Answer

