If you have worked with CSS a lot you may have noticed that input fields do not behave like other HTML elements when it comes to making an input field fit the content within it. In this article I'm going to show you a simple trick to make an input field grow and shrink as you type with some little CSS and JavaScript.
For the markup we're going to need an input and a span.
<input type="text">
<span></span>
Now let's apply some styles to our content.
input[type="text"],
span {
font-family: 'Open Sans', 'Helvetica Neue', sans-serif;
font-size: 1.75rem;
border: 2px solid #666;
/* box-sizing: border-box; */
/* padding: 0.5em 1em; */
}
input[type="text"] {
width: 6em;
padding: 0.5em 1em;
color: #555;
border-radius: 2em;
outline: 0;
}
input[type="text"]:focus {
border-color: #ff7996;
}
span {
position: absolute;
left: -9999px;
display: inline-block;
min-width: 6em;
}
There's one thing to note here. Borders and font properties applied to the input field need to be applied to the span as well, the padding also needs to be applied to both the span and the input if we set the box-sizing
to border-box
, you'll know why when we move to JavaScript. Notice that I set a min-width
to the span and width
to the input field this is just to have a predefined width for our input field so that the it doesn't shrink below that width. Other styles are there just to hide the span and make the input field look pretty.
Now let's move to the actual trick.
const input = document.querySelector('input');
const span = document.querySelector('span');
input.addEventListener('input', function (event) {
span.innerHTML = this.value.replace(/\s/g, ' ');
this.style.width = span.offsetWidth + 'px';
});
In the code above we simply listen to input events on our text input then we replace the content of the span with the content in the input. Notice that we also replace the spaces on this.value
by  
due to the fact that in HTML multiple spaces will only be rendered as a single space. After that we apply the width of the span to the input field.
This is how it would look like:
I hope this article was helpful.
Any questions or additions? Leave a comment below.
Top comments (5)
Awesome!
Thank you very much. :)