select(プルダウン) の文字を左右中央揃えにしたいときのCSSメモ


select に text-align:centerは効かない

select タグのテキストを左右中央にしたいのですが、
text-align: center; が効かず、
text-indentを%指定したりすればインデントされるのですが、
文字数が不確定の場合はうまいこといきません。

無理矢理な方法ですが、
selectの文字自体は透明にしておき、selectと同じ幅の p なりに同じテキストを入れて、これにtext-align:center をするのはどうか、というサンプルです。

サンプルデモ

Codepen
http://codepen.io/skwbr/pen/JYGQLv

コード

html
<div class="btn-select">
<p class="label">選択してください</p>
<select class='select'>
  <option value=''>選択してください</option>
  <option value='1'>選択肢1</option>
  <option value='2'>選択肢2</option>
  <option value='3'>選択肢3</option>
</select>
</label>
</div>

はじめ p をselectの上に乗せて、pointer-events: none; でクリックを背面(select)に送っていたのですが、IE10以前で pointer-events が効かないようなので、select をopacityで透明にして、クリックは受け付けつつ背面のpが見えるように、という感じにしています。

css
body {
  text-align: center;
}

.btn-select {
  width: 300px;
  margin: 20px auto;
  position: relative;
  background: #333;
  border-radius: 6px;
  cursor: pointer; /* IEでcursorがチラついたので */
}

.label {
  color: #fff;
  position: absolute;
  width: 100%;
  z-index: 1;
}

.select {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  display: block;
  cursor: pointer;
  width: 100%;
  border: none;
  padding: 20px;
  opacity: 0;
  position: relative;
  z-index: 2;
}

/* IE10以上で矢印を消す */
.select::-ms-expand {
  display: none; 
}

/* フォーカス時 */
.select:focus {
  z-index: -1;
  opacity: 1;
}

ラベルの変わらないボタン的に使う場合は、JSは不要ですが、
selectと同じようにonchangeでラベルを変えたいときはやはりJSを用います。

js
// selectと同じようにonchangeでラベルを変えたいときはJSを用いる
$('.select').on('change', function(){

  var $this = $(this)
  var $option = $this.find('option:selected');
  $('.label').text($option.text());

  // onchange後にフォーカスしてるのが嫌な場合
  $this.blur();

});

Webアクセシビリティ的な問題もありそうですが、
ひとつの一例として紹介でした。

出典/参考

"CSS pointer-events (for HTML) | Can I use..."
http://caniuse.com/#feat=pointer-events

"CSSだけで<select>をカスタマイズする - Qiita"
http://qiita.com/hiloki@github/items/844726db4128ebb0fdd8