1

I'd like to know how to shrink a row of images so that they all fit within a div with an unspecified height. The images should never scale up beyond their native height, and they must maintain their aspect ratio. Also, I'd like the height of the containing div to be limited to the native height of the tallest image. The image tags have no height or width attributes.

Here's a fiddle with what I have so far. I approached this using flexbox and object-fit: scale-down. The row of images in question are gray and are in the div with the green background. They currently do not scale at all, but they are at least centered vertically and horizontally how I'd like them to be. Here are before and after images of the effect I'd like to achieve (sorry for switching the green background to yellow in the images). Additional details below the code snippet, but that about sums up the basic question.

body {
    font-family: arial;
    font-size: 26px;
    text-align: center;
    color: black;
    background-color: white;
}

.smallhint {
  font-size: 16px;
  color: #8c8c8c;
}

img {
    padding: 0;
    margin: 0;
    font-size: 0;
    display: block;
    object-fit: scale-down;
    min-height: 0;
}

.flex-column {
    display: flex;
    flex-direction: column;
    padding: 0px;
    margin: 0px;
    height: 90vh;
    flex-grow: 0;
    min-width: 0;
    min-height: 0;
}

.flex-row {
    display: flex;
    flex-direction: row;
    flex: 0 1.5 auto;
    justify-content: center;
    align-items: center;
    background-color: green;
}

.context {
    display: flex;
    flex-direction: column;
    max-height: 100%;
  background-color: blue;
}

.primary {
    position: relative;
    z-index: 0;
    right: 0;
    bottom: 0;
    padding: 0;
    font-size: 0;
    min-height: 0;
    align-items: end;
    background-color: orange;
}

.primary img {
    margin-left: auto;
    margin-right: auto;
    border-style: solid;
    border-width: 3px;
    border-color: black;
    height: calc(100% - 2*3px);
}

.mask {
    position: absolute;
    z-index: 1;
    top: 0;
    right: 0;
    width: 100%;
    height: 100%;
    font-size: 0;
}

.nonimage {
    padding-top: 5px;
    display: inline;
  background-color: pink;
}
<div class="flex-column">

    <div class="primary">
    <img src="https://via.placeholder.com/200">
        <div class="mask">
      <img src="https://via.placeholder.com/200/FF000">
    </div>
    </div>

    <div class="flex-row">
    <div class="context">
      <img src="https://via.placeholder.com/75x150">
    </div>
    <div class="context">
      <img src="https://via.placeholder.com/150x75">
    </div>
    </div>

    <div class="nonimage">
        <div class="smallhint">Some Text<br>Other Text</div>
    </div>

</div>

I'm working on a (fixed-height) interface styled with CSS and will likely be asking a series of questions. I'm not great at CSS, so I'm open to approaches that are very different from my failed attempt!

At the top is a single centered image ("primary image"), below that are two other images ("secondary images") in a row, and below that is some text. Eventually, I'd like both sets of images to be responsive to changes in the height and width of the browser. However, I'd like to preferentially scale down the secondary images more than the primary image when the browser is too short to contain everything at native dimensions. For this, it seemed like flexbox containers with various flex-grow values would work here; it seems to work with the primary image somewhat, but the secondary images refuse to scale.

Also, I'm aware that, even if my current approach worked, the object-fit: scale-down strategy would leave behind some unwanted "padding" that will result in visual space between the secondary images. I have a feeling a very different approach may be required to get the effect that I want in the end, since I want the images to sit adjacent to each other without extra space around them. Furthermore, there also seems to be an issue with the container itself when the browser becomes very thin, since a scrollbar appears but it should always be 90vh.

Thank you all for the input!

ratburger
  • 21
  • 4
  • your question is kinda vague, difficult to see what you're trying to achieve. However did you try the flex-wrap property? – Samakaab Aug 03 '20 at 04:39
  • Is there a particular part that is very unclear to you? I could be too close to the problem to realize it's not clear. Were the images I provided useful? As for flex-wrap: I do not want the images to wrap, so I left this as the default "nowrap." Thanks for your time. – ratburger Aug 03 '20 at 06:09
  • Nope exactly. Can you share what the end product would look like? – Samakaab Aug 03 '20 at 11:51
  • Here are [before](https://i.stack.imgur.com/sCvmv.png) and [after](https://i.stack.imgur.com/CqJaK.png) images of the end product. Before, all images are at native dimensions because the browser height is tall enough to fit everything. After, the browser height is reduced. This causes the divs that contain images to shrink in height. For the row of "secondary" images (yellow background) this forces the portrait image (left) to shrink while maintaining its aspect ratio. The landscape image (right) just barely fits the div, so it does not have to shrink in this example. Thanks again. – ratburger Aug 03 '20 at 17:02

1 Answers1

0

Add a min-height: 0; rule for .flex-row. I guess that means it was pretty close to working when I asked the question.

This solution retains the issue I mention in my question about the additional "padding" created around images when object-fit: scale-down (or cover) is used. So, that means I'll be asking another question about that topic!

ratburger
  • 21
  • 4