使用CSS自定义类型编号输入的增量箭头

时间:2017-07-30 04:11:37

标签: html css html5 css3 textfield

我有一个使用以下代码呈现的类型编号的输入:

<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

使用两个单独的按钮模拟第二个视图。

我如何按照描述设置箭头样式?

5 个答案:

答案 0 :(得分:38)

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

...允许您使用自定义按钮,这些按钮可以链接以执行微调器(箭头)(.stepUp().stepDown())的功能,前提是您保持输入&#39 ; s type="number"

例如:

&#13;
&#13;
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;
}
&#13;
<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>
&#13;
&#13;
&#13;

注意:为了更改输入的值,需要找到它。为了提供灵活性,在上面的示例中,我将按钮和<input>分组在一个共同父项下,并使用该父项查找<input>(选择不依赖于它们在DOM中的接近度或特定顺序)。上述方法 会将所有 input[type=number] 兄弟更改为按钮 。如果这不方便,可以使用任何其他方法从按钮中找到输入:

  • 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>

另请注意,上述示例仅在.parentNode内搜索,而不是在整个document内搜索,这也是可能的:
即:onclick="document.getElementById('#some-id').stepUp()"

  • 邻近 previousElementSibling | nextElementSibling
<button onclick="this.previousElementSibling.stepUp()"></button>
  • 确定和查找DOM结构中特定输入元素的任何其他方法。例如,可以使用第三方库,例如jQuery:
<button onclick="$(this).prev()[0].stepUp()"></button>

使用jQuery时的一个重要注意事项是stepUp()stepDown()方法放在DOM元素上,而不是放在jQuery包装器上。 DOM元素位于0包装器的jQuery属性中。

preventDefault()上的

注意。点击<button> 中的<form>触发表单提交。因此,如果在上面的表格中使用,onclick也应包含preventDefault();。例如:

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

但是,如果使用<a>代码而不是<button> s,则无需这样做。此外,可以使用小型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();
})

答案 1 :(得分:3)

数字输入可以用我最近发现的以下脚本进行样式化:

Demo

此脚本是超轻量级(未压缩的1.49kb,压缩的0.71kb,压缩的0.35kb),可用且可靠的数量输入,替代了内置在浏览器中的数字输入中的可怕,奇怪的小输入按钮。它是使用ES6模块编写的,因此需要为旧版浏览器进行编译。

作者的存储库为here。 希望这会有所帮助;)

编辑: 另外,如果您希望使用向上/向下箭头按钮,而不是加/减按钮,则可以使用another jQuery-based solution

Number input with up/down arrows

<div class="quantity">
  <input type="number" min="1" max="9" step="1" value="1">
</div>
$(document).ready(function () {
  jQuery('<div class="quantity-nav"><button class="quantity-button quantity-up">&#xf106;</button><button class="quantity-button quantity-down">&#xf107</button></div>').insertAfter('.quantity input');
  jQuery('.quantity').each(function () {
    var spinner = jQuery(this),
        input = spinner.find('input[type="number"]'),
        btnUp = spinner.find('.quantity-up'),
        btnDown = spinner.find('.quantity-down'),
        min = input.attr('min'),
        max = input.attr('max');

    btnUp.click(function () {
      var oldValue = parseFloat(input.val());
      if (oldValue >= max) {
        var newVal = oldValue;
      } else {
        var newVal = oldValue + 1;
      }
      spinner.find("input").val(newVal);
      spinner.find("input").trigger("change");
    });

    btnDown.click(function () {
      var oldValue = parseFloat(input.val());
      if (oldValue <= min) {
        var newVal = oldValue;
      } else {
        var newVal = oldValue - 1;
      }
      spinner.find("input").val(newVal);
      spinner.find("input").trigger("change");
    });

  });
});
body {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  min-width: 100vw;
  background: #34495E;
  font-size: 1rem;
}

.quantity {
  position: relative;
}

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

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

.quantity input {
  width: 45px;
  height: 42px;
  line-height: 1.65;
  float: left;
  display: block;
  padding: 0;
  margin: 0;
  padding-left: 20px;
  border: none;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);
  font-size: 1rem;
  border-radius: 4px;
}

.quantity input:focus {
  outline: 0;
}

.quantity-nav {
  float: left;
  position: relative;
  height: 42px;
}

.quantity-button {
  position: relative;
  cursor: pointer;
  border: none;
  border-left: 1px solid rgba(0, 0, 0, 0.08);
  width: 21px;
  text-align: center;
  color: #333;
  font-size: 13px;
  font-family: "FontAwesome" !important;
  line-height: 1.5;
  padding: 0;
  background: #FAFAFA;
  -webkit-transform: translateX(-100%);
  transform: translateX(-100%);
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  user-select: none;
}

.quantity-button:active {
  background: #EAEAEA;
}

.quantity-button.quantity-up {
  position: absolute;
  height: 50%;
  top: 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
  font-family: "FontAwesome";
  border-radius: 0 4px 0 0;
  line-height: 1.6
}

.quantity-button.quantity-down {
  position: absolute;
  bottom: 0;
  height: 50%;
  font-family: "FontAwesome";
  border-radius: 0 0 4px 0;
}

答案 2 :(得分:2)

您可以像这样轻松地将第一个设计与第二个设计转换:

HTML

FoodOrderTotalFragment

CSS

<div class="quantity">
    <button class="btn minus1">-</button>
    <input class="quantity" id="id_form-0-quantity" min="0" name="form-0-quantity" value="1" type="number">
    <button class="btn add1">+</button>

答案 3 :(得分:1)

我找到了一个不错的解决方案。只需旋转箭头键并将不透明度设置为0。(它们现在位于正确的位置,不可见但可单击),然后在这些不可见按钮上设置一个:after和:before元素。然后可以根据需要设置这些元素的样式。

HTML

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

CSS

input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
    transform: rotate(90deg);
    height: 80px;
    opacity: 0;
}

.quantity-wrapper {
    position: relative;
}

.quantity-wrapper:after {
    content: "+";
    position: absolute;
    right: 5px;
    height: 100%;
    top: 8px;
    pointer-events: none;
}

.quantity-wrapper:before {
    content: "-";
    position: absolute;
    left: 5px;
    height: 100%;
    top: 8px;
}

答案 4 :(得分:1)

这是另一个版本,基于@tao 的回答,使用 font-awesome:

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:after {
  display: inline-block;
  position: absolute;
  font-family: "Font Awesome 5 Free"; 
  font-weight: 900;
  content: '\f077';
  transform: translate(-50%, -50%) rotate(180deg);;
}
.number-input button.plus:after {
  transform: translate(-50%, -50%) rotate(0deg);
}

.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;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" integrity="sha512-HK5fgLBL+xu6dm/Ii3z4xhlSUyZgTT9tuc/hSrtw6uzJOvgRr2a9jyxxT1ely+B+xFAmJKVSTbpM/CuL7qxO8w==" crossorigin="anonymous" />

<div class="number-input">
  <button onclick="this.parentNode.querySelector('input[type=number]').stepDown()" class="minus"></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>