Авто-масштабирование элемента input по ширине значения

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для автоматической подстройки размера <input type="text"> под введённый текст можно применить следующий код:

JS
Скопировать код
document.getElementById('input').oninput = function() {
  this.style.width = ((this.value.length + 1) * 8) + 'px';
};

Скрипт работает с элементом <input id="input">, корректируя ширину поле ввода пропорционально количеству введённых символов. Предполагаемая ширина одного символа умножается на число '8', которое может быть скорректировано в соответствии с размером используемого шрифта.

Кинга Идем в IT: пошаговый план для смены профессии

Метод с применением JavaScript

JS
Скопировать код
const input = document.querySelector('#input');
input.oninput = function() {
  const textWidth = getTextWidth(this.value, window.getComputedStyle(this).font);
  this.style.width = (textWidth + 4) + 'px';
};

Визуализация

Изобразим данный процесс как просторную площадку (🏞️), способную принимать форму в соответствии с размерами объекта, который на неё помещают:

Markdown
Скопировать код
Раньше: [🏞️......] (Первоначальный размер поля ввода)
Теперь:  [🏞️🎵🎶🎵🎶] (Адаптация размера под введённое содержимое)
HTML
Скопировать код
<input type="text" oninput="this.style.width = ((this.value.length + 1) * 8) + 'px';">

Подобно изменчивому пейзажу, поле ввода реагирует на размер содержимого и адаптируется под него. 🚀

Учет шрифта, отступов и границ

Учет стилей

При расчётах не забудьте учесть отступы и границы элемента:

JS
Скопировать код
input.oninput = function() {
  const style = window.getComputedStyle(this);
  const padding = parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
  const border = parseFloat(style.borderLeftWidth) + parseFloat(style.borderRightWidth);
  this.style.width = (getTextWidth(this.value, style.font) + padding + border + 4) + 'px';
};

Регулировка размера шрифта

При ограниченном пространстве на странице можно отрегулировать размер шрифта, чтобы он максимально эффективно занял имеющееся место:

JS
Скопировать код
const minWidth = 100;
const maxWidth = 600;

input.oninput = function() {
   this.style.width = Math.max(minWidth, Math.min(maxWidth, (getTextWidth(this.value, style.font) + padding + border + 4))) + 'px';
   this.style.fontSize = (this.offsetWidth >= maxWidth ? '75%' : '100%');
};

Особенности CSS и сокрытие Div'ов

Применение ширины в процентах вместе с CSS

Адепты CSS могут использовать следующий код:

CSS
Скопировать код
.input-wrapper {
  width: 100%;
}
.input-wrapper input {
  width: 100%;
}

Оберните <input> в div с шириной заданной в процентах. Элемент будет расширяться или сужаться в соответствии с размерами div.

Трюк с невидимым Div

Копирование стилей input в невидимый div можно выполнить вот так:

JS
Скопировать код
input.oninput = function() {
  const ghostDiv = document.getElementById('ghost');
  ghostDiv.innerHTML = this.value.replace(/ /g, "&nbsp;");
  
  const newWidth = ghostDiv.offsetWidth + 4;
  this.style.width = newWidth + 'px';
};
HTML
Скопировать код
<div id="ghost" style="display: none; white-space: pre;"></div>

Общее использование плагинов и атрибута Contenteditable

Применение jQuery плагина для автоматического изменения размера

Плагины jQuery, например Autosize, могут оказаться полезными, особенно если вы уже используете jQuery.

Мудрое применение Contenteditable

Как альтернативу можно задействовать contenteditable span:

HTML
Скопировать код
<span contenteditable="true" oninput="resizeSpan(this)"></span>

Однако не забывайте фильтровать введённые данные, чтобы предотвратить XSS-атаки на ваше приложение.

Тонкая настройка и балансировка

Учёт пробелов на конце

Если вы будете учитывать пробелы на конце строки, можно избежать визуальных несоответствий:

JS
Скопировать код
ghostDiv.innerHTML = this.value.replace(/ /g, "&nbsp;") + "&nbsp;";

Стилизация Placeholder'а

Выберите стиль placeholder'а таким образом, чтобы он гармонировал с активным текстом и обеспечивал естественную работу с интерфейсом:

CSS
Скопировать код
input::placeholder {
  color: #ccc;
  opacity: 1; /* Уже лучше выглядит в Firefox */
}

Стилизация фокуса и браузерные особенности

Используйте :focus-visible для обеспечения лучшего UX в процессе ввода.

И будьте готовы к особенностям разных браузеров — они могут представить неожиданные различия в рендеринге и расчётах отступов!

Полезные материалы

  1. MDN Web Docs: <input type="text"> — Подробное описание HTML-элемента для текстового ввода.
  2. Stack Overflow: Есть ли jQuery плагин для автоматического расширения текстовых полей? — Обсуждение и примеры автоматического изменения размера текстовых полей.
  3. JSFiddle: Песочница для кода — Платформа для тестирования и представления кода на HTML, CSS и JavaScript, включая демонстрацию работы текстовых полей с автокоррекцией размера.
  4. Autosize — Плагин jQuery для автоматического расширения текстового поля.
  5. Обучающий курс на DigitalOcean — Пошаговое руководство по реализации автоматического расширения текстовых полей в фреймворке Angular.