Simplest Method to Custom Styling of The SELECT Elements

How it works

The solution works in a way that it dynamically adds an additional SPAN element positioned absolutely below the SELECT element. This SPAN has a custom graphic that we want to apply. SELECT element’s opacity is set to zero so it is not visible but it’s clickable. Since the SELECT element is not visible, what we see actually is the SPAN below.

This solution doesn’t style the OPTION dropdown, only the default appearance of the SELECT element but it is very applicable.

Important thing to remember: this trick relies heavily on absolute positioning. Newly created SPAN element will position itself in relation to parent element (DIV in my case). If you have other stuff inside the parent element, things like text, labels etc. make sure that you position the newly created SPAN accordingly.

Checking if any of the options is selected by default. If it is we will use it as a default value. If not, we are using the previously stored TITLE attribute value.

1

$(this).css({'z-index':10,'opacity':0,'-khtml-appearance':'none'})

For each of the SELECT elements we are setting the z-index to anything above the value of 1, opacity to zero, and we’re also removing the default styling for Safari.

1

.after('<span class="select">'+title+'</span>')

We are then adding a SPAN element that have background image set in CSS and is placed exactly below the SELECT element.

1

2

3

4

.change(function(){

val=$('option:selected',this).text();

$(this).next().text(val);

})

With every change of value for the SELECT elements we are updating the SPAN element inner text.

HTML/CSS source code

Just as a script, proper markup and CSS is very important to make this to work. SELECT elements needs to be wrapped inside a parent element (DIV in my case) that has a position property set to relative, so the newly created SPAN can be properly positioned.

This is the markup for the SELECT element:

1

2

3

4

5

6

7

8

9

10

<div>

<select class="select"title="Select one">

<option></option>

<option>Blue</option>

<option>Red</option>

<option>Green</option>

<option>Yellow</option>

<option>Brown</option>

</select>

</div>

Note the TITLE attribute. Script will use it as a default value.

CSS looks like this (some comments included):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

/* all form DIVs have position property set to relative so we can easily position newly created SPAN */

formdiv{position:relative;}

/* setting the width and height of the SELECT element to match the replacing graphics */