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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45396280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 14:49:09  来源:igfitidea点击:

Customizing Increment Arrows on Input of Type Number Using CSS

htmlcsstextfield

提问by MadPhysicist

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

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

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

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

It looks like this:

它看起来像这样:

enter image description here

在此处输入图片说明

I would like to turn it into something like this:

我想把它变成这样的:

enter image description here

在此处输入图片说明

The second view is emulated using two separate buttons.

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

How could I style the arrows as described?

我怎样才能按照描述设计箭头?

回答by tao

tl;dr:

tl;博士:

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):

私下被问及以下设置很多次后,我决定为它添加一个演示(Bootstrap 4 + jQuery + Font Awesome 输入组设置):

$('.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;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>

<div class="input-group inline-group">
  <div class="input-group-prepend">
    <button class="btn btn-outline-secondary btn-minus">
      <i class="fa fa-minus"></i>
    </button>
  </div>
  <input class="form-control quantity" min="0" name="quantity" value="1" type="number">
  <div class="input-group-append">
    <button class="btn btn-outline-secondary btn-plus">
      <i class="fa fa-plus"></i>
    </button>
  </div>
</div>



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]控件不能跨浏览器设置样式。实现您想要的跨浏览器/跨设备的最简单和最安全的方法是使用以下方法隐藏它们:

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".

...它允许您使用自定义按钮,这些按钮可以链接以执行微调器(箭头)将(.stepUp().stepDown())的功能,前提是您保留输入的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 #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>



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 <input>under a common parent and used that parent to find the <input>(choosing not to rely on their proximity or particular order in DOM). The above method will change anyinput[type=number]sibling to the buttons. If that's not convenient, one could use any other methods to find the input from the buttons:

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

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

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()"

还要注意上面的例子只在 内部搜索.parentNode,而不是在整个 中搜索document,这也是可能的:
即:onclick="document.getElementById('#some-id').stepUp()"

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

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 0property of the jQuerywrapper.

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



Noteon preventDefault(). Clicking a <button>inside a <form>willtrigger the form submission. Therefore, if used as above, inside forms, the onclickshould also contain preventDefault();. Example:

注意preventDefault()。单击 a<button>里面的 a<form>触发表单提交。因此,如果如上使用,在表单内部,onclick也应该包含preventDefault();. 例子:

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

However, if one would use <a>tags instead of <button>s, this is not necessary. Also, the prevention can be set globally for all form buttons with a small JavaScript snippet:

但是,如果使用<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();
  });
}

... or, using jQuery:

...或者,使用 jQuery:

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

回答by Ingo Winkler

I found a nice solution. Just rotate the arrow keys and set the opacity to 0. (they are now in the right place, invisible but clickable) Then set an :after and :before element over these invisible buttons. These elements can then be styled as desired.

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

HTML

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

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

回答by Aslam khan

You can easily convert first design with second one like this:

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

HTML

HTML

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

CSS

CSS

.quantity{
   display:flex;
   width:160px;
}

/* it will support chrome and firefox */
.quantity input[type=number]::-webkit-inner-spin-button,
.quantity input[type=number]::-webkit-outer-spin-button{
   -webkit-appearance:none;
}

.quantity input,.quantity button{
   width:50px;
   padding:.5em;
   font-size:1.2rem;
   text-align:center;
   font-weight:900;
   background:white;
   border:1px solid #aaa;
}

.quantity input{
   border-left:none;
   border-right:none;
}