添加文本后缀为<input type =“number”/>

时间:2018-04-12 12:45:35

标签: html css html5 input suffix

我目前有很多这样的输入:

<input type="number" id="milliseconds">

此输入字段用于表示以毫秒为单位的值。 但我确实有多个数字输入,它们取值为dB或百分比。

<input type="number" id="decibel">
<input type="number" id="percentages">

我想要做的是在输入字段中添加一个类型后缀,让用户知道输入所代表的值类型。像这样:

enter image description here

(编辑此图像以显示我想要的结果,我也从输入类型中隐藏了向上和向下箭头。)

我曾试图谷歌这个,但我似乎无法找到任何相关信息。有谁知道这是否可能,以及你如何能够完成这样的事情?

5 个答案:

答案 0 :(得分:10)

您可以为每个输入元素使用包装<div>,并将单位定位为伪元素::after,并使用相应单位的content

这种方法适用于绝对定位的伪元素不会影响现有布局。然而,这种方法的缺点是,你必须确保用户输入不像文本字段那么长,否则单元将在上面显示不愉快。对于固定的用户输入长度,它应该可以正常工作。

&#13;
&#13;
/* prepare wrapper element */
div {
  display: inline-block;
  position: relative;
}

/* position the unit to the right of the wrapper */
div::after {
  position: absolute;
  top: 2px;
  right: .5em;
  transition: all .05s ease-in-out;
}

/* move unit more to the left on hover
   for arrow buttons will appear to the right of number inputs */
div:hover::after {
  right: 1.5em;
}

/* set the unit abbreviation for each unit class */
.ms::after {
  content: 'ms';
}
.db::after {
  content: 'db';
}
.percent::after {
  content: '%';
}
&#13;
<div class="ms">
  <input type="number" id="milliseconds" />
</div>
<hr />
<div class="db">
  <input type="number" id="decibel" />
</div>
<hr />
<div class="percent">
  <input type="number" id="percentages">
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:3)

另一种有趣的方法是使用一些JavaScript,以使后缀实际上停留在输入文本上(可能看起来更好):

const inputElement = document.getElementById('my-input');
const suffixElement = document.getElementById('my-suffix');


inputElement.addEventListener('input', updateSuffix);

updateSuffix();

function updateSuffix() {
  const width = getTextWidth(inputElement.value, '12px arial');
  suffixElement.style.left = width + 'px';
}


/**
 * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.
 * 
 * @param {String} text The text to be rendered.
 * @param {String} font The css font descriptor that text is to be rendered with (e.g. "bold 14px verdana").
 * 
 * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393
 */
function getTextWidth(text, font) {
    // re-use canvas object for better performance
    var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
    var context = canvas.getContext("2d");
    context.font = font;
    var metrics = context.measureText(text);
    return metrics.width;
}
#my-input-container {
  display: inline-block;
  position: relative;
  font: 12px arial;
}

#my-input {
  font: inherit;
}

#my-suffix {
  position: absolute;
  left: 0;
  top: 3px;
  color: #555;
  padding-left: 5px;
  font: inherit;
}
<div id="my-input-container">
  <input type="number" id="my-input" value="1500">
  <span id="my-suffix">ms.</span>
</div>

但是,这仅仅是概念的证明。您将需要做一些进一步的工作才能使其投入生产,例如使其成为可重复使用的插件。

此外,您还需要处理输入元素溢出的情况。

答案 2 :(得分:2)

我有一个案例,设计团队希望后缀随值浮动。我们正在使用数字宽度非常不均匀的自定义字体。我想到了一个想法,即使用重影跟踪输入宽度并通过使用包装器元素用 max-width 限制溢出。这仍然是一些正在进行的工作并且有问题(没有初始填充等)。

const fillBuffer = (e) => {
  // Clear the buffer if input gets wiped
  if (e.target.value.length === 0) {
    e.target.parentElement.querySelector('.suffix span').textContent = "";
    return;
  }

  // Using a filler char will prevent the suffix to be overwritten with the input
  const extraFiller = e.target.value.length ? '1' : '';

  e.target.parentElement.querySelector('.suffix span').textContent = e.target.value + extraFiller;
}

// Attach the listeners
document.querySelectorAll('input').forEach((el) => {
  el.addEventListener('keydown', fillBuffer);
  el.addEventListener('keyup', fillBuffer);
});
* {
  font-size: 1em;
  font-family: Papyrus, sans-serif;
  box-sizing: border-box;
}

body {
  padding: 1em;
}

.input-wrapper {
  margin-bottom: 0.5em;
}

.input-wrapper.with-suffix {
  position: relative;
  max-width: 150px;
  overflow: hidden;
}

.input-wrapper.with-suffix input {
  margin: 0;
  width: 100%;
  outline: 0;
  padding-left: 4px;
  padding-right: 16px;
}

.input-wrapper.with-suffix .suffix {
  position: absolute;
  padding-left: 6px;
  top: 2px;
  pointer-events: none;
  width: 100%;
}

.input-wrapper.with-suffix .suffix span {
  user-select: none;
  pointer-events: none;
}

.input-wrapper.with-suffix .suffix .filler {
  display: inline-block;
  white-space: pre; /* Allow more than two whitespaces to be rendered */
  color: rgba(0, 0, 0, 0.0);
  background: rgba(255, 0, 0, 0.3);
  max-width: calc(100% - 16px);
}
<div class="input-wrapper with-suffix">
  <input type="text" value="5000">
  <div class="suffix"><span class="filler">5000</span><span>€</span></div>
</div>
  
  
<div class="input-wrapper with-suffix">
  <input type="text" value="5000">
  <div class="suffix"><span class="filler">5000</span><span>€</span></div>
</div>

答案 3 :(得分:0)

如果您有选择添加元素到输入,那么您可以尝试: -

<div class="container">
  <input type="text" id="milliseconds">
  <span class="ms">ms</span>
</div>

.container {
  max-width: 208px; /*adjust it*/ 
  margin: auto;
  position: relative;
  display: inline-block;
}

#milliseconds {
  padding-right: 35px;
}

.ms {
 position: absolute;
 top: 0;
 right: 10px;
}

答案 4 :(得分:-2)

如果可能的话,使用具有api设计的ANT Design,因此我们只需要编写addOnBefore和addOnAfter

https://ant.design/components/input/