2

I'm using flexbox for grid columns

In the first row I have three dr-col-1 and two dr-col-2 (total of 7 flex-grow steps).

In the second row I have all seven dr-col-1.

When I rendered it, I noticed that alignment it not precise:

enter image description here

How can I precisely align columns in both rows?

.dr-row {
  display: flex;
}
.dr-col-1 {
  flex-grow: 1;
  flex-basis: 0;
  border: 1px solid black;
}

.dr-col-2 {
  flex-grow: 2;
  flex-basis: 0;
  border: 1px solid black;
}
<div class="dr-row">
    <div class="dr-col-2">
      one
    </div>

    <div class="dr-col-1">
      two
    </div>

    <div class="dr-col-1">
      three
    </div>

    <div class="dr-col-1">
      four
    </div>

    <div class="dr-col-2">
      five
    </div>
  </div>

<div class="dr-row">
    <div class="dr-col-1">
      one
    </div>

    <div class="dr-col-1">
      two
    </div>

    <div class="dr-col-1">
      three
    </div>

    <div class="dr-col-1">
      four
    </div>

    <div class="dr-col-1">
      five
    </div>
    <div class="dr-col-1">
      six
    </div>
    <div class="dr-col-1">
      seven
    </div>
  </div>

Codepen

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Michael
  • 15,386
  • 36
  • 94
  • 143

4 Answers4

2

The flex-grow property is designed to distribute free space in the container. It's not designed for specific sizing of flex items (that would be flex-basis).

The columns aren't aligning because there are more vertical borders in the second row.

More specifically, there is 8px of border width in row one, and 12px of border width in row two (not including the edges).

This means there is more free space in row one, which results in the misalignment.

Instead of using flex-grow try using flex-basis:

.dr-row {
  display: flex;
}
.dr-col-1 {
  flex: 0 0 14.29%;
  border: 1px solid black;
  box-sizing: border-box;
}

.dr-col-2 {
  flex: 0 0 28.58%;
  border: 1px solid black;
  box-sizing: border-box;
}
body { margin: 0; }
<div class="dr-row">
    <div class="dr-col-2">one</div>
    <div class="dr-col-1">two</div>
    <div class="dr-col-1">three</div>
    <div class="dr-col-1">four</div>
    <div class="dr-col-2">five</div>
  </div>

<div class="dr-row">
    <div class="dr-col-1">one</div>
    <div class="dr-col-1">two</div>
    <div class="dr-col-1">three</div>
    <div class="dr-col-1">four</div>
    <div class="dr-col-1">five</div>
    <div class="dr-col-1">six</div>
    <div class="dr-col-1">seven</div>
  </div>

revised codepen

For more information see: flex-grow not sizing flex items as expected

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
2

When you have two .dr-col-1, there are 4 borders, 4 * 1px = 4px.

When you have one .dr-col-2, there are 2 borders, 2 * 1px = 2px.

So you need to compensate that difference of 2px, for example by increasing the flex-basis:

.dr-col-2 {
  flex-basis: 2px; /* flexFactor * borderWidth */
}

.dr-row {
  display: flex;
}
.dr-col-1 {
  flex-grow: 1;
  flex-basis: 0;
  border: 1px solid black;
}
.dr-col-2 {
  flex-grow: 2;
  flex-basis: 2px;
  border: 1px solid black;
}
<div class="dr-row">
  <div class="dr-col-2">one</div>
  <div class="dr-col-1">two</div>
  <div class="dr-col-1">three</div>
  <div class="dr-col-1">four</div>
  <div class="dr-col-2">five</div>
</div>
<div class="dr-row">
  <div class="dr-col-1">one</div>
  <div class="dr-col-1">two</div>
  <div class="dr-col-1">three</div>
  <div class="dr-col-1">four</div>
  <div class="dr-col-1">five</div>
  <div class="dr-col-1">six</div>
  <div class="dr-col-1">seven</div>
</div>
Oriol
  • 274,082
  • 63
  • 437
  • 513
  • 1
    It's interesting that `box-sizing: border-box` doesn't solve this problem. – Michael Benjamin Jan 21 '17 at 21:49
  • @Michael_B It would be interesting if `box-sizing: border-box` prevented the borders from reducing the available space, but probably it would be so problematic. – Oriol Jan 21 '17 at 22:03
  • Yes, that's what I was thinking. Unlike `flex-basis`, `flex-grow` doesn't recognize the `border-box` box model. Then again, why would it? `flex-grow` is only concerned about container space. But then again, `border-box` changes width calculations. FML. – Michael Benjamin Jan 21 '17 at 22:08
1

The border also takes some place

here is the same HTML/CSS, but I used outline instead of borders.

https://jsfiddle.net/nfo1pg9f/

.dr-row {
  display: flex;
  box-sizing: border-box;
}
.dr-col-1 {
  flex-grow: 1;
  flex-basis: 0;
  outline: 1px solid black;
}

.dr-col-2 {
  flex-grow: 2;
  flex-basis: 0;
  outline: 1px solid black;
}
<div class="dr-row">
    <div class="dr-col-2">
      one
    </div>

    <div class="dr-col-1">
      two
    </div>

    <div class="dr-col-1">
      three
    </div>

    <div class="dr-col-1">
      four
    </div>

    <div class="dr-col-2">
      five
    </div>
  </div>

<div class="dr-row">
    <div class="dr-col-1">
      one
    </div>

    <div class="dr-col-1">
      two
    </div>

    <div class="dr-col-1">
      three
    </div>

    <div class="dr-col-1">
      four
    </div>

    <div class="dr-col-1">
      five
    </div>
    <div class="dr-col-1">
      six
    </div>
    <div class="dr-col-1">
      seven
    </div>
  </div>
avrahamcool
  • 13,888
  • 5
  • 47
  • 58
0

Here give this a try, not sure if it's the best resolve, but seems to align perfectly no matter the browser size

The border is seems to be off on the elements, adding a single pixel to the grow:2; seems to realign things again. I added some margin and padding for appearance purpose

.dr-row {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-around;
  
}
.dr-row div{
  margin:5px;
  flex-basis: 0;
  border: 1px solid black;
}
.dr-col-1 {
  flex-grow: 1;
}

.dr-col-2 {
  flex-grow: 2;
  padding: 6px;
}
<div class="dr-row">
    <div class="dr-col-2">
      one
    </div>

    <div class="dr-col-1">
      two
    </div>

    <div class="dr-col-1">
      three
    </div>

    <div class="dr-col-1">
      four
    </div>

    <div class="dr-col-2">
      five
    </div>
  </div>

<div class="dr-row">
    <div class="dr-col-1">
      one
    </div>

    <div class="dr-col-1">
      two
    </div>

    <div class="dr-col-1">
      three
    </div>

    <div class="dr-col-1">
      four
    </div>

    <div class="dr-col-1">
      five
    </div>
    <div class="dr-col-1">
      six
    </div>
    <div class="dr-col-1">
      seven
    </div>
  </div>
  • Your requests and questions should be in a comment section. It's not an answer – Michael Jan 21 '17 at 21:26
  • well please post some of the code so a real answer can be given –  Jan 21 '17 at 21:34
  • I hope this helps. –  Jan 21 '17 at 22:21
  • I would be grateful if someone can remove this negative 1 because I am new to stack overflow, it wont allow me to help other people with their issues. –  Jan 23 '17 at 17:47