Custom <select> element with flexible width
by Takayuki Shimada
HTML
<h3>基本形</h3>
<p>
<span class="select">
<select class="select-select">
<option>1 ほげほげ</option>
<option>2 ふがふがふがふがふがふが</option>
<option>3 ぴよ</option>
</select>
<span class="select-value"></span>
</span>
</p>
<h3>max-width を当てる</h3>
<p>
<span class="select" style="max-width:300px">
<select class="select-select">
<option>ほげほげ</option>
<option>ふがふがふがふがふがふがふがふがふがふがふがふが</option>
<option>ぴよ</option>
</select>
<span class="select-value"></span>
</span>
</p>
<h3>テキストと並べる</h3>
<p>
ほげほげ
<span class="select" style="max-width:300px">
<select class="select-select">
<option>ほげ</option>
<option>ふが</option>
<option>ぴよ</option>
</select>
<span class="select-value"></span>
</span>
ふがふが
</p>
<h3>ちょっとカッコよくする</h3>
<p>
<span class="select select_cool">
<select class="select-select">
<option>1 ほげほげ</option>
<option>2 ふがふがふがふがふがふが</option>
<option>3 ぴよ</option>
</select>
<span class="select-value"></span>
</span>
</p>
CSS
html {
background-color: #eee;
}
.select {
display: inline-block;
position: relative;
z-index: 0;
border: 3px solid #000;
overflow: hidden;
}
.select:after {
content: "▼";
display: block;
position: absolute;
top: 0;
right: 0;
width: 20px;
color: #fff;
background-color: #000;
text-align: center;
line-height: 28px;
}
.select-select {
position: relative;
z-index: 2;
width: 100%;
height: 28px;
margin: 0;
padding: 3px 30px 3px 3px;
font: inherit;
opacity: 0;
-ms-filter: alpha(opacity=0);
-webkit-appearance: none;
}
.select-select:focus {
filter: none;
}
.select-value {
-moz-box-sizing: border-box;
box-sizing: border-box;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1;
overflow: hidden;
width: auto;
height: auto;
padding: 0 20px 0 9px;
line-height: 28px;
white-space: nowrap;
text-overflow: ellipsis;
}
.select-select:focus ~ .select-value {
outline: thin dotted #333;
outline: 2px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
.select_cool {
background: url(http://necomesi.jp/blog/tsmd/wp-content/uploads/sites/3/2014/04/select_bg.png) no-repeat right center #fff;
border: 1px solid #ccc;
border-radius: 3px;
box-shadow: 1px 1px 0 rgba(255, 255, 255, .5);
}
.select_cool:after {
content: normal;
}
JavaScript
function Select($el) {
this.$el = $($el);
this.$select = this.$el.find('.select-select');
this.select = this.$select[0];
this.$value = this.$el.find('.select-value');
this.$select.on('change keydown', $.proxy(this, '_onChange')).change();
}
Select.prototype._onChange = function (e) {
setTimeout($.proxy(this, 'update'), 0);
};
Select.prototype.update = function () {
var option = this.select.options[this.select.selectedIndex];
var value = option.textContent || options.innerText;
this.$value.text(value);
};
$(function () {
$('.select').each(function () {
new Select(this);
});
});