Search code examples
cssflexboxword-wrapfixed-width

Make fixed width flexbox items wrap correctly


I can't manage to wrap flex items correctly if they're fixed width in Google Chrome. However, when using percentage-based widths, everything wraps correctly.

How can I make this work with fixed width items?

See example: http://codepen.io/anon/pen/wajWLz

* {
  box-sizing: border-box;
  font-family: Arial;
}
.wrapper {
  width: 300px;
  background: #eee;
  border: solid #ddd 1px;
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -moz-box-wrap: wrap;
  -webkit-box-wrap: wrap;
  -webkit-flex-wrap: wrap;
  -ms-flexbox-wrap: wrap;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
}
.item {
  background: #ddd;
  border: solid 1px #aaa;
  width: 100px;
  /* Doesn't wrap correctly */
}
.wrapper-second .item {
  width: 33.333333%
  /* Wraps correctly */
}
<p>The wrapper is 300px wide, each item is <strong>100px</strong> wide</p>

<div class="wrapper">
  <div class="item">item</div>
  <div class="item">item</div>
  <div class="item">item</div>
  <div class="item">item</div>
  <div class="item">item</div>
  <div class="item">item</div>
</div>

<p>you should see 3 items per row,
  <br />Chrome however wraps after the 2nd item (wraps too soon).</p>

<p>when you change the item width to <strong>33.333333%</strong>, it however wraps correctly.</p>

<div class="wrapper wrapper-second">
  <div class="item">item</div>
  <div class="item">item</div>
  <div class="item">item</div>
  <div class="item">item</div>
  <div class="item">item</div>
  <div class="item">item</div>
</div>

<p><strong>Question:</strong> how can I make flexbox wrap fixed width items correctly?</p>


Solution

  • Your issue is that you have set all elements to box-sizing: border-box;. This means that the width of .wrapper will include the border width.

    To fix either:

    • Add box-sizing: content-box; to .wrapper
    • Change width: 300px; to width: 302px; on .wrapper

    * {
      box-sizing: border-box;
      font-family: Arial;
    }
    .wrapper {
      box-sizing: content-box;
      width: 300px;
      background: #eee;
      border: solid #ddd 1px;
      display: -webkit-box;
      display: -moz-box;
      display: -ms-flexbox;
      display: -webkit-flex;
      display: flex;
      -moz-box-wrap: wrap;
      -webkit-box-wrap: wrap;
      -webkit-flex-wrap: wrap;
      -ms-flexbox-wrap: wrap;
      -ms-flex-wrap: wrap;
      flex-wrap: wrap;
    }
    .item {
      background: #ddd;
      border: solid 1px #aaa;
      width: 100px;
      /* Doesn't wrap correctly */
    }
    .wrapper-second .item {
      width: 33.333333%
      /* Wraps correctly */
    }
    <p>The wrapper is 300px wide, each item is <strong>100px</strong> wide</p>
    
    <div class="wrapper">
      <div class="item">item</div>
      <div class="item">item</div>
      <div class="item">item</div>
      <div class="item">item</div>
      <div class="item">item</div>
      <div class="item">item</div>
    </div>
    
    <p>you should see 3 items per row,
      <br />Chrome however wraps after the 2nd item (wraps too soon).</p>
    
    <p>when you change the item width to <strong>33.333333%</strong>, it however wraps correctly.</p>
    
    <div class="wrapper wrapper-second">
      <div class="item">item</div>
      <div class="item">item</div>
      <div class="item">item</div>
      <div class="item">item</div>
      <div class="item">item</div>
      <div class="item">item</div>
    </div>
    
    <p><strong>Question:</strong> how can I make flexbox wrap fixed width items correctly?</p>