Summary:
The number of lines in a text area, times line height, is not the same as the height of the textarea element, why is that?
Detail
I'm working on a function to resize textarea
elements in an AngularJs directive, and the answer I found gave this as the meat of the solution in the link function:
angular.module('auto.resize', []).directive('autoResize', ['$timeout', function($timeout) {
return {
restrict: 'A',
link: function link(scope, elm) {
const resize = function() {
elm[0].style.height = elm[0].scrollHeight + "px";
}
elm.on("blur keyup change", resize);
$timeout(resize);
}
}
}]);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS </title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
</head>
<body>
<div>
<textarea auto-resize></textarea>
</div>
</body>
This doesn't work as I'd like when you add extra lines, then type on anything but the bottom line it slowly shrinks down by an amount smaller than the line height.
My fix is this:
angular.module('auto.resize', []).directive('autoResize', ['$timeout', function($timeout) {
return {
restrict: 'A',
link: function link(scope, elm) {
const resize = function() {
const lines = elm[0].value.split("\n").length;
const lineHeight = parseInt(getComputedStyle(elm[0]).lineHeight.match(/(\d+)/)[1];
elm[0].style.height = lines * lineHeight + "px";
}
elm.on("blur keyup change", resize);
$timeout(resize);
}
}
}]);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS </title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
</head>
<body>
<div>
<textarea auto-resize></textarea>
</div>
</body>
This corrects itself for not resizing unnecessarily, however, my issue is that lines * lineHeight
is not the same as scrollHeight
, there seems to be some padding, that I can't divine.
How do I map between the two?