select要素デザイン時に事件は起こった!
select要素(プルダウン)のデザインを実装している時に、矢印アイコンを画像ではなくCSSのみで実装する場合の方が最近は多くなってきました。
今回私もinput要素を非表示にし、label要素と擬似要素、beforeを使用しました。
デザインはこんな感じで問題ありませんでした。
しかしここで問題が!!
Select要素(プルダウン)の上にある擬似要素beforeでデザインした矢印の位置をposition:absolute;で指定していました。
そのせいで矢印が配置してある下にあるSelect要素(プルダウン)の部分のみクリックしても反応しない😭
矢印以外の位置をクリックした時には問題ありませんでした。
これは地味に気持ち悪いですよね。。。。
そんな時に簡単に回避する方法がpointer-events:none;です!!
矢印をデザインしているbefore要素に追加するだけで矢印エリアをクリックしても下にあるselect要素(プルダウン)が反応しました!!
デモサイトを作成しましたのでこちらよりご確認いただけます!
pointer-eventsって?
結構検索すると分かりやすくまとめている方がいらっしゃるので、そちらを参考にしていただければと思います!
こちらでも簡単にご説明を。。
pointer-eventsとは特定の要素がマウスイベントの対象になる際そのクリックの挙動を指定します。
こんな時便利!!
・要素の下にあるクリックイベントを優先したい
・aタグの動作を無効にしたい
・画像を長押し保存(SP)、control保存(PC)できないようにしたい など
実装方法
・クリックしたくない要素の場合 pointer-event: none;
・クリックできるようにしたい場合 pointer-event: auto;
※ただしIE10以下のブラウザは非対応ですのでご注意ください!
CSS
.form__select__list { display: table; width: 300px; padding: 0; table-layout: fixed; } .form__select__item { display: table-cell; position: relative; } .form__select__item .ico__arrow-btm, .form__select__item .ico__arrow-btm-none { position: relative; } .form__select__item .ico__arrow-btm:before, .form__select__item .ico__arrow-btm-none:before { position: absolute; right: 10px; width: 8px; height: 8px; top: 30%; content: ''; z-index: 1; border: 0px; border-top: solid 2px #999; border-right: solid 2px #999; -ms-transform: rotate(135deg); -webkit-transform: rotate(135deg); transform: rotate(135deg); } .form__select__item .ico__arrow-btm:before{ pointer-events: none; } .form__select { padding: 0 20px; width: 100%; height: 40px; background-color: #fff; border: 1px solid #ccc; border-radius: 5px; line-height: 40px; box-sizing: border-box; font-size: 13px; } .form__select__item select { outline: none; appearance: none; -moz-appearance: none; -webkit-appearance: none; }
HTML
pointer-events: none;なし
<ul class="form__select__list"> <li class="form__select__item"> <div class="ico__arrow-btm-none"> <select class="form__select" name="test"> <option value="white">white</option> <option value="black">black</option> <option value="gray">gray</option> <option value="blue">blue</option> </select> </div> </li> </ul>
pointer-events: none;あり
<ul class="form__select__list"> <li class="form__select__item"> <div class="ico__arrow-btm"> <select class="form__select" name="test"> <option value="white">white</option> <option value="black">black</option> <option value="gray">gray</option> <option value="blue">blue</option> </select> </div> </li> </ul>
その他汎用性の高いformeデザインいろいろ
ラジオボタン、チェックボックス01
CSS
/* radio-list,checkbox-list */ .form-box input[type='radio'], .form-box input[type='checkbox'] { display: none; } .form__type-list, .form__detail-list { display: inline-block; } .form__type-item, .form__detail-item { display: inline; } .form__type-label, .form__detail-label { display: inline-block; position: relative; padding: 10px; color: #333; box-sizing: border-box; cursor: pointer; font-size: 14px; } .form__type-text, .form__detail-text { padding-left: 20px; position: relative; } input[type='radio']:disabled+.form__type-label, input[type='checkbox']:disabled+.form__detail-label { color: #999; cursor: default; } input[type='radio']:checked+.form__type-label .form__type-text:before { border-color: #FF93A0; } input[type='radio']:checked+.form__type-label .form__type-text:after { width: 6px; height: 6px; position: absolute; top: 50%; left: 3px; background-color: #FF93A0; border-radius: 50%; content: ''; -webkit-transform: translate(0, -50%); -moz-transform: translate(0, -50%); -ms-transform: translate(0, -50%); transform: translate(0, -50%); } .form__type-text:before { width: 10px; height: 10px; position: absolute; top: 50%; left: 0; border: 1px solid #999; border-radius: 50%; content: ''; -webkit-transform: translate(0, -50%); -moz-transform: translate(0, -50%); -ms-transform: translate(0, -50%); transform: translate(0, -50%); } .form__detail-label:before { width: 10px; height: 10px; position: absolute; border: 1px solid #999; border-radius: 2px; content: ''; } input[type='checkbox']:checked+.form__detail-label:after { width: 4px; height: 10px; position: absolute; top: 20%; left: 15%; z-index: 1; border: 2px solid #FF93A0; border-width: 0 2px 2px 0; content: ''; -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); transform: rotate(45deg); }
HTML
<div class="form-box"> <ul class="form__type-list"> <li class="form__type-item"> <input type="radio" name="TODO" id="TODO1-1"> <label for="TODO1-1" class="form__type-label"> <span class="form__type-text">テキスト</span> </label> </li> <li class="form__type-item"> <input type="radio" name="TODO" id="TODO1-2"> <label for="TODO1-2" class="form__type-label"> <span class="form__type-text">テキスト</span> </label> </li> <li class="form__type-item"> <input type="radio" name="TODO" id="TODO1-3" disabled> <label for="TODO1-3" class="form__type-label"> <span class="form__type-text">テキスト</span> </label> </li> </ul> </div>
ラジオボタン、チェックボックス02
CSS
/* radio-box,checkbox-box */ .form__check-radio { height: 40px; position: relative; width: calc(100% / 3 - 10px); display: inline-block; } .form__check-radio input[type='radio'], .form__check-radio input[type='checkbox'] { display: inline-block; width: 100%; height: inherit; position: relative; margin: 0; padding: 0; z-index: 1; opacity: 0; box-sizing: border-box; } .form__check-radio input[type='radio']+label, .form__check-radio input[type='checkbox']+label { display: inline-block; padding: 10px; position: absolute; width: 100%; top: 0; left: 0; z-index: 0; color: #444; background-color: #fff; border-color: #ccc; border: 1px solid #ccc; border-radius: 5px; line-height: 1; box-sizing: border-box; } .form__check-radio__text { display: inline-block; padding-left: 22px; line-height: 1.4; vertical-align: top; font-size: 13px; } .form__check-radio input[type='radio']+label::after, .form__check-radio input[type='checkbox']+label::after { display: block; width: 10px; height: 5px; position: absolute; top: 22%; left: 9px; border-bottom: 3px solid #ccc; border-left: 3px solid #ccc; content: ''; transform: rotate(-45deg); transform-origin: right } .form__check-radio input[type='radio']:checked+label, .form__check-radio input[type='checkbox']:checked+label { color: #FF93A0; background-color: #FFF4F4; border-color: #FF93A0; } .form__check-radio input[type='radio']:checked+label::after, .form__check-radio input[type='checkbox']:checked+label::after { border-bottom: 3px solid #FF93A0; border-left: 3px solid #FF93A0; }
HTML
<div class="form__check-radio"> <input type="radio" name="radiobox1"> <label> <span class="form__check-radio__text">ラジオ</span> </label> </div> <div class="form__check-radio"> <input type="radio" name="radiobox1"> <label> <span class="form__check-radio__text">ラジオ</span> </label> </div> <div class="form__check-radio"> <input type="radio" name="radiobox1"> <label> <span class="form__check-radio__text">ラジオ</span> </label> </div> <div class="form__check-radio"> <input type="checkbox" name="checkbox1"> <label> <span class="form__check-radio__text">チェック</span> </label> </div> <div class="form__check-radio"> <input type="checkbox" name="checkbox1"> <label> <span class="form__check-radio__text">チェック</span> </label> </div> <div class="form__check-radio"> <input type="checkbox" name="checkbox1"> <label> <span class="form__check-radio__text">チェック</span> </label> </div>
レスポンジブサイトを実装する際にもaタグの切り替えに使えそうですね!!
SPではブロックリンクを実装、PCでは各要素をリンクに切り替えたいとかけっこうあります。
Jsを使用せずにcssのみでクリックを制御できるのはありがたーーい!
IE10以下が非対応ですが、矢印以外のエリアではプルダウンが機能しているので致命的ではないので今回はこのまま実装できそうです!!