1

I was wondering if the layout I draw on the following image is possible using flexbox and this HTML structure:

<div class="box">
    <img src="url..." alt="" />
    <h5>Lorem Ipsum</h5>
    <p>Lorem Ipsum Dolor Sit Amet...</p>
</div>

It would be great if this could be done with flexbox and without adding more boxes inside.

Flexbox Layout

MyXoToD
  • 620
  • 5
  • 13
  • If the height of the `.box` is known, yes but other than that, no, not really. – Paulie_D Sep 01 '16 at 11:14
  • Why flexbox? Float the image to the left or right –  Sep 01 '16 at 11:22
  • If you want the image responsive at all, you'd be well advised to wrap it in a div too. – Paulie_D Sep 01 '16 at 11:24
  • @blonfu sure you can get this solution in many ways but I was looking for a way to do it with the given structure using flexbox. – MyXoToD Sep 07 '16 at 10:43
  • I was just curious of reason to use flexbox instead of any other technique –  Sep 07 '16 at 10:46
  • Well it's a valid question but since I use flexbox a lot the recent weeks I'm always wondering what is possible with it. I give it a try and if I can't succeed but not sure if it would work somehow I drop a question to other developers. – MyXoToD Sep 07 '16 at 10:59

1 Answers1

1

For fixed image width and height, it's possible. The main idea is in the following snippet.

.box {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  align-content: space-between;
  height: 300px;
}

.img {
    width: 300px; height: 300px;
}

h5, p {
  /* 100% - image width - margin between */
  width: calc(100% - 300px - 16px); 
}

Since the height of the parent is the same as the height of the image, the content overflows and gets wrapped to the right. Then we have to manually set the width because it's otherwise going to 100% of the parent.

.box {
  background-color: #ddd;
  padding: 16px;
  margin-bottom: 24px;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  height: 300px;
  align-content: space-between;
}

.img {
  background-color: #333;
  color: #ddd;
  width: 300px;
  height: 300px;
}

h5, p {
  padding: 0;
  margin: 0;
  background-color: #ccc;
  /* 100% - image width - margin between */
  width: calc(100% - 300px - 16px); 
}

h5 {
  font-size: 18px;
  margin-bottom: 8px;
}

.box:nth-child(even) .img {
  order: 3;
}
<div class="box">
    <div class="img">&lt;img&gt;</div>
    <h5>Lorem Ipsum</h5>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mollis cursus hendrerit. Suspendisse potenti. Aliquam posuere ex ut lacus euismod dictum. Proin et ligula posuere leo viverra tempor a in tellus</p>
</div>

<div class="box">
    <div class="img">&lt;img&gt;</div>
    <h5>Lorem Ipsum</h5>
    <p>Lorem Ipsum Dolor Sit Amet...</p>
</div>

<div class="box">
    <div class="img">&lt;img&gt;</div>
    <h5>Lorem Ipsum</h5>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mollis cursus hendrerit. Suspendisse potenti. Aliquam posuere ex ut lacus euismod dictum. Proin et ligula posuere leo viverra tempor a  </p>
</div>

Full-height paragraph

You might want to extend your paragraph all the way to the bottom (maybe add some links there). It's easy to extend it so you can turn p into flexbox to snap something to the bottom, for example (this example not in the demo below, you can only notice this by the gray background).

.box {
  /* ... */
  justify-content: space-between;
}

p {
  flex-grow: 1;
}

.box {
  background-color: #ddd;
  padding: 16px;
  margin-bottom: 24px;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  height: 300px;
  align-content: space-between;
  justify-content: space-between;
}

.img {
  background-color: #333;
  color: #ddd;
  width: 300px;
  height: 300px;
}

h5, p {
  padding: 0;
  margin: 0;
  background-color: #ccc;
  /* 100% - image width - margin between */
  width: calc(100% - 300px - 16px); 
}

h5 {
  font-size: 18px;
  margin-bottom: 8px;
}

p {
  flex-grow: 1;
}

.box:nth-child(even) .img {
  order: 3;
}
<div class="box">
    <div class="img">&lt;img&gt;</div>
    <h5>Version 2</h5>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mollis cursus hendrerit. Suspendisse potenti. Aliquam posuere ex ut lacus euismod dictum. Proin et ligula posuere leo viverra tempor a in tellus</p>
</div>

<div class="box">
    <div class="img">&lt;img&gt;</div>
    <h5>Lorem Ipsum</h5>
    <p>Lorem Ipsum Dolor Sit Amet...</p>
</div>

<div class="box">
    <div class="img">&lt;img&gt;</div>
    <h5>Lorem Ipsum</h5>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mollis cursus hendrerit. Suspendisse potenti. Aliquam posuere ex ut lacus euismod dictum. Proin et ligula posuere leo viverra tempor a in tellus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mollis cursus hendrerit. Suspendisse potenti. </p>
</div>

Both versions above breaks when the text cannot fit (try changing browser window size).

Doesn't show all, but never breaks

You can set the max-height for the paragraph if you don't want it to break and clip the text which cannot fit with overflow: hidden.

p {
  max-height: 250px;
  overflow: hidden;
}

.box {
  background-color: #ddd;
  padding: 16px;
  margin-bottom: 24px;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  height: 300px;
  align-content: space-between;
  justify-content: space-between;
}

.img {
  background-color: #333;
  color: #ddd;
  width: 300px;
  height: 300px;
}

h5, p {
  padding: 0;
  margin: 0;
  background-color: #ccc;
  /* 100% - image width - margin between */
  width: calc(100% - 300px - 16px); 
}

h5 {
  font-size: 18px;
  margin-bottom: 8px;
}

p {
  flex-grow: 1;
}

.box:nth-child(even) .img {
  order: 3;
}

p {
  max-height: 250px;
  overflow: hidden;
}
<div class="box">
    <div class="img">&lt;img&gt;</div>
    <h5>Version 3</h5>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mollis cursus hendrerit. Suspendisse potenti. Aliquam posuere ex ut lacus euismod dictum. Proin et ligula posuere leo viverra tempor a in tellus</p>
</div>

<div class="box">
    <div class="img">&lt;img&gt;</div>
    <h5>Lorem Ipsum</h5>
    <p>Lorem Ipsum Dolor Sit Amet...</p>
</div>

<div class="box">
    <div class="img">&lt;img&gt;</div>
    <h5>Lorem Ipsum</h5>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mollis cursus hendrerit. Suspendisse potenti. Aliquam posuere ex ut lacus euismod dictum. Proin et ligula posuere leo viverra tempor a in tellus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mollis cursus hendrerit. Suspendisse potenti. Aliquam posuere ex ut lacus euismod dictum. Proin et ligula posuere leo viverra tempor a in tellus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mollis cursus hendrerit. Suspendisse potenti. Aliquam posuere ex ut lacus euismod dictum. Proin et ligula posuere leo viverra tempor a in tellus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mollis cursus hendrerit. Suspendisse potenti. Aliquam posuere ex ut lacus euismod dictum. Proin et ligula posuere leo viverra tempor a in tellus. </p>
</div>
Lazar Ljubenović
  • 18,976
  • 10
  • 56
  • 91
  • Thanks for your detailed answer. Not exactly what would work for me but good to know, that this could be a solution. – MyXoToD Sep 07 '16 at 10:44
  • You could also float images left and right, and keep the rest flowing the usual way. But since you asked for flexbox, I didn't wanna cheat. – Lazar Ljubenović Sep 07 '16 at 10:46