1

In my layout, I have three vertically stacked items within a column. What I'm trying to achieve is to center the middle item (green) within the column and have the other items attached to that.

What I have:

.flex-row {
   display: flex;
   flex-direction: row;
}

.flex-col {
   display: flex;
   flex-direction: column;
}

.flex-start {
  display: flex;
  justify-content: flex-start;
}

.flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

.flex-end {
  display: flex;
  justify-content: flex-end;
}

.col {
  width: 50px;
  min-height: 250px;
  margin: 5px;
}

.item {
  width: 40px;
  height: 40px;
  margin: 5px;
}

.long {
  height: 60px;
}

.red {
  background: red;
}

.blue {
  background: blue;
}

.green {
  background: green;
}
.yellow {
  background: yellow;
}
<div class="flex-row">
  <div class="red col flex-center">
    <div class="flex-col">
      <div class="blue item"></div>
      <div class="green item"></div>
      <div class="yellow item long"></div>
    </div>
  </div>
  <div class="red col flex-center">
    <div class="flex-col">
      <div class="blue item long"></div>
      <div class="green item"></div>
      <div class="yellow item"></div>
    </div>
  </div>
  <div class="red col flex-center">
    <div class="flex-col">
      <div class="blue item long"></div>
      <div class="green item"></div>
      <div class="yellow item long"></div>
    </div>
  </div>
</div>

What I'm aiming at:

enter image description here

It should be noted that the center items (green) have a fixed height, while the other's height (blue and yellow) is determined by the content. I could set a fixed size on the columns as well, but I'd prefer it be flexible and adapt to the height of the contained items.

idleberg
  • 12,634
  • 7
  • 43
  • 70
  • I don’t see how that would be possible - not if you want to keep this HTML structure. If you changed the direction of the flex main axis, and grouped the elements “by color” instead in the HTML, _then_ you could have the blue items in the first _row_ aligned to the bottom, and the yellow ones to the top. (That would still not make the green part be perfectly centered though, if the largest blue and the largest yellow element aren’t the same size.) – 04FS Sep 19 '19 at 09:00
  • You have to wrap inner 3 boxes with `div` and assign different classes to achieve this layout with `CSS`. – Asfan Shaikh Sep 19 '19 at 09:02

1 Answers1

3

You can achieve that layout with positioning, since green box has a fixed height.

.flex-row {
  display: flex;
  flex-direction: row;
}

.flex-col {
  height: 100%;
  position: relative;
}

.col {
  width: 50px;
  min-height: 250px;
  margin: 5px;
}

.item {
  width: 40px;
  height: 40px;
  margin: 5px;
}

.long {
  height: 60px;
}

.red {
  background: red;
}

.blue {
  background: blue;
  position: absolute;
  bottom: calc(50% + 25px); /* 5px for margin + green box's height / 2 */
}

.green {
  background: green;
  position: relative;
  top: 50%;
  transform: translateY(-50%)
}

.yellow {
  background: yellow;
  position: absolute;
  top: calc(50% + 25px); /* 5px for margin + green box's height / 2 */
}
<div class="flex-row">
  <div class="red col flex-center">
    <div class="flex-col">
      <div class="blue item"></div>
      <div class="green item"></div>
      <div class="yellow item long"></div>
    </div>
  </div>
  <div class="red col flex-center">
    <div class="flex-col">
      <div class="blue item long"></div>
      <div class="green item"></div>
      <div class="yellow item"></div>
    </div>
  </div>
  <div class="red col flex-center">
    <div class="flex-col">
      <div class="blue item long"></div>
      <div class="green item"></div>
      <div class="yellow item long"></div>
    </div>
  </div>
</div>
user9408899
  • 4,202
  • 3
  • 19
  • 32