It works so far on using the contenteditable
attribute on the
It's kinda hacky, but it works.
First, modify your CSS
.autogrow {
border: 1px solid rgb( 0, 0, 0 );
padding: 10px;
}
@keyframes line_insert {
from {
height: 0px;
}
to {
height: 20px;
}
}
.autogrow[contenteditable] > div {
animation-duration: 250ms;
animation-name: line_insert;
}
.autogrow[contenteditable] {
overflow: hidden;
line-height: 20px;
}
Then add this jQuery that detects Shift + Enter events and appends a div whenever they occur
$(".autogrow").keydown(function(e){
if (e.keyCode == 13 && e.shiftKey || e.keyCode == 13)
{
$(this).animate({height: $(this).height()+20},200);
$(this).append('<div><br></div>');
}
});
And that should work.
Check fiddle https://jsfiddle.net/wx38rz5L/582/
To avoid these issues, I personally use a solution not based on pure CSS animations / transitions which I found always have problems. For example, in your CSS implementation, there is a bounce back effect if using the Enter too fast (you can slow the animation down to see it better).
Moreover, new lines handling is different between browsers, some will add <div><br></div>
, some versions of IE add only <br>
, etc.
I've never been able to fix all these problems or found an implementation fixing all of these so I decided to not modify at all the behavior of the contenteditable
, let the browser do is magic which works and instead, react to what's happening.
We don't even have to worry about keys events like Shift + Enter or events like deletion, etc., all of these are natively handled by the navigator.
I choose instead to use 2 elements: one for the actual contenteditable
and one for the styling of my contenteditable
which will be the one having height animations / transitions based on the actual height of the contenteditable
.
To do that, I'm monitoring every events that can change the height of a contenteditable
and if the height of my styling element is not the same, I'm animating the styling element.
var kAnimationSpeed = 125;
var kPadding = 10;
$('div[contenteditable]').on('blur keyup paste input', function() {
var styleElement = $(this).prev();
var editorHeight = $(this).height();
var styleElementHeight = styleElement.height();
if (editorHeight !== styleElementHeight - kPadding * 2) {
styleElement.stop().animate({ height: editorHeight + kPadding * 2 }, kAnimationSpeed);
}
});
.autogrowWrapper {
position: relative;
}
.autogrow {
border: 1px solid rgb(0, 0, 0);
height: 40px; /* line-height + 2 * padding */
}
div[contenteditable] {
outline: none;
line-height : 20px;
position: absolute;
top: 10px; /* padding */
left: 10px; /* padding */
right: 10px; /* padding */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="autogrowWrapper">
<div class="autogrow"></div>
<div contenteditable="true"></div>
</div>