Reputation: 17870
In the following form the label along the left column is sized correctly until there is not enough room. Then the labels shrink. But when the row has 3 items in it the label is sized different than the row with 2 items.
body {
font-family: Arial;
font-size: 12px;
}
.input1 {
flex: 1;
}
.row {
flex-direction: row;
display: flex;
flex: 1;
align-items: center;
}
span {
width: 120px;
}
.main {
width: 200px;
}
.group {
border: 1px solid rgba(0,0,0,.25);
}
.shrinkSameAmount {
width: 52px;
min-width: 52px;
}
<p>Full Size:</p>
<div class="group">
<div class="row"><span>ID</span><input class="input1"/></div>
<div class="row"><span>ID</span><input class="input1"/><button>X</button></div>
</div>
<p>Reduced Size:</p>
<div class="main group">
<div class="row"><span>ID</span><input class="input1"/></div>
<div class="row"><span>ID</span><input class="input1"/><button>X</button></div>
</div>
<p>What I want when reduced:</p>
<div class="main group">
<div class="row"><span class="shrinkSameAmount">ID</span><input class="input1"/></div>
<div class="row"><span class="shrinkSameAmount">ID</span><input class="input1"/><button>X</button></div>
</div>
Is there a way I can keep the label widths to the same size whether the width of the viewport is large or small?
Upvotes: 2
Views: 2121
Reputation: 274024
First add min-width:0
to the input and button element to allow them to shrink. Then you can adjust the flex-basis
to make sure that the input alone or the button and the input will have the same value.
In the example below the value is 300px
. If the input is alone it will take all this as its flex-basis
. With the button, the value will be splitted between both
* {
box-sizing: border-box;
}
body {
font-family: Arial;
font-size: 12px;
}
.input1 {
min-width: 0;
flex-basis: 210px;
flex-grow: 1;
}
.input1:last-child {
flex-basis: 300px;
}
button:last-child {
flex-basis: 90px;
max-width: 90px;
min-width: 0;
padding: 1px 0;
flex-grow: 1;
}
.row {
flex-direction: row;
display: flex;
flex: 1;
align-items: center;
}
span {
flex-basis: 120px;
}
.group {
border: 1px solid rgba(0, 0, 0, .25);
width: 100%;
animation: change 5s linear infinite alternate;
}
@keyframes change {
to {
width: 18%;
}
}
<p>Full Size:</p>
<div class="group">
<div class="row"><span>ID</span><input class="input1" /></div>
<div class="row"><span>ID</span><input class="input1" /><button>X</button></div>
</div>
There is a slight miss alignment at low width, I will figured it out.
Upvotes: 2
Reputation: 2996
Flexbox applies certain flexibility you need to control in this case. I changed your <span>
s into <label>
elements, and added this CSS:
label {
flex: 0 0 120px;
}
The flex
value here is shorthand for flex-grow: 0
, flex-shrink: 0
, flex-basis: 120px
. The flex-basis property is a starting width, set it to whatever value you would like that "column" of labels to be.
To get the fields to obey the width of the container I changed the rule for the inputs to:
.input1 {
width: 100%;
flex-shrink: 1;
}
This makes the inputs use up all available space.
body {
font-family: Arial;
font-size: 12px;
}
label {
flex: 0 0 120px;
}
.input1 {
width: 100%;
flex-shrink: 1;
}
.row {
flex-direction: row;
display: flex;
align-items: center;
}
.main {
width: 200px;
}
.group {
border: 1px solid rgba(0,0,0,.25);
}
<p>Full Size:</p>
<div class="group">
<div class="row"><label>ID</label><input class="input1"/></div>
<div class="row"><label>ID</label><input class="input1"/><button>X</button></div>
</div>
<p>Reduced Size:</p>
<div class="main group">
<div class="row"><label>ID</label><input class="input1"/></div>
<div class="row"><label>ID</label><input class="input1"/><button>X</button></div>
</div>
Upvotes: 1