posted on:September 7, 2010
Custom styling of the SELECT elements
Recently I have been asked by my client to some custom styling on form elements. As you know we have no issues (well, at least no major issues) when it comes to prettifying input fields, text areas and buttons. But the form I needed to apply custom design to contained couple of select elements. Now this is something that’s not that simple.
I always aim for the simplest solutions possible in everything I do, not just work related. I enjoy having short, few lines scripts, reduced markup etc. That is why I didn’t opt for some of the ready made solutions we have out there. I rather tried to come up with the solution of my own.
Take a look at the demo or
Download files
How it works
The solution I am talking about here is actually a workaround, trick. It 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 considering the simplicity I (and my clients 🙂 ) believe that 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.
Also, as with any other project I am working on, I used jQuery as the library of choice.
The script
Here is the entire script:
$(document).ready(function(){ if (!$.browser.opera) { $('select.select').each(function(){ var title = $(this).attr('title'); if( $('option:selected', this).val() != '' ) title = $('option:selected',this).text(); $(this) .css({'z-index':10,'opacity':0,'-khtml-appearance':'none'}) .after('<span class="select">' + title + '</span>') .change(function(){ val = $('option:selected',this).text(); $(this).next().text(val); }) }); }; });
Script, line by line explained:
$(document).ready(function(){
Script executes on DOM load.
if (!$.browser.opera) {
Had some issues with transparency in Opera so I decided not to support Opera for this trick.
$('select.select').each(function(){
What follows will apply to every SELECT element with the class name select
var title = $(this).attr('title');
Each SELECT element should have TITLE attribute set to whatever we want to show as a default value of the drop down. We are storing the value of the TITLE attribute in a variable for further usage.
if( $('option:selected', this).val() != '' ) title = $('option:selected',this).text();
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.
$(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.
.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.
.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:
<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 defautl value.
CSS looks like this (some comments included):
/* all form DIVs have position property set to relative so we can easily position newly created SPAN */ form div{position:relative;} /* setting the width and height of the SELECT element to match the replacing graphics */ select.select{ position:relative; z-index:10; width:166px !important; height:26px !important; line-height:26px; } /* dynamically created SPAN, placed below the SELECT */ span.select{ position:absolute; bottom:0; float:left; left:0; width:166px; height:26px; line-height:26px; text-indent:10px; background:url(images/bg_select.gif) no-repeat 0 0; cursor:default; z-index:1; }
Try the demo, download the files and of course let me know what you think 🙂
Enjoyed the article?
Then don't miss our next one! Subscribe to our RSS feed or share it with your friends.
Share on FacebookTweet thisDeliciousStumbleUpon RedditSubscribe
Comments (27 Comments)
Sorry, the comment form is closed at this time.
Thomas Svensson
September 7, 2010
Mladen Stepanic
September 7, 2010
Pippin
September 7, 2010
cssglobe
September 7, 2010
Davor
September 7, 2010
IGotNothin
September 7, 2010
Matt
September 8, 2010
Carlos
September 8, 2010
Mike
September 10, 2010
Wael Al-Sallami
September 12, 2010
ANdReiâ„¢
September 12, 2010
Mathias
September 12, 2010
Diti
September 12, 2010
Jonathan
September 12, 2010
Ricardo
September 13, 2010
XingWoo
September 13, 2010
Thany
September 13, 2010
Volomike
September 13, 2010
Ritu
September 14, 2010
cmacias
September 19, 2010
Beben
September 22, 2010
Ben Stokes
September 25, 2010
algerien-dev
September 26, 2010
Antti202
September 29, 2010
tildy
September 30, 2010
Web Designer Leicester
September 30, 2010
David Christian-Woodruff
October 6, 2010