5

I have 4 blocks with a title, description and a button.

I want to keep Title and Description aligned on top, and the Button to be aligned on bottom no matter how long the description or title is.

I also need to keep the same HTML structure.

Sample picture of what I actually need:

Sample picture of what I actually need

Can somebody figure it out? I didn't find a fix on internet so far.

/* FLEXBOX RELATED */
.grid {
  display: flex;
  justify-content: space-between;
  flex-flow: row wrap;
}
.block {
  flex: 0 24%;
  display: flex;
}
.container {
  display: flex;
  flex-flow: row wrap;
  align-items: flex-start;
}
.title {
  flex: 0 100%;
}
.desc {
  flex: 0 100%;
}
.button {
  flex: 0 100%;
  align-self: flex-end;
}


/* NO FLEXBOX RELATED */
.block {
  background-color: #ccc;
}
.title {
  font-size: 2rem;
  font-weight: bold;
  padding: 0.5rem;
  text-align: center;
}
.desc {
  background-color: grey;
  padding: 0.5rem;
}
.button {
  padding: 0.5rem;
  color: blue;
  text-align: center;
  font-weight: bold;
}
<div class="grid">
  <div class="block">
    <div class="container">
      <div class="title">Title 1</div>
      <div class="desc">Description Description Description Description Description Description Description Description Description Description</div>
      <div class="button">Button</div>
    </div>
  </div>
  <div class="block">
    <div class="container">
      <div class="title">Title 2</div>
      <div class="desc">Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description</div>
      <div class="button">Button</div>
    </div>
  </div>
  <div class="block">
    <div class="container">
      <div class="title">Title 3</div>
      <div class="desc">Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description</div>
      <div class="button">Button</div>
    </div>
  </div>
  <div class="block">
    <div class="container">
      <div class="title">Title 4</div>
      <div class="desc">Description Description Description Description Description Description Description Description Description Description</div>
      <div class="button">Button</div>
    </div>
  </div>
</div>

The codepen code is here

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
ice
  • 65
  • 1
  • 6

1 Answers1

4

Since you're working with a row-direction flex container, pinning the last item to the bottom is not possible. You're dealing with cross axis space distribution, which means flex lines are either stretched or packed, and there's no way to pin two items to the top and one to the bottom (unless you go beyond flexbox and use absolute positioning).

Here's a complete explanation.

A simple and effective method to make your layout work would be a column-direction container with a flex auto margin on the last item. By aligning your items on the main axis you can space away individual items.

Here's an explanation of flex auto margins:

/* FLEXBOX RELATED */
.grid {
  display: flex;
  justify-content: space-between;
  flex-flow: row wrap;
}
.block {
  flex: 0 24%;
  display: flex;
}
.container {
  display: flex;
  flex-direction: column; /* new */
  /* flex-flow: row wrap; */
  /* align-items: flex-start; */
}
.title {
  /* flex: 0 100%; */
}
.desc {
  /* flex: 0 100%; */
}
.button {
  margin-top: auto; /* new */
  /* flex: 0 100%; */
  /* align-self: flex-end; */
}


/* NO FLEXBOX RELATED */
.block {
  background-color: #ccc;
}
.title {
  font-size: 2rem;
  font-weight: bold;
  padding: 0.5rem;
  text-align: center;
}
.desc {
  background-color: grey;
  padding: 0.5rem;
}
.button {
  padding: 0.5rem;
  color: blue;
  text-align: center;
  font-weight: bold;
}
<div class="grid">
  <div class="block">
    <div class="container">
      <div class="title">Title 1</div>
      <div class="desc">Description Description Description Description Description Description Description Description Description Description</div>
      <div class="button">Button</div>
    </div>
  </div>
  <div class="block">
    <div class="container">
      <div class="title">Title 2</div>
      <div class="desc">Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description</div>
      <div class="button">Button</div>
    </div>
  </div>
  <div class="block">
    <div class="container">
      <div class="title">Title 3</div>
      <div class="desc">Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description</div>
      <div class="button">Button</div>
    </div>
  </div>
  <div class="block">
    <div class="container">
      <div class="title">Title 4</div>
      <div class="desc">Description Description Description Description Description Description Description Description Description Description</div>
      <div class="button">Button</div>
    </div>
  </div>
</div>

revised codepen

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • Thank you @Michael_B for such a good explanation. What if I want to add a second div to stick to bottom like on this codepen [Codepen link with 2 divs pinned to bottom](https://codepen.io/nicutor/pen/preEQq) Doesn't seem to work with margin-top: auto. Is there a way to fix this? Should I open a new question or you can respond here? I am quite new at stackoverflow. Thank you. – ice Aug 08 '17 at 00:13
  • Leave `margin-top: auto` on the top div you want bottom-aligned. That will space away all the items above, and pack all items below. Remove the other `margin-top: auto`. If you leave it on the bottom item, it will try to space away from the one right above. https://codepen.io/anon/pen/WEpGWg – Michael Benjamin Aug 08 '17 at 00:21
  • Thank you very much. You saved my day! I will come back to you for sure in future if I will have more questions. This thing with margin-top: auto, was a mister for me by now. I saw something about, read it, but never understand it. I've also found some [extra explanation about here](https://hackernoon.com/flexbox-s-best-kept-secret-bd3d892826b6). Maybe can be usefully for others too. Have a great day! – ice Aug 08 '17 at 00:33
  • The second link in my answer provides a complete and easy-to-follow explanation of flex auto margins. – Michael Benjamin Aug 08 '17 at 00:40