1.21 gigawatts
1.21 gigawatts

Reputation: 17870

Setting the flex values to make the label appear correctly when container width is small?

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

Answers (2)

Temani Afif
Temani Afif

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

BugsArePeopleToo
BugsArePeopleToo

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

Related Questions