15

Please see this codepen: https://codepen.io/allen-houng/pen/XGMjMr?editors=1100#0

    <div>
      <img src="https://res.cloudinary.com/djcpf0lmv/image/upload/v1549372650/Templates/yoga.jpg" data-radium="true" style=";">
      <div class="description">
        Fusce consequat. Nulla nisl. Nunc nisl. Duis bibendum, felis sed interdum   venenatis, turpis enim blandit mi, in porttitor pede justo eu massa. Donec dapibus. Duis at velit eu est congue elementum.
      </div>
    </div>

I have a parent div with two child divs - an image and a description. I'm sizing the image according to viewport height which means the width would be dynamic and responsive. How would I size the corresponding sibling div .description to match the image's width without javascript?

In other words, how do I turn this: enter image description here

into this: enter image description here

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Allen
  • 3,601
  • 10
  • 40
  • 59

2 Answers2

44

Make the container inline-block (or any shrink-to-fit configuration like table,inline-grid,inline-flex, float,absolute etc) then force the width of text to be 0 so the width of the container is defined by the image (the text doesn't contribute to the width) then force the width again to be 100% using min-width

.parent {
  background: pink;
  display:inline-block;
}

img {
  display: block;
  max-height: 70vh;
}

.description {
  width:0;
  min-width:100%;
}
<div class="parent">
    <img src="https://picsum.photos/id/1004/900/600">
  <div class="description">
    Fusce consequat. Nulla nisl. Nunc nisl. Duis bibendum, felis sed interdum   venenatis, turpis enim blandit mi, in porttitor pede justo eu massa. Donec dapibus. Duis at velit eu est congue elementum.
  </div>
</div>

The same trick work even without image where you need any element to be sized based on another one.

Example with text defining the size of another text:

.parent {
  background: pink;
  display:inline-block;
}

.description {
  width:0;
  min-width:100%;
}
<div class="parent">
   <h2>a title that will define the width</h2>
  <div class="description">
    Fusce consequat. Nulla nisl. Nunc nisl. Duis bibendum, felis sed interdum   venenatis, turpis enim blandit mi, in porttitor pede justo eu massa. Donec dapibus. Duis at velit eu est congue elementum.
  </div>
</div>

Example with text defining the size of the image (the opposite of the first snippet)

.parent {
  background: pink;
  display:inline-block;
}

img {
  width:0;
  min-width:100%;
}
<div class="parent">
    <img src="https://picsum.photos/id/1004/900/600">
   <h2>a title that will define the width</h2>
</div>

<div class="parent">
    <img src="https://picsum.photos/id/1004/900/600">
   <h2>define the width</h2>
</div>

<div class="parent">
    <img src="https://picsum.photos/id/1004/900/600">
   <h2>very small</h2>
</div>

It can also work with complex structure.

Example using CSS grid:

.container {
  display: inline-grid;
  border: 1px solid;
  grid-template-columns: auto auto;
}
.container > div {
  padding:2px;
  border:1px solid green;
}
.auto {
  grid-column:1/-1;
  width:0;
  min-width:100%;
}
<div class="container">
  <div>some text here</div>
  <div>and here</div>
  <img src="https://picsum.photos/id/1004/900/600" class="auto">
</div>
<br>

<div class="container">
  <div>some text here</div>
  <div>and a long one here</div>
  <p class="auto">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis ornare lacus at nisi laoreet, a fermentum augue vestibulum. Cras convallis ultrices quam, ac fermentum nibh posuere eu. Cras in pellentesque lorem. In et condimentum justo. Phasellus scelerisque nisi vitae vestibulum volutpat. Duis sit amet augue </p>
</div>

another one with table:

table {
  display: table;
  border:1px solid green;
}

td {
  padding: 5px;
  text-align: center;
  border:1px solid green;
}

.auto {
  width: 0;
  min-width: 100%;
  display: block;
}
<table>
  <tr>
    <td>text </td>
    <td>more text</td>
    <td>A</td>
  </tr>
  <tr>
    <td colspan="3"><img src="https://picsum.photos/id/1004/900/600" class="auto"></td>
  </tr>
</table>

<table>
  <tr>
    <td>long text here</td>
    <td>more text</td>
    <td>AAAAAAAA</td>
  </tr>
  <tr>
    <td colspan="3"><p class="auto">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis ornare lacus at nisi laoreet, a fermentum augue vestibulum. Cras convallis ultrices quam, ac fermentum nibh posuere eu. Cras in pellentesque lorem. In et condimentum justo. Phasellus scelerisque nisi vitae vestibulum volutpat. Duis sit amet augue </p></td>
  </tr>
</table>

We can also use contain: size that will do the same job as width:0; min-width:100%;

.parent {
  background: pink;
  display: inline-block;
}

img {
  display: block;
  max-height: 70vh;
}

.description {
  contain: size;
}
<div class="parent">
  <img src="https://picsum.photos/id/1004/900/600">
  <div class="description">
    Fusce consequat. Nulla nisl. Nunc nisl. Duis bibendum, felis sed interdum venenatis, turpis enim blandit mi, in porttitor pede justo eu massa. Donec dapibus. Duis at velit eu est congue elementum.
  </div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • 2
    @NihalChandwani and maybe one day you will need the column direction so check this: https://stackoverflow.com/a/48943583/8620333 similar trick ;) – Temani Afif Apr 12 '21 at 18:30
  • While this technical works, this is not a clean / professional solution. It will cause the page to have visual jumps when its loaded, as the caption will go from width 0 to width 100%, changing the layout of the page as it does so. Really unclean. – user18490 Oct 09 '22 at 12:35
  • @user18490 the answer box is down below, give us a clean and professional solution ;) – Temani Afif Oct 09 '22 at 13:42
  • I don't necessarily have one. Just say this is a hack. Though I had this problem with figure/figcaption ([see my post on SOF](https://stackoverflow.com/questions/73948207/figcaption-to-take-the-width-of-the-image-it-is-associated-with-within-a-figure)) and someone said this question was answered in this post. Which I disagree. Making the widht: 0 then min-width: 100% is awful because it creates a visual jump when you load the page. I offered a solution in my own question since no one was able to help with something clean & pro) – user18490 Oct 09 '22 at 17:46
  • @user18490 your solution is as awful as mine because it will also create a visual jump and we don't add answers inside questions, they need to remain *question* – Temani Afif Oct 09 '22 at 18:39
0

You can simply set the width to be 100% on your image. Just add 'width: 100%;' into your img style tag to test, like so:

<div>
  <img src="https://res.cloudinary.com/djcpf0lmv/image/upload/v1549372650/Templates/yoga.jpg" data-radium="true" style="width: 100%;">
  <div class="description">
    Fusce consequat. Nulla nisl. Nunc nisl. Duis bibendum, felis sed interdum venenatis, turpis enim blandit mi, in porttitor pede justo eu massa. Donec dapibus. Duis at velit eu est congue elementum.
  </div>
</div>

Or make it into a class :

.img-full {
  display: block;
  width: 100%;
}
<div>
  <img src="https://res.cloudinary.com/djcpf0lmv/image/upload/v1549372650/Templates/yoga.jpg" data-radium="true" class="img-full">
  <div class="description">
    Fusce consequat. Nulla nisl. Nunc nisl. Duis bibendum, felis sed interdum venenatis, turpis enim blandit mi, in porttitor pede justo eu massa. Donec dapibus. Duis at velit eu est congue elementum.
  </div>
</div>

The "display: block" just ensures your img is always in it's own block, regardless of width. i.e. your text won't appear next to it, only under or above it.

cmprogram
  • 1,854
  • 2
  • 13
  • 25
  • setting the width to 100% stretches the image out since im sizing it based on viewport height – Allen Mar 07 '19 at 09:33
  • Well then the answer is that unless you do it statically, you can't have both. If your images differ, you can either set height to 100% or width to 100%. Your css isn't going to re-create an image with a different resolution to suit. – cmprogram Mar 07 '19 at 09:35
  • @cmprogram Not true, you can use media queries. – Xavier Oct 27 '19 at 22:05
  • @Xavier That does not change the image resolution, it stretches or squashes the image per the screens resolution. – cmprogram Oct 28 '19 at 09:05
  • @cmprogram Sorry I meant using queries in a different way. By checking the orientation of the viewport, you can choose whether to use `height:100%`; or `width:100%`;. If you use `height:100%`;, set the width to `auto`, or vise-versa. – Xavier Nov 17 '19 at 19:58
  • @cmprogram oops I was thinking of a different problem, sorry. Although I still think you could use a query to check the orientation of the parent wrapper and then set the appropriate dimension property with the other set to auto. – Xavier Nov 17 '19 at 20:07
  • @cmprogram ... and if you can't query the wrapper, then just set the wrapper to be a percentage of the viewport, then you can use the query on the viewport and get the desired results. – Xavier Nov 17 '19 at 20:09