2

I'm currently working on my blog where I am trying to fit all Images into a 1:1 Ratio, which works great for images where the height is larger than the width. Well on the other hand it also works "well" with images where the width is bigger. But the main problem I have is that the images with a bigger width don't need to be fit in into the 1:1 ratio as this would align the description below better.

This works fine The Text should be aligned

How can I fix this? (Please find my code below):

CSS:

.img-container {
    background: transparent;
    position: relative;
    width: 100%;
}

.img-container:after {
    content: "";
    display: block;
    padding-bottom: 100%;
}

.img-container img {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: center;
    cursor: pointer;
}

HTML:

<div class="img-container">
<img src="xxx"/>
</div>

Thank you in advance!

brox
  • 53
  • 7
  • So if I understood well, you don't want the blank space between the 2nd image and "Movie Title", that's it? The ratio isn't responsible of this fyi – underflow Mar 03 '23 at 17:28
  • @underflow It is. The white space is a result of giving a horizontal image a 1:1 `aspect-ratio` value. – Mikhail Batcer Mar 10 '23 at 10:45

6 Answers6

0

object-fit: cover; will adjust the size of the image.

Hardik
  • 106
  • 9
0

I'm solving the same problem.

The only non-js solution I have working so far is to use vw units for max-height. But for it to work consistently you may need parent elements to have width based on viewport width too, so you have a value needed. In my example it's 55.

.img-container img {
    width: 55vw;
    height: auto;
    max-height: 55vw;
    object-fit: contain;
    object-position: center center;
}
Mikhail Batcer
  • 1,938
  • 7
  • 37
  • 57
0

You can modify your CSS by specifying a maximum height for the container dependent on the width of the picture to get your desired layout where photos with a wider width don't need to be squeezed into a 1:1 ratio.

.img-container {
  background: transparent;
  position: relative;
  width: 100%;
}

.img-container:after {
  content: "";
  display: block;
  padding-bottom: 100%;
}

.img-container img {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  cursor: pointer;
  max-height: calc(100vw - 40px); /* set max-height based on the width of the image */
}

/* additional stuff */    
@media only screen and (min-width: 768px) {
  .img-container img {
    max-height: calc((100vw - 80px) / 2); /* set a smaller max-height for larger screens */
  }
}

The img element in this code has a max-height attribute that is set to calc (100vw - 40px). This determines the image's maximum height depending on the viewport's width minus a little margin of 40 pixels. With their original aspect ratio preserved, this prevents photos with a wider width from being cropped to match a 1:1 aspect ratio.

For a responsive site:

To adapt the max-height property for wider screens, I also included a media query. This query lowers the maximum height for larger screens to better match the image and the information below it by setting the max-height to calc((100vw - 80px) / 2).

To create the layout you want, you can change the values of the media query and the max-height property as necessary.

Muzammil-cyber
  • 141
  • 1
  • 7
0

you can do something like that (you need to have an additional container)

.demo-wrapper {
  width: 660px;
  margin: 0 auto;
}

.img-container {
  width: 100%;
  padding-bottom: 100%;
  position: relative;
  overflow: hidden;
}

.inner {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
  }
  
img {
    object-fit: cover;
    width: 100%;
    min-height: 100%;
}
<div class="demo-wrapper">
  <div class="img-container">
    <div class='inner'>
      <img src="https://thumbs.dreamstime.com/b/beautiful-rain-forest-ang-ka-nature-trail-doi-inthanon-national-park-thailand-36703721.jpg"/>
    </div>
  </div>
  <div>Title 1</div>


  <div class="img-container">
    <div class='inner'>
      <img src="https://thumbs.dreamstime.com/b/walking-path-rain-forest-doi-intanon-nationalpark-chiang-mai-thailand-daylight-mountain-walking-path-rain-forest-doi-148937950.jpg"/>
    </div>
  </div>
  <div>Title 2</div>
</div>
  • This doesn't keep images intact, but fits every image to a square by cropping with `object-fit: cover`. – Mikhail Batcer Mar 10 '23 at 14:35
  • Looks like your idea is a little bit different than "fit all Images into a 1:1 Ratio". If you don't want any space between the horizontal image and the title after that, that means that image will not be (visually) inside any 1:1 ratio box – that will be just image and title after that. Can you pls help me to understand the idea about how it could be in 1:1 ratio and not crop image, and not have any space after that – and i will be happy to help! – lastcallofsummer Mar 12 '23 at 21:49
  • `the images with a bigger width don't need to be fit in into the 1:1 ratio` - this is from the question. And the question is how to `set the max-height same as width`. – Mikhail Batcer Mar 13 '23 at 08:11
  • You want to set all images max-height as a parent container width? That is all? – lastcallofsummer Mar 13 '23 at 19:16
  • Yes. That would solve the problem. – Mikhail Batcer Mar 14 '23 at 05:45
  • Can you use any js? – lastcallofsummer Mar 15 '23 at 12:01
0

Here is my solution using the same exact HTML you have. The container will adjust its height and width based on its child image height. Whether it's portrait or landscape, the container will follow the height of the image. If it's portrait, it won't crop anything (just like how object-fit: contain behaves), and if it's landscape, it will take the middle 1:1 of the image (just like how object-fit: cover behaves).

So in a way, this is like object-fit: contain for portrait image, but object-fit: cover for landscape image:

.img-container {
  background: transparent;
  position: relative;
  width: 100%;
  overflow: hidden;
}

.img-container:after {
  content: "";
  display: block;
  padding-bottom: 100%;
}

.img-container img {
  position: absolute;
  height: 100%;
  left: 50%;
  transform: translate(-50%, 0);
}
<h1>portrait</h1>
<div class="img-container">
  <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/85/Tour_Eiffel_Wikimedia_Commons_%28cropped%29.jpg/640px-Tour_Eiffel_Wikimedia_Commons_%28cropped%29.jpg">
</div>
<h1>landscape</h1>
<div class="img-container">
  <img src="https://upload.wikimedia.org/wikipedia/commons/5/57/Cumulus_Clouds_over_Yellow_Prairie2.jpg">
</div>

The only drawback I could think of when using this is that you need to specify max width for the outer container since it has a 100% width.

Damzaky
  • 6,073
  • 2
  • 11
  • 16
0

I'm handling the same issue using aspect-ratio and object-fit: cover;.

It is also possible to use object-fit: fill; however, this will stretch the image.

Hope this helps.

CSS:

.img-container {
    background: transparent;
    aspect-ratio: 1/1;
}

.img-container img {
    aspect-ratio: 1/1;
    object-fit: fill;
    width: 100%;
}

HTML:

  <div class="img-container">
    <img src="https://picsum.photos/seed/picsum/700/600" />
  </div>
  <h4>Movie Title</h4>