<h1>Auto Resize Textarea to Fit Content</h1>

<h2>Textareas</h2>

<p><strong>Problem (doesn't resize vertically):</strong> <textarea class="textarea"></textarea></p>

<p><strong>Solution with span:</strong> <span class="textarea" role="textbox" contenteditable></span></p>

<p><strong>Solution with JS (only deals with line breaks): </strong> <textarea class="textarea resize-ta"></textarea></p>
.textarea {
  border: 1px solid #ccc;
  font-family: inherit;
  font-size: inherit;
  padding: 1px 6px;
}
.width-machine {
  /*   Sort of a magic number to add extra space for number spinner */
  padding: 0 1rem;
}

.textarea {
  display: block;
  width: 100%;
  overflow: hidden;
  resize: both;
  min-height: 40px;
  line-height: 20px;
}

.textarea[contenteditable]:empty::before {
  content: "Placeholder still possible";
  color: gray;
}

/* Just for demo */
* {
  box-sizing: border-box;
}
body {
  font-family: "Heebo", sans-serif;
  max-width: 500px;
  margin: 0 auto;
  padding: 1rem;
}

p strong {
  display: block;
}
h1 {
  border-bottom: 5px solid blue;
}
h2 {
  border-bottom: 2px solid navy;
}
// Dealing with Input width
let widthMachine = document.querySelector(".width-machine");

// Dealing with Textarea Height
function calcHeight(value) {
  let numberOfLineBreaks = (value.match(/\n/g) || []).length;
  // min-height + lines x line-height + padding + border
  let newHeight = 20 + numberOfLineBreaks * 20 + 12 + 2;
  return newHeight;
}

let textarea = document.querySelector(".resize-ta");
textarea.addEventListener("keyup", () => {
  textarea.style.height = calcHeight(textarea.value) + "px";
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.