Auto-resizing text areas

Something that I’ve always been confused by is why so many forms on websites require the user to drag and expand large text areas if they need more space.

See that diagonal line at the bottom right? That want’s you to drag the textarea to see all the text you just typed in.

This is the default behaviour of <textarea> components, but it’s unnecessary — If I typed more text in than currently fits, I want to see that text, so just expand it for me.

The improvement

Here’s how developers should refine the textarea instead. It should just auto expand or contract depending on how much you type in.

As a developer, it also means you no longer need to add restrictions to how the user can resize it — Because the width will likely be static, and your character limit, if you have one, will limit the height automatically.

An example where the text is still less than one line.
An example where there text is longer and therefore so is the textarea.

React code

import React, { useRef } from 'react';

//////////////

interface AutoHeightTextareaProps {
    onChange: (value: string) => void;
    style?: React.CSSProperties;
}

const AutoHeightTextarea = (props: AutoHeightTextareaProps) => {
    const textAreaRef = useRef<HTMLTextAreaElement>(null);

    const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
        console.log('handleChange')
        props.onChange(e.target.value);
        // This changes the height of the textarea if needed
        if (!textAreaRef.current) return;
        textAreaRef.current.style.height = props.style?.minHeight?.toString() ?? '1.5em';
        textAreaRef.current.style.height = `${textAreaRef.current.scrollHeight}px`;
    };

    console.log('rerendering');

    return (
        <textarea
            ref = {textAreaRef}
            onChange={handleChange}
            style = {{
                resize: 'none',
                overflow: 'hidden',
                width: '100%',
                border: '1px solid #000',
                borderRadius: '8px',
                // 0 padding on the bottom edge helps it look visually balanced with the top.
                padding: '8px 8px 0px 8px',
                backgroundColor: 'transparent',
                ...props.style,
            }}
        />
    );
};

export default AutoHeightTextarea;

Note that in the code above, I don’t manage the value of the textbox separately. This means that if I needed to re-render the component the value would be lost. If you do need re-render at all (Or need to give it an initial value), put it in a useState managed variable that you update in when handling the change.

Thanks…

I also dissect and speculate on design and development.
Digging into subtle details and implications, and exploring broad perspectives and potential paradigm shifts.
Check out my conceptual articles on Substack or find my latest below.


You can also find me on Threads, Bluesky, Mastodon, or xTwitter for more diverse posts about ongoing projects.

My latest articles

Storyboarding Immersive Experiences

Storyboarding 360 degree immersive experiences requires a different approach to traditional media…

Staging XR scenes (Keep doing your crappy little drawings)

Some people create beautiful perspective illustrations to visualise and storyboard their virtual reality designs And it’s tempting to think you’re not a strong designer if you’re not doing that too…

Focal point blocking for XR media

Planning out a linear VR experience requires thinking about where the viewers attention might be. Thinking about the focal points…

Designing immersive experiences

In traditional cinema, TV, or even the more modern phone screen, there’s limited screen real-estate. But removing that limitation creates a design problem…

The future is not prompt engineered

Let’s not pretend the importance of prompt engineering is ubiquitous. The most prevalent power of generative AI is in the way it adapts to us, not the other way around…

The typography of dates, times, & filenames

A deep dive into carefully considered date formatting, line length and general typography attributes of filenames…
Bluesky
Threads
Twitter / X
Mastodon
Instagram


Author:

Date:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.