Quantcast
Channel: Active questions tagged flexbox - Stack Overflow
Viewing all articles
Browse latest Browse all 1675

CSS flex - stretch or shrink image to fill remaining vertical space but not introduce scrolling

$
0
0

I realize there are other similar sounding questions, but I couldn't find one to help me solve this problem.

--

I am working on a layout of items in CSS and I am trying to achieve the following:

  • Each item is as tall as its content is except one item that contains an image and the image is allowed to grow or shrink to fill the available space.
  • The image is 50% of the width of the viewport and is next to some text content.
  • The image cannot be shorter than the text content (unless it's aspect ratio is such that it is a really wide and short image).
  • The image should grow (proportionally) to fill the remaining vertical space in the visible viewport. If the image cannot be made tall enough to fill the remaining space, then the section the image is in should stretch at least. In the example below, this section has a chartreuse background.
  • The image should not grow so much that it causes scrolling.
  • If the viewport is resized and made shorter, then the image should scale down in size until it is as short as the content next to it.

--

The idea is to make it so that the image section (and the image itself) is scaled to fill any extra vertical space, so there is no blank whitespace vertically in the viewport.

But, at the same time, the goal is to not introduce scrolling if possible. Scrolling should only happen if the image cannot be made any smaller and the image plus the rest of the content is taller than the viewport.

Desired outcomeActual outcome
This is the desired outcome. The blue sections are sections of content that should not shrink or expand and they are correct in both of these pictures. The only section that should expand or shrink is the image (the chartreuse background section). And that section should resize the image in it such that it is at least as tall as the content to its right but no taller than what would cause scrolling. So in this case, the section is sized down to the minimum size, where the image is the same height as the content in the row.Contrast that with the image showing what actually happens. In this image, the blue sections are the correct size but the image is not resizing vertically. It stays the height that it is and when the window is resized, the content starts to scroll instead of the image being resized like it is in the desired outcome image. In this image, instead of overflowing and introducing scrolling, the browser should have shrunk the image proportionally down as much as is necessary, up until the point that it is the same height as the content in the row, and then the content should overflow and the browser should start to scroll.
desiredactual

Here is a gif showing what happens. I am sorry for the quick looping animation.resize gif

--

The following example shows this layout with some sections of content that should not be shrunk. These are the .inner elements that do not have the flexible class.

The element with the .flexible class should be able to expand or shrink as described above to eliminate any unfilled vertical whitespace but also to prevent unnecessary scrolling (this section should be made as small as possible before scrolling starts).

Is it possible to do this with a CSS-only approach? I am not able to get the image to resize when I resize the viewport.

JSFiddle

Note The snippet below is best viewed in its own browser window. Please see the JSFiddle for a better example - https://jsfiddle.net/nt0785p3/.

The idea with this is that the image should be as short as the text next to it up until the browser window is tall enough to show all of the sections without scrolling. Once the browser window is taller than all the sections, then the image should start vertically expanding (proportionally) until it cannot get any taller (without becoming wider than 50% of the viewport). At that point, the green background behind the image section should just fill the remaining vertical space.

  .outer {    border: 1px solid black;    height: 70vh;    overflow-y: scroll;    display: flex;    flex-direction: column;    align-items: stretch;    gap: 8px;  }  .inner.flexible {    flex: 1;    border: 1px dashed blue;  }  .inner {    padding: 8px;    border: 1px solid blue;    background-color: lightblue;  }  .inner.image-container {    display: flex;    flex-direction: row;    align-items: center;    gap: 8px;    border: 1px solid orange;    background-color: chartreuse;  }  .inner.image-container > .image img {    max-width: 100%;    max-height: 100%;    min-width: 0;    min-height: 0;    object-fit: contain;  }  .inner.image-container > .content {    width: 50%;  }
<div class="outer"><div class="inner"><p>The first section 1</p><p>The first section 2</p></div><div class="inner"><p>The second section 1</p><p>The second section 2</p></div><div class="inner image-container flexible"><div class="image"><img src="https://m.media-amazon.com/images/I/71QHUI7yiUL._AC_SX679_.jpg" /></div><div class="content"><p>Descriptive content goes here</p><p>The image should not shrink shorter than this</p><p>But the image might be taller than this if there is extra vertical space in the viewport.</p><p>Basically, the image should be at least as tall as this text but not so large that it causes scrolling. It should shrink, if necessary, to reduce the need for scrolling.</p></div></div><div class="inner">The third section</div><div class="inner">The fourth section</div><div class="inner">The fifth section</div><div class="inner">The sixth section</div><div class="inner">The seventh section</div></div>

Viewing all articles
Browse latest Browse all 1675

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>