0

In this JSFiddle how can I downsize the img / img-container to be only as wide as its widest sibling div?

.outer {
  display: inline-flex;
  flex-flow: column;
}

.outer span {
  display: flex;
}

div {
  border: 1px dotted black;
}
<div class="outer">
  <div>
    <span>text</span>
    <span>more text</span>
  </div>
  
  <div>
    <img src="https://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon@2.png?v=73d79a89bded">
  </div>
  
  <div>
     <span>this should determine width</span>
  </div>
</div>
Paulie_D
  • 107,962
  • 13
  • 142
  • 161
user2651804
  • 1,464
  • 4
  • 22
  • 45
  • Using `width: 100%; max-width: 100%;` on the image will scale it to fit its container, in this case the div, which will automatically expand to match the width of its siblings. – Wild Beard Feb 16 '18 at 15:55
  • Related but NOT dupe - https://stackoverflow.com/questions/48830306/how-can-i-shrink-a-img-to-fit-its-flex-container – Paulie_D Feb 16 '18 at 15:59
  • @WildBeard Have you tried it? I can't make it work – user2651804 Feb 16 '18 at 16:24

4 Answers4

1

You can do this with CSS table layout and set width: 1% on table and white-space: nowrap on text elements.

.outer {
  display: table;
  width: 1%;
}
.outer span {
  white-space: nowrap;
}
div {
  border: 1px dotted black;
}
img {
  max-width: 100%;
}
<div class="outer">
  <div><span>text</span><span>more text</span></div>
  <div class="image">
    <img src="https://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon@2.png?v=73d79a89bded">
  </div>
  <div><span>this should determine width</span></div>
</div>
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
  • This is nice, except for one detail :/ The only deviation from the JSFiddle and my actual application need is that the last div width is determined by an image, not a span. The span text needs to wrap in the first division. – user2651804 Feb 16 '18 at 16:48
1

As you asked about it for flexbox layout particularly, here is trick playing with pseudo and positions. Note, it only works if you know the image aspect ratio already, example below for a square image.

div {
  border: 1px dotted black;
}

.outer {
  display: inline-flex;
  flex-flow: column;
}

.image {
  position: relative;
}

.image:before {
  content: "";
  display: block;
  padding-top: 100%;
  /*https://stackoverflow.com/a/10441480/483779*/
}

.image img {
  position: absolute;
  left: 0;
  top: 0;
  max-width: 100%;
}
<div class="outer">
  <div class="image">
    <img src="https://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon@2.png?v=73d79a89bded">
  </div>
  <div>this should determine width</div>
</div>
Stickers
  • 75,527
  • 23
  • 147
  • 186
1

I'm not sure how cross-browser compatible this solution is, but it works on Chrome 64, Safari 11, and Firefox 57.

Give the element containing the img a width: 0; min-width: 100%; max-width: 100%;, and the img itself a width: 100%;.

Like this:

div {
  border: 1px dotted black;
}

.outer {
  display: inline-flex;
  flex-flow: column wrap;
}

.child {
  width: 0;
  min-width: 100%;
  max-width: 100%;
}

.img {
  width: 100%;
}
<div class="outer">
  <div>
    <span>text</span>
    <span>more text</span>
  </div>
  
  <div class="child">
    <img class="img" src="https://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon@2.png?v=73d79a89bded" />
  </div>
  
  <div class="main">
     <span contenteditable>this should determine width</span>
  </div>
</div>

Another Solution

Use a background-image instead of an img. This allows us to make the image scale with the width of the widest element in the flexbox.

The trick is to set a padding-bottom on the element with the image proportional to the image proportions. In this case the image is square, so I'll set `padding-bottom: 100%; so it creates a square element.

If the image was a wide rectangle, 200 x 100 px, I would set padding-bottom: 50%. Or, if the image was a tall rectangle, 100 x 200 px, I would set padding-bottom: 200%.

Like this:

div {
  border: 1px dotted black;
}

.outer {
  display: inline-flex;
  flex-flow: column wrap;
}

.img {
  background-image: url(https://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon@2.png?v=73d79a89bded);
  background-repeat: no-repeat;
  background-size: cover;
  padding-bottom: 100%;
}
<div class="outer">
  <div>
    <span>text</span>
    <span>more text</span>
  </div>
  
  <div class="img">
  </div>
  
  <div>
     <span contenteditable>this should determine width</span>
  </div>
</div>
Brett DeWoody
  • 59,771
  • 29
  • 135
  • 184
-1

Your CSS container is already as wide as its widest sibling div. You just need to shrink the border of the picture with paint or photoshop.

Vicoco
  • 1