How to make images fluid width after changing their dimensions?

111 Views Asked by At

The snippet shows two groups of images in flexbox. The first is images at their original resolution that have a fluid layout. They each take up 1/3 of the width of the screen, and resize properly when you change the width of the screen so that at any time the first row has exactly 3 images.

The second group of images are cropped to a certain dimension (removing equal amounts from the top and bottom of the image and leaving the middle part). This unfortunately isn't a fluid layout. It's stuck at the hardcoded 200px amount. The first row can have 1, 2 or 3 images depending on the width of the screen.

How can I combine the two things? So the images get cropped like in the second set of images, but have a fluid layout like the first set of images and each row has exactly 3 images scaled to the right size?

.container1 {
  width: 33.33%;
  overflow: hidden;
}

.container1 img {
  max-width: 100%;
}

.container2 {
  width: 200px;
  height: 200px;
  overflow: hidden;
}

.container2 img {
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}
<h1>original img</h1>
<div>
  <img src="https://picsum.photos/200/300" />
</div>
<h1>fluid layout</h1>
<div style="display:flex;flex-wrap:wrap">
  <div class="container1">
    <img src="https://picsum.photos/200/300" />
    img 1
  </div>
  <div class="container1">
    <img src="https://picsum.photos/200/300" />
    img 2
  </div>
  <div class="container1">
    <img src="https://picsum.photos/200/300" />
    img 3
  </div>
  <div class="container1">
    <img src="https://picsum.photos/200/300" />
    img 4
  </div>
</div>
<h1>resized images</h1>
<div style="display:flex;flex-wrap:wrap">
  <div class="container2">
    <img src="https://picsum.photos/200/300" />
    img 1
  </div>
  <div class="container2">
    <img src="https://picsum.photos/200/300" />
    img 2
  </div>
  <div class="container2">
    <img src="https://picsum.photos/200/300" />
    img 3
  </div>
  <div class="container2">
    <img src="https://picsum.photos/200/300" />
    img 4
  </div>
</div>

1

There are 1 best solutions below

6
T J On

Use CSS Grid for the second case, this allows you to explicitly mention how many columns you want per row:

.grid-parent {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.flex-parent {
  display: flex;
  flex-wrap: wrap
}

.flex-item {
  width: 33.33%;
  overflow: hidden;
}

.flex-item img {
  max-width: 100%;
}

.grid-parent {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.grid-item {
  overflow: hidden;
}

.grid-item img {
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}
<h1>original img</h1>
<div>
  <img src="https://picsum.photos/200/300" />
</div>
<h1>fluid layout</h1>
<div class="flex-parent">
  <div class="flex-item">
    <img src="https://picsum.photos/200/300" /> img 1
  </div>
  <div class="flex-item">
    <img src="https://picsum.photos/200/300" /> img 2
  </div>
  <div class="flex-item">
    <img src="https://picsum.photos/200/300" /> img 3
  </div>
  <div class="flex-item">
    <img src="https://picsum.photos/200/300" /> img 4
  </div>
</div>
<h1>resized images</h1>
<div class="grid-parent">
  <div class="grid-item">
    <img src="https://picsum.photos/200/300" /> img 1
  </div>
  <div class="grid-item">
    <img src="https://picsum.photos/200/300" /> img 2
  </div>
  <div class="grid-item">
    <img src="https://picsum.photos/200/300" /> img 3
  </div>
  <div class="grid-item">
    <img src="https://picsum.photos/200/300" /> img 4
  </div>
</div>