Reputation: 15422
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?
Upvotes: 28
Views: 22686
Reputation:
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.
Upvotes: 3
Reputation: 21
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;
}
Upvotes: 2
Reputation: 1060
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);
Upvotes: 1
Reputation: 272106
For full screen display, the simplest solution is to use viewport units to specify width and height of images:
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.sstatic.net/2DdPE.jpg"></div>
<div class="demo" title="Large image, rotated"><img class="rotated" src="https://i.sstatic.net/2DdPE.jpg"></div>
<div class="demo" title="Small image, normal"><img class="normal" src="https://i.sstatic.net/ustNQ.jpg"></div>
<div class="demo" title="Small image, rotated"><img class="rotated" src="https://i.sstatic.net/ustNQ.jpg"></div>
Upvotes: 14
Reputation: 454
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;
}
Upvotes: 0
Reputation: 6419
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>
Upvotes: 2
Reputation: 7746
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.
Upvotes: 0
Reputation: 1039
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/
Upvotes: -2