1

GOAL: Align the first row's items (images) to the bottom, and the second row's items to the top.

CONDITIONS:
(1) Each item has a different height.
(2) Each item has a different width.

With tables it's dead simple:

enter image description here

.tall {height:100px; width:100px}
.short {height:50px; width:200px}
p {background:blue; margin:0px; display:inline-block}
td {vertical-align:top}
tr:nth-child(1) td { vertical-align:bottom; text-align:center}
<table>
<tr>
<td><p class=tall>.</td>
<td><p class=short>.</td>
<td><p class=tall>.</td>
<td><p class=short>.</td>
</tr>

<tr>
<td>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
<td>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
<td>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
<td>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</tr>
</table>

If tables were responsive, I'd use them.

If each item in the container is a image+text combo (one row in the flex), then css can't target and align the image separately because it's tied to the text.

If I use two rows, each one flexed, then it's no longer responsive: on small screens, all the first row items will print, then all the second row items will print, e.g., row1cell1 won't be matched with row1cell2. And on large screens, the columns won't line up because each text block is a different width.

SOLUTIONS:

(1) Is there a way to do it with flexbox?
(2) Is there a way to have tables be responsive?
(3) Could add whitespace to all the short images to make them as tall as the tallest one, which is a pain.

1 Answers1

1

You can consider a trick with baseline alignment. The idea is that the image will define the baseline of each flex item. Then you consider width:0;min-width:100% to have the text equal to the image (How to match width of text to width of dynamically sized image?)

.container {
  display: flex;
  max-width:800px;
  align-items: baseline;
  border:1px solid red;
  flex-wrap:wrap;
}

.container>div {
  margin: 0 5px;
  display:flex;
  flex-direction:column;
  min-width:0;
  flex-grow:1;
}
img {
  width:100%;
}
span {
  width: 0;
  min-width: 100%;
}
<div class="container">
  <div><img src="https://i.picsum.photos/id/1001/100/300.jpg"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</span></div>
  <div><img src="https://i.picsum.photos/id/1001/250/100.jpg"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</span></div>
  <div><img src="https://i.picsum.photos/id/1001/200/200.jpg"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</span></div>
  <div><img src="https://i.picsum.photos/id/1001/200/400.jpg"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</span></div>
</div>

In case you want to center the content isntead:

.container {
  display: flex;
  max-width:800px;
  align-items: baseline;
  justify-content:space-around;
  border:1px solid red;
  flex-wrap:wrap;
}

.container>div {
  margin: 0 5px;
  display:flex;
  flex-direction:column;
  min-width:0;
}
img {
  width:100%;
}
span {
  width: 0;
  min-width: 100%;
}
<div class="container">
  <div><img src="https://i.picsum.photos/id/1001/100/300.jpg"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</span></div>
  <div><img src="https://i.picsum.photos/id/1001/250/100.jpg"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</span></div>
  <div><img src="https://i.picsum.photos/id/1001/200/200.jpg"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</span></div>
  <div><img src="https://i.picsum.photos/id/1001/200/400.jpg"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</span></div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Holy mother of CSS! – Michael Bluejay May 23 '20 at 01:21
  • `display:inline-block` instead of `float` for the span, No ? – Rainbow May 23 '20 at 01:34
  • I'm afraid your solution came with another problem: the columns are way too narrow, they don't fill the horizontal space. I tried removing the width:0; min-width:100% but then each item appears on its own row. – Michael Bluejay May 23 '20 at 01:34
  • @MichaelBluejay flex-grow: 1; on the flex item and width:100% on the image should do it – Temani Afif May 23 '20 at 01:54
  • @ZohirSalak yes, even display:block will work too .. don't know why float came first to my mind. – Temani Afif May 23 '20 at 01:58
  • flew-grow:1 spreads them out, thx! I was trying the wrong commands. • Without enlarging the images, is there a way to center them over the text? I wouldn't think so, but you keep pulling magic out of your bag of tricks. – Michael Bluejay May 23 '20 at 02:41
  • I'm sorry I'm not being clear. I don't want the images to expand horizontally, so I took out the width:100%. But when I do that, the text is limited to the image width. I updated the OP code and image to make it clearer what I'm going for. – Michael Bluejay May 24 '20 at 18:14