selectのテキストを中心で揃える方法(safari対応)

Pocket

selectのテキストを中心に揃えようとすると、safariでは select の text-align:center が効かず、左に揃ってしまう。
なんとかしたいという要望に、調査・対応。

方法の調査

方法1: selectそのものの幅を、selectされたoptionの幅に合わせる

 

方法2: 幅を決めて、その中に(やや強引に)中心寄せする

案2を採用しました。
 

方法2の注意点

余計なcssを削除したり、paddingやmarginを調整する

html

上記リンクでは、要素を指定するのにclassを使っているが、複数ある場合はidで指定したほうが無難か。

                        <div class="btn-select" style="">
                            <p id="hoge_label" class="label"><?php // ここにSELECTED値 ?></p>
                            <select id="select_hoge_id" class='select' name="hoge_id">
                                <option value=''>Categories</option>
                                <option value='1'>Option 1</option>
                                <option value='2'>Option 2</option>
                                <option value='3'>Option 3</option>
                             </select>
                        </div>

のように、selected な値をpに入れる。

css

.btn-select {
    width: 200px; ← 幅
    height:40px; ← hとする
    padding:5px 0; ← pとする
    position: relative;
    background: #f8f8f8; ← select部の背景色
    border-radius: 6px;
    cursor: pointer;
    vertical-align:bottom; ← inlineでキレイに見せるため
    display:inline-block; ← inlineでキレイに見せるため
    margin: 0 10px; ← 左右に隙間を入れる
    border:1px solid #d3d3d3;← select部の枠
}
.btn-select .label {
  position: absolute;
  width: 100%;
  z-index: 1;
}
.btn-select .select {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  display: block;
  cursor: pointer;
  width: 100%;
  height:30px; ← h-2*p の値 にするとキレイに見える。 40 - 5*2 = 30
  border: none;
  padding: 0px;
  opacity: 0;
  position: relative;
  z-index: 2;
}
.btn-select .select::-ms-expand {
    display: none;
}
.btn-select .select:focus {
    z-index: -1;
    opacity: 1;
}

js

javascriptは、classで指定してもいいが、複数ある場合はidで指定したほうが無難か。

<script>
// selectと同じようにonchangeでラベルを変えたいときはJSを用いる
jQuery('select#select_hoge_id').on('change', function(){
    var $this = jQuery(this)
    var $option = $this.find('option:selected');
    jQuery('#hoge_label').text($option.text());
    // onchange後にフォーカスしてるのが嫌な場合
    $this.blur();
});
</script>