Labanino
Labanino

Reputation: 3960

Flex items in a row rendering at different widths

I created 3 boxes using css flexbox in html but Chrome is rendering the boxes with different sizes.

enter image description here

Drag the border of the browser to make the view smaller.

Thanks for your help!

Codepen: https://codepen.io/labanino/pen/rGaNLP

body {
  font-family: Arial;
  font-size: 2rem;
  text-transform: uppercase;
}

.flex {
  height: 200px;
  display: flex;
  flex-direction: row;
}

.flex>section {
  flex: 1 1 auto;
  display: flex;
  justify-content: center;
  flex-direction: column;
  text-align: center;
}

.flex>section:nth-child(1) {
  background: brown;
  margin-right: 20px;
  border: 1px solid #999;
}

.flex>section:nth-child(2) {
  background: pink;
  margin-right: 20px;
  border: 1px solid #999;
}

.flex>section:nth-child(3) {
  background: green;
  margin-right: 0;
  border: 1px solid #999;
}
<div class="flex">
  <section>Brown</section>
  <section>Pink</section>
  <section>Green</section>
</div>

Upvotes: 5

Views: 9061

Answers (2)

Michael Benjamin
Michael Benjamin

Reputation: 371003

Here's the source of the problem:

.flex > section { flex: 1 1 auto }

This breaks down to:

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: auto

With flex-basis: auto you are sizing the item based on the length of the content. Hence, wider content will create wider items.

If you want equal size for all items in the row, then use:

  • flex-basis: 0, and
  • min-width: 0 / overflow: hidden

With flex-basis: 0 you're allocating to each item an equal distribution of space in the container. More details here: Make flex-grow expand items based on their original size

With min-width: 0 or overflow: hidden you're allowing items to shrink past their content, so they can remain equal size on smaller screens. More details here: Why doesn't flex item shrink past content size?

.flex {
  display: flex;
  height: 200px;
}
.flex>section {
  flex: 1;          /* new; same as flex: 1 1 0 */
  overflow: hidden; /* new */
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

/* non-essential demo styles */
.flex>section:nth-child(1) {
  background: brown;
  margin-right: 20px;
  border: 1px solid #999;
}
.flex>section:nth-child(2) {
  background: pink;
  margin-right: 20px;
  border: 1px solid #999;
}
.flex>section:nth-child(3) {
  background: green;
  margin-right: 0;
  border: 1px solid #999;
}
body {
  font-family: Arial;
  font-size: 2rem;
  text-transform: uppercase;
}
<div class="flex">
  <section>Brown</section>
  <section>Pink</section>
  <section>Green</section>
</div>

revised codepen

Upvotes: 4

Spartacus
Spartacus

Reputation: 1508

Don't use auto in your flex property for your items. Use 100%, and this will adapt the width in the flex box, and adjusts to any number of elements you add (in case you want to add more than 3).

.flex > section {
  flex: 1 1 100%;  
  display: flex;
  justify-content: center;
  flex-direction: column;
  text-align: center;
}

The reason they're all different sizes is because when you use auto, it bases its width on the content of the box. That's why the middle one isn't as wide, because the word 'pink' takes up less space than 'green'.

Upvotes: 7

Related Questions