Customizing Increment Arrows on Input of Type Number Using CSS

后端 未结 4 1960
误落风尘
误落风尘 2020-11-28 19:58

I have an input of type number that is rendered using the following code:

4条回答
  •  醉酒成梦
    2020-11-28 20:24

    tl;dr:

    Having been asked in private about the following setup quite a few times, I decided to add a demo for it (Bootstrap 4 + jQuery + Font Awesome input-group setup):

    $('.btn-plus, .btn-minus').on('click', function(e) {
      const isNegative = $(e.target).closest('.btn-minus').is('.btn-minus');
      const input = $(e.target).closest('.input-group').find('input');
      if (input.is('input')) {
        input[0][isNegative ? 'stepDown' : 'stepUp']()
      }
    })
    .inline-group {
      max-width: 9rem;
      padding: .5rem;
    }
    
    .inline-group .form-control {
      text-align: right;
    }
    
    .form-control[type="number"]::-webkit-inner-spin-button,
    .form-control[type="number"]::-webkit-outer-spin-button {
      -webkit-appearance: none;
      margin: 0;
    }
    
    
    
    
    
    
    


    long (initial) answer:

    The native input[type=number] controls are not style-able cross-browser. The easiest and safest way to achieve what you want cross-browser/cross-device is to hide them using:

    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;
    }
    

    ...which allows you to use your custom buttons, which could be linked to execute the functions the spinners (arrows) would (.stepUp() and .stepDown()), provided you keep the input's type="number".

    For example:

    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 #ffffd;
      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 #ffffd;
      border-width: 0 2px;
      font-size: 2rem;
      height: 3rem;
      font-weight: bold;
      text-align: center;
    }


    Note: In order to change the input's value, one needs to find it. To provide flexibility, in the example above I grouped buttons and the under a common parent and used that parent to find the (choosing not to rely on their proximity or particular order in DOM). The above method will change any input[type=number] sibling to the buttons. If that's not convenient, one could use any other methods to find the input from the buttons:

    • by id: .querySelector('#some-id'):
    
    
    • by className: .querySelector('.some-class'):
    
    

    Also note the above examples only search inside the .parentNode, not in the entire document, which is also possible:
    i.e: onclick="document.getElementById('#some-id').stepUp()"

    • by proximity (previousElementSibling | nextElementSibling)
    
    
    • any other way to determine and find a particular input element in a DOM structure. For example, one could use third party libraries, such as jQuery:
    
    

    An important note when using jQuery is that the stepUp() and stepDown() methods are placed on the DOM element, not on the jQuery wrapper. The DOM element is found inside the 0 property of the jQuery wrapper.


    Note on preventDefault(). Clicking a

    However, if one would use tags instead of

提交回复
热议问题