Jak na textareu s automatickou výškou

Ukážeme vám, jak zajistit, aby se výška textového pole přizpůsobovala délce textu.
Článek původně vyšel na autorově webu Je čas.
Při použití pole pro psaní delšího textu (<textarea>
) čelíme dilematu, jak ho udělat vysoké. Nízká výška způsobí uživateli, který bude chtít zapsat delší text, značné nepohodlí. Naopak vysoká <textarea>
bude zase zabírat možná zbytečně hodně místa.
Prohlížeče kromě IE 11 a starších umožňují provést změnu velikosti tažením myši, slouží k tomu CSS vlastnost resize
.
Co ale velikost uzpůsobovat automaticky v závislosti na obsahu?
Počítání znaků
Asi první, co člověka napadne, je počítat v <textarea>
znaky a odřádkování a nějak podle toho vypočítat výšku.
Přepočet výšky je nutný provádět při události oninput
(pro starší prohlížečeonkeyup
+ onpaste
+ oncut
+ onfocus
).
Vzhledem k různým proporcím různých písmen je téměř nemožné dosáhnout přesného výsledku.
Zjištění výšky scrollHeight
Asi nejlepší možnost je při změně obsahu nastavit výšku na 0
a z vlastnostiscrollHeight
získat rozměry, které se následně nastaví jako výška.
V případě okrajového box modelu je ještě nutno připočíst offsetHeight
.
Skript si při inicializaci nastaví pro <textarea>
do data-*
atributu aktuální výšku, která se bude brát jako minimální. Výchozí minimální výšku tak jde zadat přes height
nebo atributem rows
.
<style>
.pole {
box-sizing: border-box;
}
</style>
<script>
var AutoHeightArea = function() {
var originalArea;
var addEvent = function(element, evnt, funct) {
if (element.attachEvent)
return element.attachEvent('on' + evnt, funct);
else
return element.addEventListener(evnt, funct, false);
};
var resize = function() {
var minHeight = originalArea.getAttribute("data-original-height");
originalArea.style.height = "0";
var newHeight = originalArea.scrollHeight + originalArea.offsetHeight;
if (minHeight > newHeight) {
newHeight = minHeight;
}
originalArea.style.height = newHeight + "px";
};
var init = function(area) {
originalArea = area;
originalArea.setAttribute("data-original-height", area.offsetHeight);
addEvent(originalArea, "paste", resize);
addEvent(originalArea, "cut", resize);
addEvent(originalArea, "input", resize);
addEvent(originalArea, "keyup", resize);
};
return {
init : init
};
}();
</script>
<textarea name="pole" id="pole" cols="30" rows="3" class="pole" data-original-height="42"></textarea>
<script>
AutoHeightArea.init(document.getElementById("pole"));
</script>
Využití contenteditable
Poslední možnost je použít contenteditable
atrapu. Skutečná <textarea>
se schová pomocí display: none
a místo ní se vloží obyčejný <div>
, který umožňuje zapisovat text. Při odeslání formuláře se potom obsah <div>
u překopíruje do skutečného pole, které se tak řádně odešle na server. Jde si tak vytvořit i primitivní WYSIWYG editor. Jelikož se jedná o obyčejný <div>
, automatické roztahování bude jeho běžná vlastnost.
Nevýhoda tohoto postupu tkví ve větší pracnosti s převedením obsahu do požadované formy. Z políčka vyleze místo plain textu HTML, které se navíc bude lišit napříč prohlížeči.
Například odřádkování někde vytváří nové odstavce (<p>
), jinde <div>
a někde pro změnu <br>
.
Odkazy jinam
- jQuery Autosize – plugin do jQuery zajišťující automatickou výšku (může být i plynule animovaná).
- Stretchy – automatická velikost elementů
<textarea>
i<input>