<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 +'.');
  });
  
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. //cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js