Как сделать чтобы textarea не растягивался
Перейти к содержимому

Как сделать чтобы textarea не растягивался

  • автор:

Как сделать адаптивный по высоте/ширине инпут

Рано или поздно вы получите от дизайнера макет, где встретится он — с виду вроде бы обычный текстовый инпут, а на деле, меняющий свою ширину или высоту, в зависимости от содержимого. Хорошие новости — отчаиваться не будем, это возможно. Причем, возможно достаточно разнообразными способами, об одном из них сегодня и поговорим.

Проблема

Прежде чем кидаться решать проблему — ее нужно осознать. С чего бы начать? Все зависит от поставленной вам задачи. Например: если требуется, чтобы инпут расширялся в ширину — это одна проблема. Если нужно чтобы он рос в высоту — это проблема другая. А если нужно чтобы сразу во все стороны, тут можно начинать страдать, дело-то непростое.

Главная проблема состоит в том, что элементы ввода не умеют растягиваться по своему содержимому. Это очень досадно и конечно мир был бы лучше, если бы они умели, но увы. Более того, однострочное текстовое поле — input вообще бессмысленно растягивать в высоту, содержимое все равно не ляжет в несколько строк, так уж он устроен. Поэтому дальше начинаются любимые фронтендерами лайфхаки.

Варианты решения

Самый первый, приходящий в топ выдачи гугла — это просто взять и заменить инпут на div с атрибутом contenteditable — и вот оно, проблема решена! Вот вам адаптивный по высоте/ширине див и редактируемое содержимое. Но если для вас (как и для меня) это не вариант, то смотрим дальше.

Следующий вариант не назовешь слишком изящным, но работающий вот что важно. Основан на том, что где-то позади самого текстового поля мы прячем невидимый блок, куда дублируем содержимое текстового поля при любом изменении. Блок изменяет свои размеры по содержимому, мы вычисляем их с помощью ява-скрипта и присваиваем текстовому полю. Если вас не смущает дополнительный мусор на странице в виде такого вот костыля — смело можно брать на вооружение.

Ну и третий вариант, который мне больше всего пришелся по душе — это все-таки вычислять содержимое текстового инпута и адаптировать его ширину/высоту, чтобы все помещалось. Давайте на него посмотрим чуть более внимательно.

Выбираем правильный инпут

Прежде всего, понадобится заменить input на textarea. Поскольку инпуты бесполезно наращивать в высоту, лучше сразу возьмем многострочное поле и будем делать вид, что это однострочный инпут.

Добавляем немного стилей, чтобы замаскировать истинную сущность нашего текстового поля.

.textarea

Тут следует обратить внимание на три обязательных параметра, без которых ничего не сработает: box-sizing, height, min-height.

box-sizing: border-box

В обязательном порядке box-sizing должен быть в значении border-box, чтобы когда вы добавите паддинг в текстовом поле, а вы его обязательно добавите, он не увеличивал дополнительно высоту или ширину текстового поля, а откладывался бы вовнутрь.

height и min-height (width и min-width)

Тут все просто: height — чтобы изначально textarea выглядела бы как input. min-height — чтобы при сбросе значения высоты текстовое поле не прыгало, а оставалось минимально необходимого размера. Все это справедливо и для свойств width и min-width.

Немного теории

Принцип действия очень простой. У каждого DOM-элемента, который может содержать контент, есть readonly-свойство scrollHeight (scrollWidth) которое и содержит так нужную нам, истинную высоту элемента, такую, при которой все содержимое этого элемента будет видно пользователю. Все, что нам требуется — при изменении текстового поля, вычислять значение scrollHeight/scrollWidth и присваивать его текстовому полю.

А для того, чтобы текстовое поле могло еще и возвращаться к своему исходному виду, перед изменением, будем сбрасывать установленную ранее высоту до нуля, для того чтобы свойство scrollHeight корректно бы показало нам, есть ли контент, не умещающийся в текстовом поле.

Немного vanilla JS-практики

Специально не использовала никаких фреймворков, для большей гибкости. Любым удобным способом получаем текстовое поле со страницы и добавляем обработчик события input

const textareaHeight = document.getElementById("text"); textareaHeight.addEventListener("input", (event) => < textareaHeight.style.height = 0; textareaHeight.style.height = textareaHeight.scrollHeight + "px"; >)

Это ввод с клавиатуры. Не стоит забывать, что текстовые поля бывают заполняются автоматически, извне. Для этого добавляем отдельный метод вставки значения:

function setValue(text: string)

Ну и давайте для ширины тоже сделаем. Все то же самое, только тут уже берем input, и высоту меняем на ширину.

const textInput = document.getElementById(«text»); textInput.addEventListener(«input», (event) => < textInput.style.width = 0; textInput.style.width = textInput.scrollWidth + "px"; >) function setValue(text: string)

Результат

Вот такие поля получились. Несложно и недолго.

Адаптивный инпут, растущий в высоту:

Адаптивный инпут, растущий в ширину:

Angular Директива

Для тех, кто дочитал аж до сюда — бонус. Если лень самостоятельно упаковать все это в директиву, я уже все сделала за вас, смотрите:

@Directive(< selector: "[adaptiveInputDirective]" >) export class AdaptiveInputDirective implements OnInit < @Input() horizontal: boolean; constructor(private element: ElementRef) <>ngOnInit() < if (this.horizontal) < this.element.nativeElement.style.whiteSpace = "nowrap"; >> @HostListener("ngModelChange", ["$event"]) onChange(): void < const input = this.element.nativeElement; if (this.horizontal) < input.style.width = 0; input.style.width = input.scrollWidth + "px"; >else < input.style.height = 0; input.style.height = input.scrollHeight + "px"; >> >

Здесь используется уже знакомый вам декоратор @HostListener. А если еще не знакомый, то обязательно почитайте статью об этом.

Пример использования:

Да, можно обойтись одним элементом — textarea. Просто, если нужна адаптивность в ширину — добавим CSS-свойство white-space: nowrap — запрет на перенос строк.

В остальном, все, о чем говорили, плюс — настраиваемый параметр horizontal указывающий что тянуть, ширину или высоту. Выбирайте нужный вариант и ни в чем не отказывайте своему дизайнеру.

Приходилось вам сталкиваться с подобной задачей? Как решали?

Как запретить растягивание textarea

Тэг TextArea — незаменимое поле ввода для текста. Современные браузеры по-умолчанию позволяют пользователям изменять размеры, растягивать его за правый нижний угол. Сделано это с добрыми намерениями, но для верстальщика оборачивается не самыми приятными последствиями.

Вот пример формы, где разрешено изменение

Видим, что пользователь может изменить размеры, нарушив задуманную геометрию верстки.

Запретить изменение размера TEXTAREA

Первая мысль — это полный запрет изменения размера. Достаточно добавить стиль:

Делаем textarea с автоматической высотой — краткий гайд

Как сделать поле для воода текста textarea, которое будет растягиваться по ширине контента. Используем CSS + HTML и совсем чуть-чуть JS.

Способом поделился пользователь Твиттера «Кричащий банан».

Предупреждая возражения, да, он не идеален, а в реплаях даже указали короткий код со Stack Overflow.

Однако способ из Твиттера весьма и весьма прикольный, отличается хитростью на грани с костыльностью и не требует вычислений.

Вот, что у вас получится:

Приступим. Сперва создайте обыкновенный блок div, а под ним расположите textarea.

В блок вставьте рандомный текст. Кричащий банан использовал Lorem Ipsum — классика.

Оба блока должны генерировать один и тот же текст. В местах, где строка должна переноситься на новый абзац в поле ввода, добавьте тэг br внутри блока div.

Для этой же разбивки в коде указываем text.split(/\r?\n/g) . Создаём компонент для разбивки, оборачиваем строки во фрагменты и не забываем указать тэг br.

Нейросети для рисования, если очень хочется красиво

Задаём блоку div и textarea одинаковые className и описываем свойства. Все свойства должны совпадать, кроме высоты.

В div добавляем свойство break-word, а textarea перемещаем поверх блока. Добавляем к окошку текста позиционирование absolute, а высоту выстраиваем в 100%. Таким образом, высота textarea будет равна высоте div, а границы textarea будут растягиваться по высоте контента.

Если вы хотите узнать ещё больше про фишки на HTML + CSS, научитесь делать простейшие анимации:

Как для поля textarea HTML запретить изменение размера?

Как для поля textarea HTML запретить изменение размера?

Иногда, при верстке сайта, в частности, при работе с контактными формами возникает необходимость в HTML запретить изменение размера textarea. Вызвать такую необходимость могут разные причины. Например, вы хотите убрать уголок-индикатор, позволяющий растянуть текстовое поле из правого нижнего угла:

Как изменить размер текстового поля

Или же вы хотите ограничить возможности пользователя по изменению размера поля textarea по горизонтали или по вертикали, для того, что бы сохранить верстку от нежелательных искажений:

Текстовое поле выходит за пределы формы

Для поля textarea HTML запретить изменение размера можно несколькими способами.

Как в HTML полностью запретить изменение размера textarea?

Если вы хотите полностью заблокировать изменение размера текстового поля textarea, а так же убрать уголок-индикатор, то наиболее эффективным будет использование свойства resize со значением none.

. wpcf7 . wpcf7 — textarea < resize : none ;

Как видите, уголок-индикатор исчез, и для пользователя нет возможности растянуть поле.

Как для textarea HTML запретить изменение размера в одном направлении?

Но такой вариант не всегда удобен, так как по умолчанию для текстового поля может быть задана слишком маленькая высота, и пользователю будет неудобно вводить текст в это поле:

Текстовое поле маленького размера

В таком случае было бы намного разумнее для textarea HTML запретить изменение размера, в зависимости от верстки, только в одном направлении. Например, в моем случае, при растягивании поля по ширине, поле уходит за пределы формы, и это существенно портит внешний вид. Но если растянуть поле в низ, то с версткой ничего страшного не произойдет, просто форма станет немного больше по высоте, и в тоже время, для пользователя будет намного удобнее вводить текст:

Поле textarea растянутое по высоте

Чтобы добиться такого результата, нам нужно задать для свойства resize одно из этих значений:

  • vertical – разрешает изменение размера текстового поля по вертикали
  • horizontal— разрешает изменение размера по горизонтали

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *