Настройте ширину поля ввода на вход
<html>
<head>
</head>
<body>
<input type="text" value="1" style="min-width:1px;" />
</body>
</html>
Это мой код, и он не работает. Есть ли другой способ в HTML, JavaScript, PHP или CSS установить минимальную ширину?
Я хочу текстовое поле ввода с динамически изменяющейся шириной, так что поле ввода будет текучим вокруг его содержимого. Каждый вход имеет встроенное дополнение 2em
, то есть проблема, а вторая проблема заключается в том, что min-width
вообще не работает с входом.
Если я устанавливаю ширину больше, чем нужно, чем вся программа, она беспорядочна, мне нужна ширина 1px, больше, только если это необходимо.
Ответы
Ответ 1
Похоже, вы ожидаете, что стиль будет динамически применяться к ширине текстового поля на основе содержимого текстового поля. Если это так, вам понадобится несколько js для изменения содержимого текстового поля, что-то вроде этого:
<input id="txt" type="text" onkeypress="this.style.width = ((this.value.length + 1) * 8) + 'px';">
Примечание. Это решение работает только тогда, когда каждый символ имеет ширину всего 8 8px
.
Ответ 2
Чтобы вычислить ширину текущего ввода, вам необходимо встроить его во временный элемент span
, прикрепить эту вещь к DOM, получить вычисленную ширину (в пикселях) с помощью свойства scrollWidth
и удалить span
снова. Конечно, вы должны убедиться, что в input
, а также в элементе span
используется тот же семейство шрифтов, размер шрифта и т.д. Поэтому я присвоил им тот же класс.
Я привязал функцию к событию keyup
, так как на keypress
входной символ еще не добавлен во вход value
, так что это приведет к неправильной ширине. К сожалению, я не знаю, как избавиться от прокрутки поля ввода (при добавлении символов в конец поля); он прокручивается, потому что символ добавляется и отображается до вызова adjustWidthOfInput()
. И, как сказано, я не могу сделать это наоборот, потому что тогда у вас будет значение поля ввода до того, как будет вставлен нажатый символ. Я попытаюсь решить эту проблему позже.
Кстати, я тестировал это только в Firefox (3.6.8), но надеюсь, что вы поймете.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Get/set width of <input></title>
<style>
body {
background: #666;
}
.input-element {
border: 0;
padding: 2px;
background: #fff;
font: 12pt sans-serif;
}
.tmp-element {
visibility: hidden;
white-space: pre;
}
</style>
</head>
<body>
<input id="theInput" type="text" class="input-element" value="1">
<script>
var inputEl = document.getElementById("theInput");
function getWidthOfInput() {
var tmp = document.createElement("span");
tmp.className = "input-element tmp-element";
tmp.innerHTML = inputEl.value.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
document.body.appendChild(tmp);
var theWidth = tmp.getBoundingClientRect().width;
document.body.removeChild(tmp);
return theWidth;
}
function adjustWidthOfInput() {
inputEl.style.width = getWidthOfInput() + "px";
}
adjustWidthOfInput();
inputEl.onkeyup = adjustWidthOfInput;
</script>
</body>
</html>
Ответ 3
В современных версиях браузера также доступен модуль 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>
Ответ 4
Здесь приведена модификация ответа Lyth, которая учитывает:
- Удаление
- Инициализация
- заполнители
Он также позволяет использовать любое количество полей ввода! Чтобы увидеть это в действии: http://jsfiddle.net/4Qsa8/
Script:
$(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>
Ответ 5
ДЛЯ ПОСМОТРЕТЬ И ЧУВСТВИТЕЛЬНОСТЬ
Вы должны использовать событие jQuery keypress() в сочетании с String.fromCharCode(e.which), чтобы получить нажатый символ. Следовательно, вы можете рассчитать, какая будет ваша ширина. Зачем? Потому что это будет выглядеть намного более сексуально :)
Вот jsfiddle, который приводит к хорошему поведению по сравнению с решениями, использующими событие keyup: http://jsfiddle.net/G4FKW/3/
Ниже приведен ванильный 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 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>
Ответ 6
Вот решение без моноширинного шрифта, с очень маленьким кусочком кода 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>
Ответ 7
Вы можете установить ширину ввода, используя атрибут size. Размер ввода определяет его ширину в символах.
Ввод может динамически регулировать размер, прослушивая ключевые события.
Например
$("input[type='text']").bind('keyup', function () {
$(this).attr("size", $(this).val().length );
});
JsFiddle здесь
Ответ 8
Вы можете сделать что-то вроде 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();
});
});
Ответ 9
Вот альтернативный способ решить эту проблему с использованием свойства DIV и "contenteditable":
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, чтобы поймать событие отправки, чтобы вы могли разобрать "значение" (.innerHTML
или .html()
соответственно) DIV.
Ответ 10
Вот простой JS и плагин jQuery, который я написал, который будет обрабатывать изменение размера элемента ввода, используя холст и размер/семейство шрифтов, чтобы определить фактическую длину строки при визуализации. (работает только в > IE9, хром, сафари, 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
Это Angular -специфический ответ, но это сработало для меня и было очень удовлетворительным с точки зрения его простоты и простоты использования:
<input [style.width.ch]="value.length" [(ngModel)]="value" />
Он автоматически обновляется через единицы символов в ответ Jani.
Ответ 12
Вы можете сделать это еще проще в angularjs, используя встроенную директиву ng-style.
В вашем 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;
Ответ 13
Стоит отметить, что красивое изменение размера может быть выполнено, когда шрифт моноширин, поэтому мы можем полностью изменить размер input
элемента с помощью блока ch
.
Также в этом подходе мы можем обновить ширину поля, просто обновив переменную CSS (настраиваемое свойство) на input
событии, и мы также должны позаботиться о уже предварительно заполненном вводе событии 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
: эта переменная будет содержать длину ввода и будет 1ch
на 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
.
Ответ 14
Я думаю, вы неправильно интерпретируете свойство минимальной ширины CSS. min-width обычно используется для определения минимальной ширины DOM в макете жидкости, например:
input {
width: 30%;
min-width: 200px;
}
Это установит минимальный размер входного элемента в 200 пикселей. В этом контексте "px" означает "пиксели".
Теперь, если вы пытаетесь проверить, чтобы поле ввода содержало по крайней мере один символ, когда пользователь отправляет его, вам нужно выполнить некоторую проверку формы с помощью JavaScript и PHP. Если это действительно то, что вы пытаетесь сделать, я отредактирую этот ответ и сделаю все возможное, чтобы помочь вам.
Ответ 15
Мне действительно понравился Lyth answer, но он также очень хотел:
- Обрабатывать backspace и удалять
- Не требуется вручную добавлять соседний тег.
- Обеспечьте минимальную ширину.
- Автоматически применяется к элементам с определенным классом
Я адаптировал его JSFiddle и придумал this. Одним из улучшений, не присутствующих в этой скрипке, было бы использовать что-то вроде jQuery CSS Parser, чтобы фактически прочитать начальную ширину из input.textbox-autosize и используйте это как minWidth. Правильно, я просто использую атрибут, который делает для компактной демонстрации, но не идеален. так как для каждого входа требуется дополнительный атрибут. Вы также можете просто поставить minWidth как 100 в JavaScript.
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
});
Ответ 16
Если вы используете Bootstrap, это можно сделать очень легко:
<div contenteditable="true" class="form-control" style="display: inline"></div>
Вам просто нужно получить содержимое div и поместить его в скрытый ввод, прежде чем отправлять форму.
Ответ 17
Просто добавьте другие ответы.
Я заметил, что в настоящее время в некоторых браузерах поле ввода имеет scrollWidth. Что значит:
this.style.width = this.scrollWidth + 'px';
должен работать хорошо. протестированы в хром, firefox и сафари.
Для поддержки удаления вы можете сначала добавить '= 0', а затем отрегулировать.
this.style.width = 0; this.style.width = this.scrollWidth + 'px';
Ответ 18
Я просто потрачу некоторое время на выяснение, как это сделать.
Фактически самый простой способ, который я нашел, - это перемещать входное значение до диапазона непосредственно перед входом, сохраняя ширину символа ввода 1. Хотя я не могу быть уверен, что он подходит для вашей первоначальной потребности.
Может быть, это какой-то дополнительный код, но в приложении "реакция + поток" это вполне естественное решение.
Ответ 19
Основываясь на ответе Майкла, я создал свою собственную версию этого с помощью 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
по ширине состоит в том, что без этого вход обрезается крошечным битом в Edge Browser.
$('.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);
});
Если это может быть улучшено, пожалуйста, дайте мне знать, как это самое чистое решение, которое я мог бы придумать.
Ответ 20
Лучше onvalue
:
<input id="txt" type="text" onvalue="this.style.width = ((this.value.length + 1) * 8) + 'px';">
Он также включает в себя вставку, перетаскивание и т.д.
Ответ 21
Почему бы не использовать только css?
<div id="wrapper">
<input onkeyup="keyup(event)">
<div id="ghost"></div>
</div>
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;
}
<div id="wrapper">
<input onkeyup="keyup(event)">
<div id="ghost"></div>
</div>
Ответ 22
Этот ответ предоставляет один из самых точных способов получения ширины текста, доступных в браузере, и является более точным, чем принятый ответ. Он использует элемент canvas html5 и в отличие от других ответов не добавляет элемент в DOM и, таким образом, позволяет избежать любых проблем с оплатой, вызванных чрезмерным добавлением элементов в DOM.
Подробнее о элементе Canvas читайте здесь относительно ширины текста.
ПРИМЕЧАНИЕ. Согласно 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);
#myInput {
font: normal normal 400 normal 18px / normal Roboto, sans-serif;
min-width: 40px;
}
<input id="myInput" />
Ответ 23
Пуленепробиваемый, общий способ:
- Учитывайте все возможные стили измеряемого
input
элемента - Уметь применять измерение на любом входе без изменения HTML или
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 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">