CSS scale several images to fit viewport keeping aspect ratio
Asked Answered
B

3

25

I'm creating a gallery where I want to list all images from an album on one page : Big Picture style :

Unlike Big Picture, I want the images to proportionally scale to fit to the width of the container div (.section-images, which is set to margin: auto 2em; so its width is the width of the user's browser minus 2*2em) as much as possible without making them larger than 90% height of the viewport.

As you imagine, a 400x600 portrait photo when scaled to fit the width would be so long the user would not see the whole image on screen, thats why I need to limit width scaling to not exceed 90% height.

<section class="section-images">
    <div class="image-box">
        <div class="image-large">
            <a href="#"><img foo1></a>
        </div>
        <div class="image-description">
          blabla1
        </div>
        ... MORE IMAGES WITH DESCRIPTONS ...
    </div>
    etc
</section>

Under each image I have the .image-description, the height of this will vary.

What is important is that at any one time a single image (so .image-large) should fit in the viewport, regardless of whether it is landscape or portrait.

I would like to do this using only CSS if possible, and only javascript if CSS is not possible.

Banquer answered 16/4, 2014 at 13:8 Comment(0)
D
35

Solution : (I stripped most of your containers to make it simple to understand and work with)

html,
body,
.section-images {
  height: 100%;
  margin: 0;
}
.section-images {
  margin: auto 2em;
  text-align: center;
}
img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 90%;
  margin: 20px auto;
}
<section class="section-images">
  <a href="#"><img src="http://i.imgur.com/hMRnvUx.jpg" /></a>
  <div class="image-description">blabla3<br/>more blablah<br/>and more blablah</div>
  <a href="#"><img src="http://i.imgur.com/lBuIEDh.jpg" /></a>
  <div class="image-description">blabla2</div>
  <a href="#"><img src="http://i.imgur.com/k8BtMvj.jpgg" /></a>
  <div class="image-description">blabla3<br/>more blablah<br/>and more blablah</div>
</section>

Explanation :

This solution is based on the fact that percentages sizes (width and height) are relative the size of the parent element.

Considering .section-images is a direct child of <body> start by setting :

html, body, .section-images {
    width:100%;
    height:100%;
    margin:0;
}

So the direct parent of the images equals viewport size.

Then, you can size your images easily using :

img{
    width:auto;
    height:auto;
    max-width:100%;
    max-height:90%;
}

Images will never exceed 100% width and 90% height of viewport while keeping their aspect ratio. And they will stay in the flow of the document.

Dormeuse answered 16/4, 2014 at 13:30 Comment(3)
This is exactly what I need but unfortunately I can't get the parent of the child to be the direct child of the body since I'm working with a slider that requires a few div wraps. – Ciracirca
@Dormeuse There are several wraps before it gets to the actual image. So should I apply 100% height to every one of them? – Ciracirca
This was really helpful and fortunately worked exactly for my purpose. I could even use 'calc(100% - 64px) and like such and πŸŽ‰ – Flatwise
J
16

You can also use viewport units to do this without changing html, body for IE9+.

img {
    width:auto;
    height:auto;
    max-width:100%;
    max-height:90vh;
}
Joell answered 7/8, 2015 at 14:23 Comment(0)
E
0

Set the height of the container section-images explicitly, and set its overflow to hidden.

Enate answered 16/4, 2014 at 13:9 Comment(1)
Thank you for responding, however that does not satisfy the requirements. – Banquer

© 2022 - 2024 β€” McMap. All rights reserved.