Rotate and scale image to "fit" container div

Blacksad picture Blacksad · Sep 8, 2015 · Viewed 10.6k times · Source

I'm using transform to rotate an image according to its EXIF data. Then, I'd like to display it "full screen" by fitting it to its parent div.

The problem is, max-width / max-height and all other sizing directives "ignore" the rotation (which is normal, according to transform specs, the element's transformation is "ignored" in the flow.

Jsfiddle: http://jsfiddle.net/puddjm4y/2/

Is there a way to achieve this?

Answer

Salman A picture Salman A · Oct 30, 2018

For full screen display, the simplest solution is to use viewport units to specify width and height of images:

  • Normal image should be 100vw wide and 100vh tall
  • Rotated image should be 100vh wide and 100vw tall

The image could be moved to the middle using CSS transformations. Here is an example, it uses two images that are larger and smaller than the viewport:

body {
  margin: 0;
}
img {
  display: block;
}
img.normal {
  max-width: 100vw;
  max-height: 100vh;
  transform: translatex(calc(50vw - 50%)) translatey(calc(50vh - 50%));
}
img.rotated {
  max-width: 100vh;
  max-height: 100vw;
  transform: translatex(calc(50vw - 50%)) translatey(calc(50vh - 50%)) rotate(90deg);
}
/* demo */
.demo {
  height: 100vh;
  position: relative;
}
.demo:nth-child(odd) {
  background-color: #CCC;
}
.demo:nth-child(even) {
  background-color: #EEE;
}
.demo::after {
  content: attr(title);
  position: absolute;
  left: 0;
  top: 0;
  padding: .25em .5em;
  background-color: rgba(255, 255, 255, .8);
}
<div class="demo" title="Large image, normal"><img class="normal" src="https://i.stack.imgur.com/2DdPE.jpg"></div>
<div class="demo" title="Large image, rotated"><img class="rotated" src="https://i.stack.imgur.com/2DdPE.jpg"></div>
<div class="demo" title="Small image, normal"><img class="normal" src="https://i.stack.imgur.com/ustNQ.jpg"></div>
<div class="demo" title="Small image, rotated"><img class="rotated" src="https://i.stack.imgur.com/ustNQ.jpg"></div>