Michael
Michael

Reputation: 16122

Align columns of a multiple flexbox rows

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

Upvotes: 2

Views: 2055

Answers (4)

user5086888
user5086888

Reputation:

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>

Upvotes: 0

Oriol
Oriol

Reputation: 287950

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>

Upvotes: 2

Michael Benjamin
Michael Benjamin

Reputation: 370993

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

Upvotes: 2

avrahamcool
avrahamcool

Reputation: 14094

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>

Upvotes: 1

Related Questions