向 <input type="number"> 添加文本后缀

新手上路,请多包涵

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

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

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

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

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

在此处输入图像描述

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

我试过用谷歌搜索这个,但我似乎找不到任何相关信息。有谁知道这是否可能,以及如何完成这样的事情?

原文由 R. De Caluwe 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.2k
2 个回答

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

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

 /* 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 or focus within
   for arrow buttons will appear to the right of number inputs */
div:hover::after,
div:focus-within::after {
  right: 1.5em;
}

/* handle Firefox (arrows always shown) */
@supports (-moz-appearance:none) {
  div::after {
    right: 1.5em;
  }
}

/* set the unit abbreviation for each unit class */
.ms::after {
  content: 'ms';
}
.db::after {
  content: 'db';
}
.percent::after {
  content: '%';
}
 <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>

如果您想支持根本不显示这些箭头的浏览器,请使用 @supportsmedia queries

原文由 andreas 发布,翻译遵循 CC BY-SA 4.0 许可协议

另一种有趣的方法是使用一些 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>

然而,这只是一个概念证明。您将需要对其进行更进一步的工作以使其可以投入生产,例如,使其成为可重用的插件。

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

原文由 Slava Fomin II 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题