jquery.select_skin.js

This jQuery plugin can skin <SELECT> lists. The plugin has the advantage of keeping the SELECT element working as usual, which is useful when other scripts work on the element. Plus it doesn't require extra markup and very little CSS.

Download

Download the lastest release: 1.0.7. The plugin is also listed on the jQuery site.

Demos

Normal select with no CSS, and its skinned version
Skinned select with a button

There is only an image, which is set as a right-aligned background of the container. Note that the text DIV is as large as the container, minus the height of the container, so to allow some room for a square button

Skinned select, with Javascript events

The original SELECT is still functional, and events are kept.

Select with skin/unskin buttons

Concept

All the scripts changing the look of a SELECT box replace the SELECT element with one or more DIVs. This allows for great customization, but we loose the ability to have events on our SELECT list. So the skinning script cannot be used alongside other scripts, such as linked list scripts, etc...

Derek Harvey presented another solution, which was to hide the SELECT box, and use a text label instead. However, the SELECT is simply transparent, and placed above the text label, and it can open and close as usual. This is important in the sense that the users (or other scripts) manipulate the SELECT and not the text label or some DIVs.

I improved the code, so that no extra markup is needed. You can simply apply the plugin to any existing SELECT box, without adding extra DIVs. I also added some capabilities to copy the SELECT style and dimension. So to some extent, the skinned SELECT will look like the original SELECT. It duplicates the colors, font size, and of course width and height. The only thing that doesn't work is the border. All the essential CSS is set in the script, but you can add yours if you wish. By default, there is no button to the SELECT select, but it is easy to add via CSS with one single image.

Usage

First, include the file jquery.select_skin.js in your page. Then, apply the select_skin plugin to any jQuery element you want:

jQuery(document).ready(function() {
    jQuery("#my-select").select_skin();
});

You can also remove the skinning:

jQuery("#unskin").click( function() {
    jQuery("#my-select").select_unskin();
});

The styles will be copied from the select element. But you can add a background image to do a button. There are only two classes:

div.cmf-skinned-select {
    background: url('skin.png') top right no-repeat ;
    border: 1px solid #ccc;
}
div.cmf-skinned-text {
    padding: 3px;
}

Notes

- First, this is my first jQuery plugin, so I am sure it could be done in a more elegant way. Besides, it hasn't really been tested much....

- It works with Firefox/Linux, Safari/Linux, Chrome/Linux, etc... and IE, despite causing problems, seems to do fairly well as far as I could test it. The plugin does not work with IE6, but it should degrade gracefully.

- The plugin doesn't do anything on multiple SELECTs. So you will have the normal scrollbars on multiple SELECTs, but you can set the border via CSS, and achieve a good looking SELECT.

- One thing annoys me: the border CSS properties are not copied from the SELECT to the text DIV. Why this doesn't work? (I also tried with border-width, border-style and border-color):

selectContainer.css('border', selectObject.css('border'));

- The font-size property cannot be copied, as it confuses IE, which renders the text with a huge size. So you will have to set it via CSS. Anyone knows a fix for that? In any case, you will get better results by setting explicitely a font to the orginal SELECT.

- I noticed that an inline SELECT becomes a block, but this is easy to fix:

div.cmf-skinned-select {
    display:-moz-inline-stack;
    display:inline-block;
    zoom:1;
    *display:inline;
}

Feel free to email me with any feedback, fixes, improvements, etc...