CSS scale several images to fit viewport keeping aspect ratio

MindOverflow picture MindOverflow · Apr 16, 2014 · Viewed 46.1k times · Source

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.

Answer

web-tiki picture web-tiki · Apr 16, 2014

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.