<div class="wrapper">
<h1>Pretty and Easy Custom Select Boxes</h1>
<p>With a little bit of CSS and jQuery, any select object on your site can be transformed from boring browser default to whatever your heart desires.</p>
<p>The script currently handles basic things like <code>disabled</code> and <code>selected</code>. It also works for <code>options</code> with different values and text.</p>
<div class="module">
<h3>What do you want?</h3>
<select name="select" id="what">
<option value="a disabled select value" disabled>a disabled select value</option>
<option value="Hello World!">an option with a different value</option>
<option value="more options">more options</option>
<option value="cookies">cookies</option>
<option value="ice cream">ice cream</option>
<option value="pizza">pizza</option>
<option value="sushi">sushi</option>
<option value="fruit">fruit</option>
</select>
<h3>When do you want it?</h3>
<select name='options' id="when">
<option value='in 30 minutes'>30 minutes</option>
<option value='at a different starting point' selected>at a different starting point</option>
<option value='right now'>Right now</option>
</select>
<div class="output">Select options to change output.</div>
</div>
<div class="module">For comparison, here is your browser default:
<select name='options' class="default">
<option value='option-1'>Option 1</option>
<option value='option-2'>Option 2</option>
<option value='option-3'>Option 3</option>
</select><br />
<span style="font-size:.9em;">(Add the class "default" to a select box to disable custom styling.)</span>
</div>
</div>
/** CodePen styles (keep scrolling for relevant styles) **/
*, *:before, *:after { box-sizing: border-box; }
body { padding: 50px; background-image: linear-gradient(to top, #fff, #e6e6e6); }
.wrapper {
max-width: 100%;
width: 600px;
margin: 0 auto;
}
code { background: #e6e6e6; padding: 1px 3px; }
a { color: #666; }
.module {
margin-top: 2em;
padding: 20px 40px;
border-radius: 10px;
color: white;
background: rgba(black, 0.5);
}
.output {
display: block;
max-width: 500px;
background: white;
color: black;
border: 1px dotted black;
padding: 1em;
margin: 2em 0 1em;
position: relative;
&:before {
content: 'Output';
text-transform: uppercase;
font-size: .7em;
color: #e6e6e6;
position: absolute;
top: -1.2em;
left: 8px;
}
}
/** Relevant styles below this line **/
.selected { /* The select box */
display: inline-block;
min-width: 200px;
background: white;
color: black;
border: 1px solid black;
padding: 5px;
cursor: pointer;
user-select: none;
&:after { /* The "dropdown" arrow */
content: '';
box-sizing: content-box;
display: inline-block;
float: right;
width: 0;
height: 0;
margin: 5px 0 5px 5px;
border-style: solid;
border-width: 8px 5px 0 5px;
border-color: #000000 transparent transparent transparent;
}
}
.fancy-select { /* Dropdown options container */
list-style: none;
min-width: 200px;
max-height: 115px;
margin: 0;
padding: 0;
display: block;
border: 1px solid black;
background-color: white;
overflow-y: scroll;
overflow-x: hidden;
position: absolute;
z-index: 2;
user-select: none;
.fancy-option { /* Individual options */
padding: 5px;
background: white;
color: black;
cursor: pointer;
&:hover {
background: blue;
color: white;
}
&.disabled {
color: rgba(black, .5);
background: white;
cursor: default;
&:hover {
color: rgba(black, .5);
background: white;
}
}
}
}
View Compiled
/**
* Fancy Select Box by Austin Wulf
* http://www.austinwulf.com
*
* To add:
* + keyboard support, including:
* - arrow keys
* - return/space for select
* - tab focus
* + touch support
* + better accessibility
* + open above box instead of below when
* dropdown is at viewport bottom
**/
$(document).ready(function(){
var $select = $('select'),
$speed = 'fast';
$select.each(function(){
// Allow default browser styling
if ( $(this).hasClass('default') ) {
return;
}
$(this).css('display', 'none');
// Generate fancy select box
$(this).after('<ul class="fancy-select" style="display: none;"></ul>');
var $current = $(this),
$fancy = $current.next('.fancy-select');
// Get options
var $options = $(this).find('option');
$options.each(function(index){
var $val = $(this).val(),
$text = $(this).text(),
$disabled = '';
// Add class for disabled options
if ( $(this).attr('disabled') ) $disabled = ' disabled';
if ( index == 0 ) {
// Create clickable object from first option
$fancy.before('<span class="selected" data-val="'+ $val +'">'+ $text +'</span>');
}
// Load all options into fake dropdown
$fancy.append('<li class="fancy-option'+ $disabled +'" data-val="'+ $val +'">'+ $text +'</li>');
// Update fake select box if this option is selected
if ( $(this).attr('selected') ) {
$(this).parent('select').val($val);
$(this).parent('select').next('.selected').attr('data-val', $val).text($text);
}
});
});
// Show/hide options on click
$('.selected').click(function(target){
var $box = $(this).next('.fancy-select'),
$target = target,
$object = $(this);
// Prevent multiple open select boxes
if ( $box.is(':visible') ) {
$box.slideUp($speed);
return;
} else {
$('.fancy-select').slideUp();
$box.slideDown($speed);
}
// Click outside select box closes it
$target.stopPropagation();
if ( $box.css('display') !== 'none' ) {
$(document).click(function(){
$box.slideUp($speed);
});
}
});
// Make selection
$('.fancy-option').click(function(){
var $val = $(this).attr('data-val'),
$text = $(this).text(),
$box = $(this).parent('.fancy-select'),
$selected = $box.prev('.selected'),
$disabled = $(this).hasClass('disabled');
// Basic disabled option functionality
if ( $disabled ) {
return;
}
$box.slideUp($speed);
// Update select object's value
// and the fake box's "value"
$selected.prev('select').val($val);
$selected.attr('data-val', $val).text($text);
// Get Output
var $what = $('#what').val(),
$when = $('#when').val();
$('.output').text('You want '+ $what +' '+ $when +'.');
});
});
This Pen doesn't use any external CSS resources.