Reputation: 4183
I am looking for a way to control the size of my input
element in the way similar to divs.
.main {
width: 100%;
display: flex;
}
.line {
min-width: 2rem;
display: flex;
}
.input {
flex: 1 1 auto;
min-width: 0;
}
<div class="main">
<div class="line">
<input class="input" />
</div>
</div>
Here I am expecting that when the view appears the initial input is of size 2rem
(padding, margin, border do not matter here) and when you start typing and exceeds the size it grows till it reach the size of main
. Any suggestions how I can achieve that?
Upvotes: 0
Views: 339
Reputation: 2829
Here is another solution using the .getBoundingClientRect()
, so the idea is to add the text of the input to a p element calculate the width of it then set it as the width of the input, this keeps using the same input instead of content editable trick that a user can press enter and have multiple lines, also can be used in forms...
var txtElement = document.querySelector("#hidden-text");
document.querySelector(".input").oninput = function() {
txtElement.innerHTML = this.value;
var width = txtElement.getBoundingClientRect().width;
this.style.width = width < 100 ? 100 : width + "px";
};
.input {
width: 100px;
}
#hidden-text {
display: inline-block;
position: absolute;
visibility: hidden;
}
#hidden-text, .input {
font-size: 16px;
font-family: Serif;
}
<div class="main">
<div class="line">
<input class="input"/>
</div>
</div>
<p id="hidden-text"></p>
Upvotes: 1
Reputation: 4122
An example using only CSS and the contenteditable
attribute:
.main {
display: flex;
}
.line {
display: flex;
}
.input {
border: 1px solid lightslategray;
padding: 0.5em;
margin: 1em;
min-width: 30ch;
max-width: 100%;
}
<div class="main">
<div class="line">
<p class="input" contenteditable></p>
</div>
</div>
Upvotes: 2
Reputation: 64705
Probably not the most efficient solution, but you could do something like this:
document.querySelector('.input').addEventListener('input', function(e) {
let span = document.createElement('span');
span.innerHTML = e.target.value;
span.style.visibility = 'hidden';
span.style.fontSize = '15px';
document.body.appendChild(span);
if (span.offsetWidth > e.target.offsetWidth - 10) {
e.target.style.width = span.offsetWidth + 'px';
}
span.parentNode.removeChild(span);
});
.main {
width: 100%;
display: flex;
}
.line {
min-width: 2rem;
display: flex;
}
.input{
flex: 1 1 auto;
min-width: 0;
}
<div class="main">
<div class="line">
<input class="input"/>
</div>
</div>
Upvotes: 1