Search code examples
javascripthtmlcss

How to make the field-sizing property regain control after a resize


Width the new field-sizing CSS property, you can allow certain form related elements to grow/shrink in size as content is inputted. (Only supported on Chrome as of writing this: caniuse)

If you input some text into the textarea in the snippet below, you can see the feature working. However, if you use the resize feature of the textarea at all, you will notice the field-sizing feature completely stops working. It is as if the browser just removes the property from the element after it has been resized.

My question is: how can we allow the field-sizing property to continue to work after a resize has occurred?

I have tried programatically setting resize: none; and field-sizing: content; after the resizing but nothing seems to allow the field-sizing property to regain control.

textarea {
  field-sizing: content;
  min-width: 6rem;
  max-width: 16rem;
}
<textarea></textarea>


Solution

  • You can subscribe the start and end events of the textarea resize (there really aren't any), to remove width and height but keep the size, using min-width and min-height.
    Warning - this will only work on extensions.

    const textarea = document.querySelector('textarea');
    
    textarea.addEventListener('pointerdown', () => {
      const { width, height } = textarea.getBoundingClientRect();
      textarea.style.width = `${width}px`;
      textarea.style.height = `${height}px`;
      textarea.style.removeProperty('min-width');
      textarea.style.removeProperty('min-height');
    })
    
    textarea.addEventListener('pointerup', () => {
      const { width, height } = textarea.getBoundingClientRect();
      textarea.style.minWidth = `${width}px`;
      textarea.style.minHeight = `${height}px`;
      textarea.style.removeProperty('width');
      textarea.style.removeProperty('height');
    })
    textarea {
      box-sizing: border-box;
      field-sizing: content;
      min-width: 6rem;
      max-width: 16rem;
    }
    <textarea></textarea>