Create Custom Select CSS Styles for Focus and Disabled States

Share this video with your friends

Social Share Links

Send Tweet
Published 3 years ago
Updated 3 years ago

In the previous lesson, we set up the initial state styles for form selects and multi-selects. Now we'll add styles for the focus and disabled states, inclusive of a workaround necessary due to the lack of a parent selector in CSS.

The way we will get around this for our focus styles is to add a sibling span element to apply the styles and position those styles on top of the Select element.

Instructor: [0:00] Our custom select styles are currently missing a critical visual state which is a visual indication of focus. Looking back at how our HTML for our selects is composed, in order to achieve a custom style that we have so far, it was required to nest the native select element inside of a div. We're styling the div to produce our custom select styles.

[0:25] Because there is no parent selector in CSS, we'll need to add an additional element to assist us in providing a focus style. We'll also add it to our multiple select so that it applies in both scenarios. The placement is important because we can affect elements that follow another element easily in CSS which we'll see.

[0:48] Let's go into our form field. We'll need to begin by styling that new focus element. The goal of this element is to mimic what we were able to apply to our normal text inputs, which is to alter the border color and add a bit of box shadow.

[1:05] To achieve that, we have to first position the focus element. For this, we're going to turn to a classic solution, which uses position: absolute, and because our border width is 2px, we're going to pull it over the border of the div by using a -2 across top, left, right and bottom. Let's briefly give it a border so that we can see where that's been positioned.

[1:28] On save, we still do not see our element. Because we are using position: absolute, we need to also add position: relative to the parent select div. This allows us to ensure our absolute position element is relative to the select.

[1:43] Now we see that this has been positioned. We want to make sure that we inherit border radius value so that it matches. We'll remove that temporary border color and let's see how we can apply this on focus.

[1:58] Because when we interact with this element, it is the native select that is gaining the focus, we can use the native select along with the focus pseudo-selector and then use the + sign, which is the adjacent sibling selector, to affect styles on our focus element.

[2:16] Just to make sure this is working, let's add back in that example border. When we interact with the element, either with tab or click, we see our red border being applied. Of course, we want to swap this to our real focus styles. For this, we can once again use that mixin that we had created an add that with an include field focus.

[2:36] However, our mixin is only altering the border color, so we need to add border width and style. We'll add border 2px, solid, and leave the color as transparent. Otherwise, it would default to the current text color of the element and be visible. With that in place on tab, which gives this native select focus, we can see those focus state styles being applied as well as with mouse interaction.

[3:01] Before we conclude this lesson, we also want to resolve styling our disabled selects. Because disabled selects will never receive a focus, we do not need to add our focus element. However, once again, because of lack of a parent selector, we do need to add an additional class which will define a select--disabled so that we can identify the divs wrapping our disabled fields.

[3:25] We'll be sure to add on the multiple as well. We can use that class to attach our disabled styles. Much like we did for focus, we can include our field disabled mixin, and on save you see that's taken effect, but our selects also include a background gradient, whereas the mixin is only updating the background color.

[3:45] We need to override that for our disabled field and we're going to provide a black to white gradient and on save you can see it, this has clearly darkened the field such that it is more clear that the field is in a disabled state and our mixin is also providing the cursor have not allowed.

[4:03] The final adjustment we'll make to complete our disabled styles is within our mixin, we need to extend our color value to also apply to the select options. We'll do a bit of reorganizing and we'll apply that color value both to the initial element that's using disabled but also extend it to any options that may be present. On save, let's look at our selects across browsers and ensure that our styles have carried through.

[4:31] In this lesson, we learn to compensate for the lack of a parent selector by adding an additional span element that was able to provide the focus related styles when the native select gained a focus state.

[4:43] This was accomplished by the use of checking for the focus state on the select and using the adjacent sibling selector. We also completed our select styles by adding a disabled class in order to fully style those fields to be visually disabled.

~ 9 minutes ago

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today