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>

Samostatná živá ukázka

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.

Živá ukázka

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>

Autor se webdesignu intensivněji věnuje od roku 2005. V poslední době se zabývá hlavně tvorbou responsivních webů a frontendem. Od roku 2013 o tom píše na webu jecas.cz.

Zatím nebyl přidán žádný komentář, buďte první!

Přidat komentář
Zdroj: https://www.zdrojak.cz/?p=18681