In this article I have describe, how to create stylish Dropdown control in HTML using CSS and JQuery. There are few simple steps, using that you make your web application more attractive.
Step 1: First create a simple Html page with default dropdown control as below
<!DOCTYPE html>
<html>
<head>
<title>Stylish Dropdown List</title>
</head>
<body>
<table>
<tr>
<td>
<span>Select Language</span>
</td>
<td>
<div class="example">
<select name="country" class="default">
<option>C</option>
<option>C++</option>
<option>C#</option>
<option>VB</option>
<option>Java</option>
</select>
</div>
</td>
</tr>
</table>
</body>
</html>
Screen Shot
Step 2: Include CSS, JavaScript and JQuery file as below
<!DOCTYPE html>
<html>
<head>
<title>Stylish Dropdown list</title>
<style type="text/css">
*
{
margin: 0;
padding: 0;
}
.group:before, .group:after
{
content: "";
display: table;
}
.group:after
{
clear: both;
}
.group
{
zoom: 1; /* For IE 6/7 (trigger hasLayout) */
}
.gist
{
font-weight: normal;
}
.gist a
{
color: #556270 !important;
}
.gist-file
{
border: none !important;
}
.gist-meta
{
background-color: transparent !important;
font-size: 10px !important;
}
.gist-data
{
background-color: transparent !important;
}
.gist-highlight .line
{
color: #999 !important;
}
.gist-highlight .nt, .gist-highlight .na
{
color: #556270 !important;
}
.gist-highlight .s
{
color: #C44D58 !important;
}
.gist-highlight .nx
{
color: #3B2D38 !important;
}
.example
{
background-color: rgba(255, 255, 255, .5);
margin-bottom: 20px;
padding: 18px;
}
.example .gist-data
{
font-size: 12px !important;
}
.dk_container
{
margin-right: 10px;
}
</style>
<style type="text/css">
/* One container to bind them... */
.dk_container {
background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f5f5f5));
background: -moz-linear-gradient(top, #fff, #f5f5f5);
background: -o-linear-gradient(top, #fff, #f5f5f5);
background-color: #f5f5f5;
font-family: 'Helvetica', Arial, sans-serif;
font-size: 12px;
font-weight: bold;
line-height: 14px;
margin-bottom: 18px;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
.dk_container:focus {
outline: 0;
}
.dk_container a {
cursor: pointer;
text-decoration: none;
}
/*Path of drop down image dk_arrows.png path*/
.dk_toggle {
background:url(Images/dropDownArrow.png) no-repeat right #FFF;
border: 1px solid #ccc;
color: #333;
padding: 5px 45px 5px 5px;
}
/* Applied when the dropdown is focused */
.dk_focus .dk_toggle {
border-color: Black;
}
/* The outer container of the options */
.dk_options {
box-shadow: rgba(0, 0, 0, .2) 0 2px 8px;
-moz-box-shadow: rgba(0, 0, 0, .2) 0 2px 8px;
-webkit-box-shadow: rgba(0, 0, 0, .2) 0 2px 8px;
border-radius: 0 0 5px 5px;
-moz-border-radius: 0 0 5px 5px;
-webkit-border-radius: 0 0 5px 5px;
}
.dk_options a {
background-color: #fff;
font-weight: bold;
padding: 8px 10px;
}
.dk_options li:last-child a {
border-bottom: none;
}
.dk_options a:hover,
.dk_option_current a {
background-color: #880015;
border-bottom-color: #880015;
color: #fff;
text-decoration: none;
text-shadow: rgba(0, 0, 0, .5) 0 1px 0;
}
/* Inner container for options, this is what makes the scrollbar possible. */
.dk_options_inner {
border: 1px solid black;
color: #333;
max-height: 250px;
text-shadow: #fff 0 1px 0;
-moz-border-radius: 0 0 5px 5px;
-webkit-border-radius: 0 0 5px 5px;
}
/* Set a max-height on the options inner */
.dk_options_inner,
.dk_touch .dk_options {
max-height: 250px;
}
/***** Critical to the continued enjoyment of working dropdowns ******/
.dk_container {
display: none;
float: left;
position: relative;
}
.dk_container a {
outline: 0;
}
.dk_toggle {
display: -moz-inline-stack;
display: inline-block;
*display: inline;
position: relative;
zoom: 1;
}
.dk_open {
position: relative;
}
.dk_open .dk_options {
display: block;
}
.dk_open .dk_label {
color: inherit;
}
.dk_options {
display: none;
margin-top: -1px;
position: absolute;
right: 0;
width: 100%;
}
.dk_options a,
.dk_options a:link,
.dk_options a:visited {
display: block;
}
.dk_options_inner {
overflow: auto;
position: relative;
}
.dk_touch .dk_options {
overflow: hidden;
}
.dk_touch .dk_options_inner {
max-height: none;
overflow: visible;
}
.dk_fouc select {
position: relative;
top: -99999em;
visibility: hidden;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"
charset="utf-8"></script>
<script type="">
(function ($, window, document) {
var ie6 = false;
// Help prevent flashes of unstyled content
if ($.browser.msie && $.browser.version.substr(0, 1) < 7) {
ie6 = true;
} else {
document.documentElement.className = document.documentElement.className + ' dk_fouc';
}
var
// Public methods exposed to $.fn.dropkick()
methods = {},
// Cache every <select> element that gets dropkicked
lists = [],
// Convenience keys for keyboard navigation
keyMap = {
'left': 37,
'up': 38,
'right': 39,
'down': 40,
'enter': 13
},
// HTML template for the dropdowns
dropdownTemplate = [
'<div class="dk_container" id="dk_container_{{ id }}" tabindex="{{ tabindex }}">',
'<a class="dk_toggle">',
'<span class="dk_label">{{ label }}</span>',
'</a>',
'<div class="dk_options">',
'<ul class="dk_options_inner">',
'</ul>',
'</div>',
'</div>'
].join(''),
// HTML template for dropdown options
optionTemplate = '<li class="{{ current }}"><a data-dk-dropdown-value="{{ value }}">{{ text }}</a></li>',
// Some nice default values
defaults = {
startSpeed: 1000, // I recommend a high value here, I feel it makes the changes less noticeable to the user
theme: false,
change: false
},
// Make sure we only bind keydown on the document once
keysBound = false
;
// Called by using $('foo').dropkick();
methods.init = function (settings) {
settings = $.extend({}, defaults, settings);
return this.each(function () {
var
// The current <select> element
$select = $(this),
// Store a reference to the originally selected <option> element
$original = $select.find(':selected').first(),
// Save all of the <option> elements
$options = $select.find('option'),
// We store lots of great stuff using jQuery data
data = $select.data('dropkick') || {},
// This gets applied to the 'dk_container' element
id = $select.attr('id') || $select.attr('name'),
// This gets updated to be equal to the longest <option> element
width = settings.width || $select.outerWidth(),
// Check if we have a tabindex set or not
tabindex = $select.attr('tabindex') ? $select.attr('tabindex') : '',
// The completed dk_container element
$dk = false,
theme
;
// Dont do anything if we've already setup dropkick on this element
if (data.id) {
return $select;
} else {
data.settings = settings;
data.tabindex = tabindex;
data.id = id;
data.$original = $original;
data.$select = $select;
data.value = _notBlank($select.val()) || _notBlank($original.attr('value'));
data.label = $original.text();
data.options = $options;
}
// Build the dropdown HTML
$dk = _build(dropdownTemplate, data);
// Make the dropdown fixed width if desired
$dk.find('.dk_toggle').css({
'width': width + 'px'
});
// Hide the <select> list and place our new one in front of it
$select.before($dk);
// Update the reference to $dk
$dk = $('#dk_container_' + id).fadeIn(settings.startSpeed);
// Save the current theme
theme = settings.theme ? settings.theme : 'default';
$dk.addClass('dk_theme_' + theme);
data.theme = theme;
// Save the updated $dk reference into our data object
data.$dk = $dk;
// Save the dropkick data onto the <select> element
$select.data('dropkick', data);
// Do the same for the dropdown, but add a few helpers
$dk.data('dropkick', data);
lists[lists.length] = $select;
// Focus events
$dk.bind('focus.dropkick', function (e) {
$dk.addClass('dk_focus');
}).bind('blur.dropkick', function (e) {
$dk.removeClass('dk_open dk_focus');
});
setTimeout(function () {
$select.hide();
}, 0);
});
};
// Allows dynamic theme changes
methods.theme = function (newTheme) {
var
$select = $(this),
list = $select.data('dropkick'),
$dk = list.$dk,
oldtheme = 'dk_theme_' + list.theme
;
$dk.removeClass(oldtheme).addClass('dk_theme_' + newTheme);
list.theme = newTheme;
};
// Reset all <selects and dropdowns in our lists array
methods.reset = function () {
for (var i = 0, l = lists.length; i < l; i++) {
var
listData = lists[i].data('dropkick'),
$dk = listData.$dk,
$current = $dk.find('li').first()
;
$dk.find('.dk_label').text(listData.label);
$dk.find('.dk_options_inner').animate({ scrollTop: 0 }, 0);
_setCurrent($current, $dk);
_updateFields($current, $dk, true);
}
};
// Expose the plugin
$.fn.dropkick = function (method) {
if (!ie6) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
}
}
};
// private
function _handleKeyBoardNav(e, $dk) {
var
code = e.keyCode,
data = $dk.data('dropkick'),
options = $dk.find('.dk_options'),
open = $dk.hasClass('dk_open'),
current = $dk.find('.dk_option_current'),
first = options.find('li').first(),
last = options.find('li').last(),
next,
prev
;
switch (code) {
case keyMap.enter:
if (open) {
_updateFields(current.find('a'), $dk);
_closeDropdown($dk);
} else {
_openDropdown($dk);
}
e.preventDefault();
break;
case keyMap.up:
prev = current.prev('li');
if (open) {
if (prev.length) {
_setCurrent(prev, $dk);
} else {
_setCurrent(last, $dk);
}
} else {
_openDropdown($dk);
}
e.preventDefault();
break;
case keyMap.down:
if (open) {
next = current.next('li').first();
if (next.length) {
_setCurrent(next, $dk);
} else {
_setCurrent(first, $dk);
}
} else {
_openDropdown($dk);
}
e.preventDefault();
break;
default:
break;
}
}
// Update the <select> value, and the dropdown label
function _updateFields(option, $dk, reset) {
var value, label, data;
value = option.attr('data-dk-dropdown-value');
label = option.text();
data = $dk.data('dropkick');
$select = data.$select;
$select.val(value);
$dk.find('.dk_label').text(label);
reset = reset || false;
if (data.settings.change && !reset) {
data.settings.change.call($select, value, label);
}
}
// Set the currently selected option
function _setCurrent($current, $dk) {
$dk.find('.dk_option_current').removeClass('dk_option_current');
$current.addClass('dk_option_current');
_setScrollPos($dk, $current);
}
function _setScrollPos($dk, anchor) {
var height = anchor.prevAll('li').outerHeight() * anchor.prevAll('li').length;
$dk.find('.dk_options_inner').animate({ scrollTop: height + 'px' }, 0);
}
// Close a dropdown
function _closeDropdown($dk) {
$dk.removeClass('dk_open');
}
// Open a dropdown
function _openDropdown($dk) {
var data = $dk.data('dropkick');
$dk.find('.dk_options').css({ top: $dk.find('.dk_toggle').outerHeight() - 1 });
$dk.toggleClass('dk_open');
}
/**
* Turn the dropdownTemplate into a jQuery object and fill in the variables.
*/
function _build(tpl, view) {
var
// Template for the dropdown
template = tpl,
// Holder of the dropdowns options
options = [],
$dk
;
template = template.replace('{{ id }}', view.id);
template = template.replace('{{ label }}', view.label);
template = template.replace('{{ tabindex }}', view.tabindex);
if (view.options && view.options.length) {
for (var i = 0, l = view.options.length; i < l; i++) {
var
$option = $(view.options[i]),
current = 'dk_option_current',
oTemplate = optionTemplate
;
oTemplate = oTemplate.replace('{{ value }}', $option.val());
oTemplate = oTemplate.replace('{{ current }}', (_notBlank($option.val()) === view.value) ? current : '');
oTemplate = oTemplate.replace('{{ text }}', $option.text());
options[options.length] = oTemplate;
}
}
$dk = $(template);
$dk.find('.dk_options_inner').html(options.join(''));
return $dk;
}
function _notBlank(text) {
return ($.trim(text).length > 0) ? text : false;
}
$(function () {
// Handle click events on the dropdown toggler
$('.dk_toggle').live('click', function (e) {
var $dk = $(this).parents('.dk_container').first();
_openDropdown($dk);
if ("ontouchstart" in window) {
$dk.addClass('dk_touch');
$dk.find('.dk_options_inner').addClass('scrollable vertical');
}
e.preventDefault();
return false;
});
// Handle click events on individual dropdown options
$('.dk_options a').live(($.browser.msie ? 'mousedown' : 'click'), function (e) {
var
$option = $(this),
$dk = $option.parents('.dk_container').first(),
data = $dk.data('dropkick')
;
_closeDropdown($dk);
_updateFields($option, $dk);
_setCurrent($option.parent(), $dk);
e.preventDefault();
return false;
});
// Setup keyboard nav
$(document).bind('keydown.dk_nav', function (e) {
var
// Look for an open dropdown...
$open = $('.dk_container.dk_open'),
// Look for a focused dropdown
$focused = $('.dk_container.dk_focus'),
// Will be either $open, $focused, or null
$dk = null
;
// If we have an open dropdown, key events should get sent to that one
if ($open.length) {
$dk = $open;
} else if ($focused.length && !$open.length) {
// But if we have no open dropdowns, use the focused dropdown instead
$dk = $focused;
}
if ($dk) {
_handleKeyBoardNav(e, $dk);
}
});
});
})(jQuery, window, document);
</script>
<script type="text/javascript">
$(function () {
$('.default').dropkick();
$('.black').dropkick({
theme: 'black'
});
$('.change').dropkick({
change: function (value, label) {
alert('You picked: ' + label + ':' + value);
}
});
$('.existing_event').dropkick({
change: function () {
$(this).change();
}
});
$('.custom_theme').dropkick({
theme: 'black',
change: function (value, label) {
$(this).dropkick('theme', value);
}
});
$('.dk_container').first().focus();
});
</script>
</head>
<body>
<table>
<tr>
<td>
<span>Select Language</span>
</td>
<td>
<div class="example">
<select name="country" class="default" tabindex="2">
<option>C</option>
<option>C++</option>
<option>C#</option>
<option>VB</option>
<option>Java</option>
</select>
</div>
</td>
</tr>
</table>
</body>
</html>
Step 3: Dropdown arrow image as given below. Save image and set the path into second style into dk_toggle class.
Sushant Mishra
27-Jul-2017It was really helpful to read this post.