'input / button elements not shrinking in a flex container
When using input and button elements inside a flex container, the flex
and/or flex-grow
properties don't seem to do anything.
Code that demonstrates my issue.
button,
input {
font-size: 1rem;
}
button {
border: none;
background-color: #333;
color: #EEE;
}
input {
border: 1px solid #AAA;
padding-left: 0.5rem;
}
.inputrow {
width: 30rem;
display: flex;
margin: 0 -.25rem;
}
.inputrow>* {
margin: 0 .25rem;
border-radius: 2px;
height: 1.75rem;
box-sizing: border-box;
}
.nickname {
flex: 1;
}
.message {
flex: 4;
}
.s-button {
flex: 1;
}
<div class="inputrow">
<input type="text" class="nickname" placeholder="Nickname">
<input type="text" class="message" placeholder="Message">
<button type="submit" class="s-button">Submit</button>
</div>
Code that shows what I'm expecting. (using DIVs instead of input
and button
).
.inputrow {
width: 30rem;
display: flex;
flex-flow: row nowrap;
margin: 0 -.25rem;
}
.inputrow>* {
margin: 0 .25rem;
height: 1.75rem;
}
.nickname {
flex: 1;
background-color: blue;
}
.message {
flex: 4;
background-color: red;
}
.s-button {
flex: 1;
background-color: green;
}
<div class="inputrow">
<div class="nickname">Nickname</div>
<div class="message">Message</div>
<div class="s-button">Submit</div>
</div>
Solution 1:[1]
An input
element, unlike a div
, comes with a default width.
Here's a simple illustration of this setting:
The browser automatically gives the input
a width.
input {
border: 1px solid blue;
display: inline;
}
div {
border: 1px solid red;
display: inline;
}
<form>
<input>
<br><br>
<div></div>
</form>
Also, an initial setting on flex items is min-width: auto
. This means that items cannot shrink below their width on the main axis.
Hence, input
elements cannot shrink below their default width and may be forced to overflow the flex container.
You can override this behavior by setting your inputs to min-width: 0
(revised codepen)
Here's a full explanation: Why don't flex items shrink past content size?
In some cases, you may need to override input widths using width: 100%
or width: 0
.
Solution 2:[2]
I would like to extend @Michael Benjamin solution
In some cases, you may need to override input widths using
width: 100%
orwidth: 0
.
you can also do calc(100%)
Solution 3:[3]
I needed to wrap the input element with a styled element and than set the input width
and min-width
as below:
.field__input input {
width: 0;
min-width: 100%;
}
Solution 4:[4]
If you have an input element inside a flex box, you can defined the width: 0
and still can utilize flex: 1
or whatever value you need.
This is Christof Kälin's answer in the comments for another answer. Putting it here for visibility.
Here is the link from his answer with working copy: https://jsbin.com/zutahalawa/edit?html,css,output
Making this answer a community wiki so that I don't get unearned credit.
Solution 5:[5]
if the parent is a flexible container set with the usual flex: 1
(flex-grow: 1
) and you want the input to shrink with the parent, this is what has worked for me:
width: 35px;
flex: 1 2 0px;
Give this as a class to the input, this will make it take the whole space when its available, but shrink to minimum size when resized.
Edit:
This works because it's a shorthand for flex: <flex-grow> <flex-shrink> <flex-basis>
as explained here https://css-tricks.com/snippets/css/a-guide-to-flexbox/#flex
The '2' is assigned to flex-shrink
which makes the element shrink.
Sometimes you still need to add min-width: 0;
as mentioned in other comments to remove the min-width
defined by browsers (for small containers)
Solution 6:[6]
Use flex-basis: 0;
for input
or input container
solves the problem.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Penny Liu |
Solution 3 | Penny Liu |
Solution 4 | |
Solution 5 | Penny Liu |
Solution 6 | Mohammad Barbast |