<html>
<head>
</head>
<body>
<input type="text" value="1" style="min-width:1px;" />
</body>
</html>
这是我的代码,但无效。在HTML,JavaScript,PHP或CSS中还有其他方法来设置最小宽度吗?
我想要一个动态变化宽度的文本输入字段,以便输入字段围绕其内容流动。每个输入都有2em
的内置填充,这就是问题所在,第二个问题是min-width
根本不处理输入。
如果我设置的宽度超过了整个程序所需的宽度,我需要1px的宽度,只有在需要时才需要更多。
答案 0 :(得分:78)
听起来您的期望是根据文本框的内容动态地将样式应用于文本框的宽度。如果是这样,您将需要一些js来运行文本框内容更改,例如this:
<input id="txt" type="text" onkeypress="this.style.width = ((this.value.length + 1) * 8) + 'px';">
注意:此解决方案仅适用于每个字符都8px
宽的情况。
答案 1 :(得分:59)
要计算当前输入的宽度,您必须将其嵌入到临时span
元素中,将该内容附加到DOM,使用{{1}获取计算的宽度(以像素为单位) }属性并再次删除scrollWidth
。当然,您必须确保span
以及input
元素中使用相同的字体系列,字体大小等。因此我为他们分配了同一个班级。
我将函数附加到span
事件,就像在keyup
上一样,输入字符尚未添加到输入keypress
,因此会导致错误的宽度。不幸的是,我不知道如何摆脱输入字段的滚动(当在字段的末尾添加字符时);它会滚动,因为在调用value
之前添加并显示了该字符。并且,如上所述,我不能反过来这样做,因为在插入按下的字符之前,你将拥有输入字段的值。我稍后会尝试解决这个问题。
adjustWidthOfInput()
答案 2 :(得分:53)
在现代浏览器版本中,CSS单元ch
也可用。据我所知,它是与字体无关的单位,其中1ch
等于任何给定字体中字符0
(零)的宽度。
因此,像下面这样简单的东西可以用作调整大小函数:
var input = document.querySelector('input'); // get the input element
input.addEventListener('input', resizeInput); // bind the "resizeInput" callback on "input" event
resizeInput.call(input); // immediately call the function
function resizeInput() {
this.style.width = this.value.length + "ch";
}
input{ font-size:1.3em; padding:.5em; }
<input>
该示例会将“elem”调整为值+ + 2个字符的长度。
答案 3 :(得分:25)
这是对Lyth答案的修改,考虑到:
它还允许任意数量的输入字段!要查看它的实际效果:http://jsfiddle.net/4Qsa8/
<强>脚本:强>
$(document).ready(function () {
var $inputs = $('.resizing-input');
// Resize based on text if text.length > 0
// Otherwise resize based on the placeholder
function resizeForText(text) {
var $this = $(this);
if (!text.trim()) {
text = $this.attr('placeholder').trim();
}
var $span = $this.parent().find('span');
$span.text(text);
var $inputSize = $span.width();
$this.css("width", $inputSize);
}
$inputs.find('input').keypress(function (e) {
if (e.which && e.charCode) {
var c = String.fromCharCode(e.keyCode | e.charCode);
var $this = $(this);
resizeForText.call($this, $this.val() + c);
}
});
// Backspace event only fires for keyup
$inputs.find('input').keyup(function (e) {
if (e.keyCode === 8 || e.keyCode === 46) {
resizeForText.call($(this), $(this).val());
}
});
$inputs.find('input').each(function () {
var $this = $(this);
resizeForText.call($this, $this.val())
});
});
风格:
.resizing-input input, .resizing-input span {
font-size: 12px;
font-family: Sans-serif;
white-space: pre;
padding: 5px;
}
<强> HTML:强>
<div class="resizing-input">
<input type="text" placeholder="placeholder"/>
<span style="display:none"></span>
</div>
$(document).ready(function() {
var $inputs = $('.resizing-input');
// Resize based on text if text.length > 0
// Otherwise resize based on the placeholder
function resizeForText(text) {
var $this = $(this);
if (!text.trim()) {
text = $this.attr('placeholder').trim();
}
var $span = $this.parent().find('span');
$span.text(text);
var $inputSize = $span.width();
$this.css("width", $inputSize);
}
$inputs.find('input').keypress(function(e) {
if (e.which && e.charCode) {
var c = String.fromCharCode(e.keyCode | e.charCode);
var $this = $(this);
resizeForText.call($this, $this.val() + c);
}
});
// Backspace event only fires for keyup
$inputs.find('input').keyup(function(e) {
if (e.keyCode === 8 || e.keyCode === 46) {
resizeForText.call($(this), $(this).val());
}
});
$inputs.find('input').each(function() {
var $this = $(this);
resizeForText.call($this, $this.val())
});
});
.resizing-input input,
.resizing-input span {
font-size: 12px;
font-family: Sans-serif;
white-space: pre;
padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="resizing-input">
First:
<input type="text" placeholder="placeholder" />
<span style="display:none"></span>
</div>
<br>
答案 4 :(得分:15)
FOR A NICER LOOK&amp; FEEL
您应该将jQuery keypress()事件与String.fromCharCode(e.which)结合使用以获取按下的字符。因此,您可以计算您的宽度将。为什么?因为它看起来会更性感:)
与使用keyup事件的解决方案相比,这是一个很好的行为:http://jsfiddle.net/G4FKW/3/
下面是一个vanilla JS,它监听input
元素的<input>
事件,并将span
兄弟设置为具有相同的文本值以便测量它。
document.querySelector('input').addEventListener('input', onInput)
function onInput(){
var spanElm = this.nextElementSibling;
spanElm.textContent = this.value; // the hidden span takes the value of the input;
this.style.width = spanElm.offsetWidth + 'px'; // apply width of the span to the input
};
/* it's important the input and its span have same styling */
input, .measure {
padding: 5px;
font-size: 2.3rem;
font-family: Sans-serif;
white-space: pre; /* white-spaces will work effectively */
}
.measure{
position: absolute;
left: -9999px;
top: -9999px;
}
<input type="text" />
<span class='measure'></span>
答案 5 :(得分:13)
这是一个解决方案不需要等宽字体,只有非常小的javascript片段代码,不需要计算计算样式,以及,甚至支持ime ,支持rtl文本。
// copy the text from input to the span
$(function () {
$('.input').on('input', function () { $('.text').text($('.input').val()); });
});
* {
box-sizing: border-box;
}
.container {
display: inline-block;
position: relative;
}
.input,
.text {
margin: 0;
padding: 2px 10px;
font-size: 24px;
line-height: 32px;
border: 1px solid #ccc;
box-radius: 3px;
height: 36px;
font: 20px/20px sans-serif;
/* font: they should use same font; */
}
.text {
padding-right: 20px;
display: inline-block;
visibility: hidden;
white-space: pre;
}
.input {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
}
<script src="https://code.jquery.com/jquery-3.2.0.min.js"></script>
<div class="container">
<span class="text">
some text
</span>
<input class="input" value="some text" />
</div>
使用span.text
来适应文本的宽度,并让输入与position: absolute
的大小相同。每次更改时将输入值复制到span
(您可以轻松地将此段代码更改为vanilla js)。因此输入将“适合”其内容的大小。
答案 6 :(得分:8)
您也可以使用 size 属性设置输入的宽度。输入的大小决定了它的字符宽度。
输入可以通过侦听关键事件来动态调整其大小。
例如
$("input[type='text']").bind('keyup', function () {
$(this).attr("size", $(this).val().length );
});
JsFiddle here
答案 7 :(得分:7)
您可以执行this
之类的操作// HTML
<input id="input" type="text" style="width:3px" />
// jQuery
$(function(){
$('#input').keyup(function(){
$('<span id="width">').append( $(this).val() ).appendTo('body');
$(this).width( $('#width').width() + 2 );
$('#width').remove();
});
});
答案 8 :(得分:7)
以下是另一种使用DIV和“满足”的解决方法。属性:
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来捕获提交事件,以便您可以解析&#39;值&#39; DIV的(.innerHTML
或.html()
)。
答案 9 :(得分:6)
这是一个特定于Angular的答案,但这对我有用,并且在简单性和易用性方面非常令人满意:
<input [style.width.ch]="value.length" [(ngModel)]="value" />
它会通过Jani's answer中的字符单元自动更新。
答案 10 :(得分:4)
这是一个简单的JS和我编写的jQuery插件,它将使用画布和字体大小/族来处理输入元素的大小,以确定渲染时的实际字符串长度。 (仅适用于&gt; IE9,chrome,safari,firefox,opera和大多数已实现canvas元素的主流浏览器。)
PlainJS:
function autoSize(input, o) {
o || (o = {});
o.on || (o.on = 'keyup');
var canvas = document.createElement('canvas');
canvas.setAttribute('style', 'position: absolute; left: -9999px');
document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
input.addEventListener(o.on, function () {
ctx.font = getComputedStyle(this,null).getPropertyValue('font');
this.style.width = ctx.measureText(this.value + ' ').width + 'px';
});
}
//Usage
autoSize(document.getElementById('my-input'));
jQuery插件:
$.fn.autoSize = function(o) {
o = $.extend({}, {
on: 'keyup'
}, o);
var $canvas = $('<canvas/>').css({position: 'absolute', left: -9999});
$('body').append($canvas);
var ctx = $canvas[0].getContext('2d');
return this.on(o.on, function(){
var $this = $(this);
ctx.font = $this.css('font');
$this.width(ctx.measureText($this.val()).width + 'px');
})
}
//Usage:
$('#my-input').autoSize();
注意:这不会处理文本转换,行间距和字母间距,也可能处理其他一些文本大小更改属性。处理文本转换属性集并调整文本值以匹配该属性。其他人可能相当直接。如果这开始获得一些牵引力,我会实施......
答案 11 :(得分:4)
您可以只设置size
属性。
如果您使用的是反应式框架之一,那么下面的内容就足够了:
<input size="{{ yourValue.length }}" [value]="yourValue" />
但是,如果您使用的是纯js,则应设置事件处理程序,例如:
<input oninput="this.setAttribute('size', this.value.length)" />
答案 12 :(得分:3)
只需添加其他答案。
我注意到现在在某些浏览器中输入字段有一个scrollWidth。这意味着:
this.style.width = this.scrollWidth + 'px';
应该很好地工作。在chrome,firefox和safari中测试过。
对于删除支持,您可以先添加'= 0'然后重新调整。
this.style.width = 0; this.style.width = this.scrollWidth + 'px';
答案 13 :(得分:2)
如果您使用Bootstrap,则可以轻松完成:
<div contenteditable="true" class="form-control" style="display: inline"></div>
在提交表单之前,您只需要获取div的内容并将其放在隐藏的输入中即可。
答案 14 :(得分:2)
值得注意的是,当字体是等宽字体时,可以进行漂亮的调整大小,因此我们可以使用input
单元完美地调整ch
元素的大小。
同样在这种方法中,我们可以通过更新input
事件上的 CSS变量(自定义属性)来更新字段的宽度,我们也应该处理DOMContentLoaded
事件
<强>标记强>
<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
:此变量将包含输入的长度,并在1ch
表达式中乘以calc()
。默认情况下,我们也可以设置最小宽度,例如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);
});
当然,即使您不使用等宽字体,这仍然有效,但在这种情况下,您需要通过将calc()
变量乘以另一个值来更改--size
公式(它严格依赖于与font-family
不同的font-size
和1ch
。
答案 15 :(得分:2)
非常简单:
oninput='this.style.width = (this.scrollWidth - N) + "px";'
其中N是实验确定的某个数字(示例中为2,我正在开发的数字为17)。
减去N可以防止在文本到达文本框结尾之前很久就积累了这个奇怪的空间。
比较。请注意即使只是第一个字符后大小也会如何变化。
<p>Subtracting N:</p>
<input type="text" placeholder="enter lots of text here" oninput='this.style.width = (this.scrollWidth-2) + "px";'>
<p>Not Subtracting N:</p>
<input type="text" placeholder="enter lots of text here" oninput='this.style.width = (this.scrollWidth) + "px";'>
答案 16 :(得分:2)
你可以使用内置的ng-style指令在angularjs中更简单。
在你的HTML中:
<input ng-style="inputStyle(testdata)" ng-model="testdata" />
在您的控制器中:
$scope.testdata = "whatever";
$scope.inputStyle = function(str) {
var charWidth = 7;
return {"width": (str.length +1) * charWidth + "px" };
};
在你的css中:
input { font-family:monospace; font-size:12px; }
调整charWidth以匹配字体的宽度。它似乎是7,字体大小为12px;
答案 17 :(得分:1)
我认为你误解了min-width CSS property。 min-width通常用于定义流体布局中的最小DOM宽度,如:
input {
width: 30%;
min-width: 200px;
}
这会将输入元素设置为最小宽度为200像素。在这种情况下,“px”代表“像素”。
现在,如果您尝试检查以确保输入字段在用户提交时至少包含一个字符,则需要使用JavaScript和PHP进行一些表单验证。如果这确实是你想要做的,我会编辑这个答案并尽力帮助你。
答案 18 :(得分:1)
我真的很喜欢Lyth's answer,但也非常想要它:
我调整了他的JSFiddle并提出了this。这个小提琴中没有的一个改进是使用像jQuery CSS Parser之类的东西来实际读取input.textbox-autosize规则中的初始宽度,并将其用作minWidth。对,我只是简单地使用了一个属性,这使得一个紧凑的演示,但并不理想。因为它需要每个输入的额外属性。您可能只想在JavaScript中将minWidth设置为100。
<强> HTML:强>
<div id='applicationHost'>
<div>Name: <input class='textbox-autosize' data-min-width='100' type="text" /></div>
<div>Email: <input class='textbox-autosize' data-min-width='100' type="email" /></div>
<div>Points: <input class='textbox-autosize' data-min-width='100' type="number" /></div>
</div>
<强> CSS:强>
#applicationHost {
font-family: courier;
white-space: pre;
}
input.textbox-autosize, span.invisible-autosize-helper {
padding:0;
font-size:12px;
font-family:Sans-serif;
white-space:pre;
}
input.textbox-autosize {
width: 100px; /* Initial width of textboxes */
}
/*
In order for the measurements to work out, your input and the invisible
span need to have the same styling.
*/
<强> JavaScript的:强>
$('#applicationHost').on('keyup', '.textbox-autosize', function(e) {
// Add an arbitary buffer of 15 pixels.
var whitespaceBuffer = 15;
var je = $(this);
var minWidth = parseInt(je.attr('data-min-width'));
var newVal = je.val();
var sizingSpanClass = 'invisible-autosize-helper';
var $span = je.siblings('span.' + sizingSpanClass).first();
// If this element hasn't been created yet, we'll create it now.
if ($span.length === 0) {
$span = $('<span/>', {
'class': sizingSpanClass,
'style': 'display: none;'
});
je.parent().append($span);
}
$span = je.siblings('span').first();
$span.text(newVal) ; // the hidden span takes
// the value of the input
$inputSize = $span.width();
$inputSize += whitespaceBuffer;
if($inputSize > minWidth)
je.css("width", $inputSize) ; // apply width of the span to the input
else
je.css("width", minWidth) ; // Ensure we're at the min width
});
答案 19 :(得分:0)
尽管这篇文章已经很老了,但我想添加一个更简单的解决方案,并且不知道为什么只提供如此庞大和/或复杂的解决方案。
这是获取所需内容的简单函数:
function resizeInput() {
const input = document.getElementById('myInput');
input.style.width = `${input.scrollWidth}px`;
};
答案 20 :(得分:0)
您希望随着文本的更改来更改大小属性。
# 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}
/>
答案 21 :(得分:0)
最好的解决方案是
答案 22 :(得分:0)
苗条版:
<input type="text" style="width: {tag.length}ch" bind:value={tag} />
答案 23 :(得分:0)
这是我的2美分。 创建一个空的不可见div。用输入内容填充它,并将宽度返回到输入字段。在每个框之间匹配文本样式。
$(".answers_number").keyup(function(){
$( "#number_box" ).html( $( this ).val() );
$( this ).animate({
width: $( "#number_box" ).width()+20
}, 300, function() {
});
});
#number_box {
position: absolute;
visibility: hidden;
height: auto;
width: auto;
white-space: nowrap;
padding:0 4px;
/*Your font styles to match input*/
font-family:Arial;
font-size: 30px;
}
.answers_number {
font-size: 30px;
font-family:Arial;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" class="answers_number" />
<div id="number_box">
</div>
答案 24 :(得分:0)
input
元素
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';
}
&#13;
input{
font-size:1.3em;
padding:5px;
margin-bottom: 1em;
}
input.type2{
font-size: 2.5em;
letter-spacing: 4px;
font-style: italic;
}
&#13;
<input class='autoSize' value="type something">
<br>
<input class='autoSize type2' value="here too">
&#13;
答案 25 :(得分:0)
此答案提供了检索浏览器中可用文本宽度的最准确方法之一,并且比接受的答案更准确。它使用canvas html5元素,与其他答案不同,它不会将元素添加到DOM中,从而避免因过度添加元素而导致的任何重排问题。
阅读有关文字宽度的Canvas元素here的更多信息。
注意:根据MDN,
getPropertyValue()
方法的简写版本(如字体)可能不可靠。我建议单独获取这些值以提高兼容性。我这里只用它来提速。
/**
* 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);
&#13;
#myInput {
font: normal normal 400 normal 18px / normal Roboto, sans-serif;
min-width: 40px;
}
&#13;
<input id="myInput" />
&#13;
答案 26 :(得分:0)
为什么不使用css?
function keyup(e) {
document.getElementById('ghost').innerText = e.target.value;
}
#wrapper {
position: relative;
min-width: 30px;
display: inline-block;
}
input {
position: absolute;
left:0;
right:0;
border:1px solid blue;
width: 100%;
}
#ghost {
color: transparent;
}
&#13;
<div id="wrapper">
<input onkeyup="keyup(event)">
<div id="ghost"></div>
</div>
&#13;
wrapper {
position: relative;
min-width: 30px;
border: 1px solid red;
display: inline-block;
}
input {
position: absolute;
left:0;
right:0;
width: 100%;
}
#ghost {
color: transparent;
}
&#13;
df.iloc[-1, 0]
这个代码是由@Iain Todd介绍的,我想我应该分享它
答案 27 :(得分:0)
更好的是onvalue
:
<input id="txt" type="text" onvalue="this.style.width = ((this.value.length + 1) * 8) + 'px';">
它还涉及粘贴,拖放等等。
答案 28 :(得分:0)
根据迈克尔的回答,我使用jQuery创建了我自己的版本。我认为这是大多数答案的清洁/缩短版本,似乎可以完成工作。
我通过使用跨度将输入文本写入然后获取宽度,与此处的大多数人做同样的事情。然后,我在调用操作keyup
和blur
时设置宽度。
这是一个有效的codepen。此编码器显示了如何将其与多个输入字段一起使用。
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);
};
上面的函数获取输入值,修剪额外的空格并将文本设置为跨度以获得宽度。如果没有文本,它将获取占位符并将其输入到跨度中。一旦它将文本输入到跨度中,它就会设置输入的宽度。宽度上的+ 5
是因为没有它,边缘浏览器中的输入会被切断。
$('.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);
});
如果可以改进,请告诉我,因为这是我能想到的最干净的解决方案。
答案 29 :(得分:0)
我只是花一些时间来弄清楚如何去做 实际上,我发现最简单的方法是在输入之前将输入值移动到span,保持输入1符号宽度。虽然我无法确定它是否符合您的初始需求 也许它有一些额外的代码,但在反应+通量应用中,它是非常自然的解决方案。