web-dev-qa-db-ja.com

CSSを使用して型番号の入力時に増分矢印をカスタマイズする

次のコードを使用してレンダリングされるタイプ番号の入力があります。

<input class="quantity" id="id_form-0-quantity" min="0" name="form-0-quantity" value="1" type="number">

次のようになります。

enter image description here

私はそれをこのようなものに変えたいです:

enter image description here

2番目のビューは、2つの個別のボタンを使用してエミュレートされます。

説明どおりに矢印のスタイルを設定するにはどうすればよいですか?

23
MadPhysicist

ネイティブのinput[type=number]コントロールは、スタイル対応可能なクロスブラウザーではありません。クロスブラウザ/クロスデバイスを実現する最も簡単で安全な方法は、以下を使用して非表示にすることです:

input[type="number"] {
  -webkit-appearance: textfield;
     -moz-appearance: textfield;
          appearance: textfield;
}
input[type=number]::-webkit-inner-spin-button, 
input[type=number]::-webkit-outer-spin-button { 
  -webkit-appearance: none;
}

...これにより、入力のtype="number"を保持していれば、スピナー(矢印)が実行する機能(.stepUp()および.stepDown())を実行するためにリンクできるカスタムボタンを使用できます。 。

例えば:

input[type="number"] {
  -webkit-appearance: textfield;
  -moz-appearance: textfield;
  appearance: textfield;
}

input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
  -webkit-appearance: none;
}

.number-input {
  border: 2px solid #ddd;
  display: inline-flex;
}

.number-input,
.number-input * {
  box-sizing: border-box;
}

.number-input button {
  outline:none;
  -webkit-appearance: none;
  background-color: transparent;
  border: none;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  cursor: pointer;
  margin: 0;
  position: relative;
}

.number-input button:before,
.number-input button:after {
  display: inline-block;
  position: absolute;
  content: '';
  width: 1rem;
  height: 2px;
  background-color: #212121;
  transform: translate(-50%, -50%);
}
.number-input button.plus:after {
  transform: translate(-50%, -50%) rotate(90deg);
}

.number-input input[type=number] {
  font-family: sans-serif;
  max-width: 5rem;
  padding: .5rem;
  border: solid #ddd;
  border-width: 0 2px;
  font-size: 2rem;
  height: 3rem;
  font-weight: bold;
  text-align: center;
}
<div class="number-input">
  <button onclick="this.parentNode.querySelector('input[type=number]').stepDown()" ></button>
  <input class="quantity" min="0" name="quantity" value="1" type="number">
  <button onclick="this.parentNode.querySelector('input[type=number]').stepUp()" class="plus"></button>
</div>

注:入力の値を変更するには、それを見つける必要があります。上記の例では、柔軟性を提供するために、ボタンと<input>を共通の親の下にグループ化し、その親を使用して<input>を見つけました(DOMの近接または特定の順序に依存しないことを選択しました)。上記の方法はanyinput[type=number]をボタンに変更します。それが便利でない場合は、他の方法を使用してボタンから入力を見つけることができます。

  • by id.querySelector('#some-id')
<button onclick="this.parentNode.querySelector('#some-id').stepUp()"></button>
  • className.querySelector('.some-class')
<button onclick="this.parentNode.querySelector('.some-class').stepUp()"></button>

また、上記の例はdocument全体ではなく、.parentNode内のみを検索することに注意してください。これも可能です。
i.e:onclick="document.getElementById('#some-id').stepUp()"

  • proximitypreviousElementSibling | nextElementSibling
<button onclick="this.previousElementSibling.stepUp()"></button>
  • dOM構造内の特定の入力要素を決定および検索する他の方法。たとえば、jQueryなどのサードパーティライブラリを使用できます。
<button onclick="$(this).prev()[0].stepUp()"></button>

JQueryを使用する際の重要な注意点は、stepUp()およびstepDown()メソッドがjQueryラッパーではなくDOM要素に配置されることです。 DOM要素は、jQueryラッパーの0プロパティ内にあります。


on preventDefault()<button>内の<form>をクリックするとwillフォーム送信がトリガーされます。したがって、フォーム内で上記のように使用する場合、onclickにはpreventDefault();も含める必要があります。例:

<button onclick="$(this).prev()[0].stepUp();preventDefault()"></button>

ただし、<a>sではなく<button>タグを使用する場合、これは必要ありません。また、小さなJavaScriptスニペットを使用して、すべてのフォームボタンに対して防止をグローバルに設定できます。

var buttons = document.querySelectorAll('form button:not([type="submit"])');
for (i = 0; i < buttons.length; i++) {
  buttons[i].addEventListener('click', function(e) {
    e.preventDefault();
  });
}

...または、jQueryを使用:

$('form').on('click', 'button:not([type="submit"])', function(e){
  e.preventDefault();
})
57