JSFiddle - React, Tailwind, and code Playground
HTML
<textarea id="area" class="text-block">Some Text</textarea>
CSS
.text-block {
resize: none;
font-size:40px;
border: none;
line-height: 1;
-moz-appearance: textfield-multiline;
-webkit-appearance: textarea;
overflow: hidden;
display: inline-block;
/* the border here is only to show the dimensions of the
textarea.*/
border: 1px solid #EEE;
}
JavaScript
var textEl = document.getElementById('area');
var emRatio = .6;
function getNewlines(){
// get the value(text) of the textarea
var content = textEl.value;
//use regex to find all the newline characters
var newLines = content.match(/\n/g);
// use the count of newlines(+1 for the first line + 1 for a buffer)
// to set the height of the textarea.
textEl.style.height = ((newLines && newLines.length || 0)+2.5)+'em';
};
function longestLine(){
// get the value(text) of the textarea
var content = textEl.value;
// split on newline's. this creates an array, where each item in
// the array is the text of one line
var a = content.split('\n');
// use a sorting function to order the items in the array:
// longest string to shortest string
a.sort(function(a,b){return b.length - a.length});
// use the longest string * the emRatio to set the width
// Due to kerning, the letters aren't ever really 1em x 1em
// So I'm multiplying by an approximate ratio here (guess and check)
textEl.style.width = (a[0].length * emRatio + 2)+ 'em';
};
function resizeTextarea(){
//set height
getNewlines();
//set width
longestLine();
};
//bind handler
textEl.onkeyup = resizeTextarea;
// This one is optional, will help when the user holds a key down
textEl.onkeydown = resizeTextarea;
//set initial size
resizeTextarea();