I like Chrome\'s nifty textarea resize control. However, the one exception is that the textarea appears to have a hard min-height/min-width setting that\'s not changeable vi
These "min-height
/min-width
" rely on cols
and rows
attributes.
Eg. if cols
is missing or less than 1, its default value is 20, so the minimum width will be 20 characters width.
(cf. http://www.w3.org/TR/html5/forms.html#the-textarea-element)
The fact you cannot resize a textarea
under its initial dimensions is reported as a bug (https://code.google.com/p/chromium/issues/detail?id=94583) although
The user agent may restrict the resizing range to something suitable, such as between the original formatted size of the element, and large enough to encompass all the element's contents.
http://www.w3.org/TR/css3-ui/#resize
Unfortunately it seems there's no way for now to change this behaviour.
Another javascript solution:
Demo: http://jsfiddle.net/nz8ut/2/
function resizableStart(e){
this.originalW = this.clientWidth;
this.originalH = this.clientHeight;
this.onmousemove = resizableCheck;
this.onmouseup = this.onmouseout = resizableEnd;
}
function resizableCheck(e){
if(this.clientWidth !== this.originalW || this.clientHeight !== this.originalH) {
this.originalX = e.clientX;
this.originalY = e.clientY;
this.onmousemove = resizableMove;
}
}
function resizableMove(e){
var newW = this.originalW + e.clientX - this.originalX,
newH = this.originalH + e.clientY - this.originalY;
if(newW < this.originalW){
this.style.width = newW + 'px';
}
if(newH < this.originalH){
this.style.height = newH + 'px';
}
}
function resizableEnd(){
this.onmousemove = this.onmouseout = this.onmouseup = null;
}
var els = document.getElementsByClassName('resizable');
for(var i=0, len=els.length; i<len; ++i){
els[i].onmouseover = resizableStart;
}
The solution above uses mouseover
and mouseout
to trigger resizableStart
and resizableEnd
. The problem is that if the element being resized has childs, when the mouse is placed over a child, the element receives a mouseout
event and, just after that, it receives a mouserover
event which bubbles from child.
To avoid those events I have implemented another solution with mouseenter
and mouseleave
events:
Demo: http://jsfiddle.net/nz8ut/3/
Here's the answer you're looking for. This is my original solution, so you've seen it here first!!
The code I've done below is in its most basic form. I've simplified it to remove the Javascript library I'd normally use along with other custom stuff I'd have to explain. This is the solution without needing any external libraries etc.
It adds an interval that checks to see if the textarea size has changed whilst the mouse cursor is over it. If it changes we know the user dragged so we force the textarea size to be 1px by 1px. This creates a very slight flicker for the user, but because they are dragging the size instantly goes back to the size they are dragging it to, only now, it will shrink all the way down to 1px by 1px.
Demo: http://jsfiddle.net/greatbigmassive/zJ4z5/5/
function TA_start(id){
var ta = document.getElementById(id);
if(typeof(ta.resizeCheckStarted) == "undefined"){
ta.resizeCheckStarted = true;
ta.resizeUpdated = false;
var cs = window.getComputedStyle(ta,null);
ta.originalH = cs.getPropertyValue("height");
ta.originalW = cs.getPropertyValue("width");
ta.originalM = cs.getPropertyValue("margin");
ta.style.width = ta.originalW;
ta.style.height= ta.originalH;
ta.style.margin= ta.originalM;
ta.resizeCheck = setInterval("TA_checkMe('"+id+"')",100);
}
}
function TA_checkMe(id){
var ta = document.getElementById(id);
if(ta.originalW != ta.style.width || ta.originalH != ta.style.height){
ta.resizeUpdated = true;
ta.originalW = ta.style.width;
ta.originalH = ta.style.height;
ta.style.width="1px";
ta.style.height="1px";
clearInterval(ta.resizeCheck);
}
}
function TA_stop(id,init){
var ta = document.getElementById(id);
if(typeof(init)=="undefined"){
if(typeof(ta.stopResizeCheck)=="undefined"){
ta.stopResizeCheck = setTimeout("TA_stop('"+id+"',true)",500);
}
} else {
clearInterval(ta.resizeCheck);
if(ta.resizeUpdated != true){
delete ta.resizeCheckStarted;
}
}
}
Fixes:
a). It doesn't shrink first time b). You don't need any additional CSS with it