26

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/

div.top {
    position: fixed;
    width: 100%;
    height: 100%;
    border: 1px solid blue;
}
img {
    transform: rotate(90deg);
    max-width: 100%;
    max-height: 100%;
}
<div class="top">
    <img src="http://www.androidpolice.com/wp-content/uploads/2014/02/nexusae0_wm_DSC02232.jpg">
</div>

Is there a way to achieve this?

Salman A
  • 262,204
  • 82
  • 430
  • 521
Blacksad
  • 14,906
  • 15
  • 70
  • 81
  • Nothing is being ignored, it's simply maintaining the aspect ratio of the image. The image in your example is scaled so that its width fits the parent width, and *then* it is rotated 90 degrees. The image is exactly as tall as the contain is wide. – user229044 Sep 08 '15 at 00:42
  • 1
    @meagar yes I agree. But i'd like it to be scaled so that its width fits the parent **height** since it's going to be rotated. – Blacksad Sep 08 '15 at 00:44
  • Is your intent to maintain the aspect ratio of the photo leaving whitespace on one side, or to completely cover the container, cropping the photo to fit, or the completely cover the photo, discarding aspect ratio? – user229044 Sep 08 '15 at 00:55
  • @meagar it's the 1st. – Blacksad Sep 08 '15 at 00:57
  • http://jsfiddle.net/puddjm4y/15/ does this count as working? – Shih-Min Lee Sep 08 '15 at 02:10
  • 2
    @Blacksad Did you find an answer ? i am facing the exact same issue. I can't make the image completely cover its parent, with no whitespace on any sides. – doubleOrt Jun 25 '17 at 02:13
  • Are you allowed to use javascript??? – Rafael Oct 26 '18 at 15:28
  • @Shih-MinLee Looks like you [ignored the IE](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit#Browser_compatibility) – vrintle Oct 26 '18 at 15:44
  • @Rafael I would allow anything if there was only one solution, where the picture fits into the original frame. Not only in the fullscreen solution as solved below. JavaScript, jQuery :). Do you have a solution? – Sarah Trees Jan 20 '20 at 07:42

9 Answers9

14

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>
Salman A
  • 262,204
  • 82
  • 430
  • 521
3

Make the height of an element equal it's width and vice versa, is a Javascript thing, since it can retrieve those values and set them back.

In CSS there's no way of accomplishing that, and also not possible with dynamic dimensions, we don't know what 100% would equal to exactly, and even if we did we wouldn't be able to use them, because there's no reference to them.

However if you would go with fixed values, that can be manipulated with media queries, then why not use variables, this way we have the value, and a reference to it.

:root {
  --width: 100px;
  --height: 140px;
}

div.top {
  position: fixed;
  width: var(--width);
  height: var(--height);
  border: 1px solid blue;
}

img {
  width: var(--width);
  height: var(--height);
  animation: rotate 3s alternate infinite;
}


/* translate values are the difference between the height */
/* and width divided between the X and Y */
/* 100 - 140 = 40 / 2 = 20px each */

@keyframes rotate {
  to {
    transform: rotate(90deg) translate(20px, 20px);
    width: var(--height);
    height: var(--width);
  }
}
<div class="top">
  <img src="http://www.androidpolice.com/wp-content/uploads/2014/02/nexusae0_wm_DSC02232.jpg">
</div>

Then again, this is just an idea.

Rainbow
  • 6,772
  • 3
  • 11
  • 28
2

I would probably go for something like this (swapped max-width/height using viewport sizing)

* {
  box-sizing:border-box;
}

html, body {
  margin:0;
}

div.top {
    position: fixed;
    width: 100%;
    height: 100%;
    top:0;
    left:0;
    border: 1px solid blue;
    display:flex;
}
img {
    transform: rotate(90deg);
    max-width: 100vh;
    max-height: 100vw;
    margin:auto;
}
<div class="top">
    <img src="http://www.androidpolice.com/wp-content/uploads/2014/02/nexusae0_wm_DSC02232.jpg">
</div>
Maciej Kwas
  • 6,169
  • 2
  • 27
  • 51
1

You could do this in JavaScript by checking the container height and setting the maxWidth of the image to the height of the container.

 /**
 * Set max width of a rotated image to container height
 * @param {*} container
 * @param {*} image
 */
function setRotatedImageWidth(container = null, image = null) {
    if (!container || !image) {
        return false; // exit if empty
    }
    var h = container.offsetHeight; // Container height
    var w = image.offsetWidth; // Image width

    // If image width is greater container height
    if (w > h) {
        image.style.maxWidth = h + 'px';
    }
}

var container = document.querySelector('.container');
var image = container.querySelector('img');
setRotatedImageWidth(container, image);
Darren Cooney
  • 1,012
  • 16
  • 25
1

I finally found the answer to what I needed for this problem, maybe it will help someone else. I have a flex parent and the child I needed to be rotated based on EXIF. I needed image-orientation: from-image;

imgBox {
    flex: 1;
    padding: 1rem;
    overflow: hidden;
 }

 .img1 {
     object-fit: cover;
     max-width: 100%;
     image-orientation: from-image;
 }
  • This helped me write a function that solved it for me - the key was having the container be flexbox, and using JS to change the height of the container to match the width of the image when it's rotated sideways. – anba Jan 28 '21 at 21:44
0

Here's a scant attempt that requires manually syncing the width / height. For those who are willing to use JS, that should be fairly easy to sync.

Here it is:

div.top {
    border: 1px solid blue;
    box-sizing: border-box;
    width: 100%;
    height: 300px;/* SYNC */
    position: relative;
    overflow: hidden;
}

div.top:before {
  content: "";
  position: absolute;
  width: 300px;/* SYNC */
  height: 100%; 
  transform: rotate(90deg);
  background-image: url(http://www.androidpolice.com/wp-content/uploads/2014/02/nexusae0_wm_DSC02232.jpg);
  background-size: contain;
  background-repeat: no-repeat;
}
<div class="top"></div>

Positioning becomes awkward. However, my hope is that someone will branch from here and conjure a better solution.

Rafael
  • 7,605
  • 13
  • 31
  • 46
0

If you could ignore the transform part as it is a question of aspect ratio and there is no answer for it, but displaying an image to 100% of the parent element is possible and will not be needing any media queries to it. 100 percent is relative to the parent and with images it is the aspect ratio that rules the dimensions. we can stretch it but that will not serve the purpose. Hope below css might help you in some way.

div.top {
    position: fixed;
    width: 100%;
    height: 100%;
    border: 1px solid blue;
    background-image:url("http://www.androidpolice.com/wp-content/uploads/2014/02/nexusae0_wm_DSC02232.jpg");
    background-size:cover;
    background-repeat:no-repeat;
    background-position:50%;
}
div.top img {
    /* transform: rotate(90deg); */
    min-width: 100%;
    min-height: 100%;
    visibility:hidden;
}
vssadineni
  • 454
  • 4
  • 11
0

I am using image natural width and height to calculate transform scale as I have documented at:

https://stackoverflow.com/a/61620946/7037600

donlys
  • 440
  • 6
  • 13
-2

For the exif part you can't do it with css as css ins't able to ready exif datas.

For the CSS part though, you need to use transform-origin, not just transform and also use width 100% and heigh auto to keep ratio.

Here is an exemple : http://jsfiddle.net/yxqgt2d1/1/

Dexter0015
  • 1,029
  • 9
  • 14