<input type="text" value="1" style=" font - family:宋体;/>

这是我的代码,它不工作。在HTML, JavaScript, PHP或CSS中是否有其他方法来设置最小宽度?

我想要一个具有动态变化宽度的文本输入字段,以便输入字段围绕其内容流动。每个输入都有一个2em的内置填充,这就是问题所在,第二个问题是最小宽度在输入上根本不起作用。

如果我设置的宽度超过了需要的宽度,那么整个程序就会很混乱,我需要1px的宽度,只在需要的时候才需要。


当前回答

下面是使用DIV和' contentteditable '属性来解决这个问题的另一种方法:

HTML:

<div contenteditable = "true" class = "fluidInput" data-placeholder = ""></div>

CSS:(给DIV一些维度,使它更容易看到)

.fluidInput {

    display         : inline-block;
    vertical-align  : top;

    min-width       : 1em;
    height          : 1.5em;

    font-family     : Arial, Helvetica, sans-serif;
    font-size       : 0.8em;
    line-height     : 1.5em;

    padding         : 0px 2px 0px 2px;
    border          : 1px solid #aaa;
    cursor          : text;
}


.fluidInput * {

    display         : inline;

}


.fluidInput br  {

    display         : none;

}


.fluidInput:empty:before {

    content         : attr(data-placeholder);
    color           : #ccc;

}

注意:如果你计划在你计划提交的FORM元素中使用这个,你将需要使用Javascript / jQuery来捕获提交事件,这样你就可以解析DIV的“值”(分别是. innerhtml或.html())。

其他回答

这个答案提供了在浏览器中检索文本宽度的最准确的方法之一,比公认的答案更准确。它使用canvas html5元素,不像其他答案,不将元素添加到DOM,从而避免了过多添加元素到DOM引起的任何回流问题。

阅读更多关于Canvas元素与文本宽度的关系。

注意:根据MDN, getPropertyValue()方法的简写版本(如font)可能不可靠。我建议单独获取值以提高兼容性。我只是为了提高速度才用的。

/** * returns the width of child text of any DOM node as a float */ function getTextWidth(el) { // uses a cached canvas if available var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas")); var context = canvas.getContext("2d"); // get the full font style property var font = window.getComputedStyle(el, null).getPropertyValue('font'); var text = el.value; // set the font attr for the canvas text context.font = font; var textMeasurement = context.measureText(text); return textMeasurement.width; } var input = document.getElementById('myInput'); // listen for any input on the input field input.addEventListener('input', function(e) { var width = Math.floor(getTextWidth(e.target)); // add 10 px to pad the input. var widthInPx = (width + 10) + "px"; e.target.style.width = widthInPx; }, false); #myInput { font: normal normal 400 normal 18px / normal Roboto, sans-serif; min-width: 40px; } <input id="myInput" />

您希望随着文本的更改而更改size属性。

# react

const resizeInput = (e) => {
  e.target.setAttribute('size', e.target.value.length || 1);
}

<input 
  onChange={resizeInput}
  size={(propertyInput.current && propertyInput.current.value.length) || 1}
  ref={propertyInput} 
/>

  

值得注意的是,当字体是等宽的时候,可以进行漂亮的大小调整,所以我们可以使用ch单位完美地调整输入元素的大小。

同样,在这种方法中,我们可以通过在输入事件上更新CSS变量(自定义属性)来更新字段的宽度,我们还应该照顾已经在DOMContentLoaded事件上预先填充的输入

Codepen演示


标记

<input type="text" value="space mono font" class="selfadapt" />

CSS

:root { --size: 0; }

.selfadapt {
   padding: 5px;
   min-width: 10ch;
   font-family: "space mono";
   font-size: 1.5rem;
   width: calc(var(--size) * 1ch);
}

作为根变量,我们设置——size: 0:这个变量将包含输入的长度,它将在calc()表达式中乘以1ch。默认情况下,我们也可以设置最小宽度,例如10ch

Javascript部分读取插入值的长度并更新变量——size:

JS

let input = document.querySelector('.selfadapt');
let root  = document.documentElement.style;

/* on input event auto resize the field */
input.addEventListener('input', function() {
   root.setProperty('--size', this.value.length );
});

/* resize the field if it is pre-populated */
document.addEventListener("DOMContentLoaded", function() {
   root.setProperty('--size', input.value.length);
});

当然,即使你不使用等宽字体,这仍然有效,但在这种情况下,你将需要通过将——size变量乘以另一个不同于1ch的值(它严格依赖于font-family和font-size)来改变calc()公式。

基于Michael的回答,我使用jQuery创建了自己的版本。我认为这是大多数答案的一个更简洁的版本,它似乎可以完成工作。

我和这里的大多数人做的是一样的事情,使用span来写入输入文本,然后得到宽度。然后,当动作keyup和blur被调用时,我设置宽度。

这是一个工作的代码依赖。这个代码依赖显示了如何将其用于多个输入字段。

HTML结构:

<input type="text" class="plain-field" placeholder="Full Name">
<span style="display: none;"></span>

jQuery:

function resizeInputs($text) {
    var text = $text.val().replace(/\s+/g, ' '),
        placeholder = $text.attr('placeholder'),
        span = $text.next('span');
        span.text(placeholder);
    var width = span.width();

    if(text !== '') {
        span.text(text);
    var width = span.width();
    }

    $text.css('width', width + 5);
};

上面的函数获取输入值,修剪多余的空格,并将文本设置为span以获得宽度。如果没有文本,则获取占位符并将其输入到span中。一旦它将文本输入到span中,它就会设置输入的宽度。宽度上的+ 5是因为如果没有它,在Edge浏览器中输入会被切断一小部分。

$('.plain-field').each(function() {
    var $text = $(this);
    resizeInputs($text);
});

$('.plain-field').on('keyup blur', function() {
    var $text = $(this);
    resizeInputs($text);
});

$('.plain-field').on('blur', function() {
    var $text = $(this).val().replace(/\s+/g, ' ');
    $(this).val($text);
});

如果这可以改进,请让我知道,因为这是我能想出的最干净的解决方案。

一个无懈可击的通用方法是:

考虑所有可能的测量输入元素的样式 能够在任何输入上应用测量,而无需修改HTML或

Codepen演示

var getInputValueWidth = (function(){ // https://stackoverflow.com/a/49982135/104380 function copyNodeStyle(sourceNode, targetNode) { var computedStyle = window.getComputedStyle(sourceNode); Array.from(computedStyle).forEach(key => targetNode.style.setProperty(key, computedStyle.getPropertyValue(key), computedStyle.getPropertyPriority(key))) } function createInputMeassureElm( inputelm ){ // create a dummy input element for measurements var meassureElm = document.createElement('span'); // copy the read input's styles to the dummy input copyNodeStyle(inputelm, meassureElm); // set hard-coded styles needed for propper meassuring meassureElm.style.width = 'auto'; meassureElm.style.position = 'absolute'; meassureElm.style.left = '-9999px'; meassureElm.style.top = '-9999px'; meassureElm.style.whiteSpace = 'pre'; meassureElm.textContent = inputelm.value || ''; // add the meassure element to the body document.body.appendChild(meassureElm); return meassureElm; } return function(){ return createInputMeassureElm(this).offsetWidth; } })(); // delegated event binding document.body.addEventListener('input', onInputDelegate) function onInputDelegate(e){ if( e.target.classList.contains('autoSize') ) e.target.style.width = getInputValueWidth.call(e.target) + 'px'; } input{ font-size:1.3em; padding:5px; margin-bottom: 1em; } input.type2{ font-size: 2.5em; letter-spacing: 4px; font-style: italic; } <input class='autoSize' value="type something"> <br> <input class='autoSize type2' value="here too">