There exist many similar questions, but none has yet solved my requirements:
Aspect ratio should be kept, AND
Height responsive, AND
Width responsive, AND
Full image should always be seen within the browser window (i.e. the responsiveness should be with regards to the tightest dimension).
I have achieved these requirements, but not all of them in the same time. For example:
If I let the code below as it is with
height="90%" width="auto"
then it is height responsive but not width responsive.
If I change to
height="auto" width="90%"
then it is width responsive but not height responsive.
If I change to
height="90%" width="90%"
then it is both height and width responsive, but the ratio is not kept.
To test, please "Run code snippet" and check with "Full page" the situation by changing both height and width of the browser window.
.test {
height: 90vh;
width: 90%;
background-color: #222;
color: #eee;
padding: 2rem;
}
.test img {
align-items: center;
}
<div class="test">
<img height="90%" width="auto" src="https://images.unsplash.com/photo-1418065460487-3e41a6c84dc5?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1600&q=80">
</div>
I have tested in many different ways (e.g. with max-width, etc.) but not succeeded so far.
Any idea how to change the above code so that all requirements are fulfilled simultaneously?
You can use max-width and max-height together on the image then it will keep your aspect ratio and always fit on the screen with the complete image showing
body {
margin: 0;
}
.test {
background-color: #222;
color: #eee;
padding: 2rem;
height: 90vh;
width: 90%;
box-sizing: border-box;
}
.test img {
margin: auto;
display: block;
max-width: 100%;
max-height: 100%;
}
<div class="test">
<img src="https://images.unsplash.com/photo-1418065460487-3e41a6c84dc5?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1600&q=80">
</div>
try this in your css:
.test img {
object-fit: cover;
width: 100%;
height: auto;
}
Solution with use of aspect-ratio:
:root {
--imageWidth: 300;
--imageHeight: 150;
}
.image-container {
max-width: calc(var(--imageWidth) * 1px);
max-height: 100%;
aspect-ratio: var(--imageWidth) / var(--imageHeight);
}
.image {
display: block;
height: 100%;
aspect-ratio: var(--imageWidth) / var(--imageHeight);
}
.resize-wrapper {
display: inline-block;
resize: both;
overflow: hidden;
border: 1px solid black;
}
<div class="resize-wrapper">
<div class="image-container">
<img src="https://placehold.co/300x150/svg" class="image" />
</div>
</div>
I want to display an image on the webpage. The image is long enough having fixed height. So, when someone checks responsiveness by decreasing screen-size it should remove the extra size from that div(which is happening).
I don't know the particular term. So, I will try to explain. it should be shown from the centre point. If image is "abcdefgh". Assume 'a','b'... all are grid number. The default behaviour when screen size will be relatively half is "abcd", but I want to display "cdef".
I gave overflow: hidden to remove extra image out of div. I tried margin-left, margin-right both auto. But, it is only required when the image is less than div size.
img {
display: block;
margin-left: auto;
margin-right: auto;
}
<!DOCTYPE html>
<html>
<body>
<div style="border:4px solid black; height:200px;overflow:hidden;text-align:center;">
<img src="https://mdbootstrap.com/img/Photos/Slides/img%20(130).jpg" alt="Paris" style="width:100%;height:200px;">
</div>
</body>
</html>
You can add object-fit: cover to 'crop' the image responsively
I used object-fit: cover;, this works.
img {
display: block;
margin-left: auto;
margin-right: auto;
object-fit: cover;
}
<!DOCTYPE html>
<html>
<body>
<div style="border:4px solid black; height:200px;overflow:hidden;text-align:center;">
<img src="https://mdbootstrap.com/img/Photos/Slides/img%20(130).jpg" alt="Paris" style="width:100%;height:200px;">
</div>
</body>
</html>
Only object-fit: cover will not work. It also needs width and height values. For best practice give height value. Please this value should not in percentage(%). And give image width: 100% and height: 100%. It will work.
.parentDiv {
border: 4px solid black;
width: 80%;
height: 250px;
margin: 0 auto;
}
img {
display: block;
object-fit: cover;
width: 100%;
height: 100%;
}
<div class="parentDiv">
<img src="https://mdbootstrap.com/img/Photos/Slides/img%20(130).jpg" alt="Paris"><div>
Please check this link: jsfiddle
You can set fixed size for image an use object-fit: cover in css.
.wrapper {
border: 4px solid black;
height: 200px;
overflow: hidden;
text-align: center;
}
.img {
display: block;
margin-left: auto;
margin-right: auto;
width: 100%;
object-fit: cover;
}
<div class="wrapper">
<img class="img" src="https://mdbootstrap.com/img/Photos/Slides/img%20(130).jpg" alt="Paris">
</div>
My apple-pie-icons image in CSS is not responding to any height attribute. It responds to width, but not height.
Could I be including it in the wrong div?
I've tried using pixels and height percentages - no response.
What am I doing wrong?
HTML
`<div class="container">
<div>
<div>
<img src="images/apple-pie.jpg" alt="Apple Pie" styling="width: 100%; height: 400px">
<h1>Apple Pie</h1>
</div>
<div id="description-container">
<div id="Apple-pies">
This was my grandmother's apple pie recipe. I have never seen another one
quite like it. It will always be my favorite and has won me several first place
prizes in local competitions. I hope it becomes one of your favorites as well!
</div>
<div class="apple-pie-icons">
<img src="images/recipe-info.png">
</div>
</div>
</div>
`
CSS
* {
font-family: Arial, Verdana, monospace;
}
.container {
width: 80%;
}
img {
position: relative;
width: 100%;
height: 500px;
}
h1 {
position: absolute;
top: 175px;
color: white;
width: 100%;
left: 32%;
font-size: 300%;
}
#description-container{
width: 650px;
height: 800px;
margin: 50px 200px 0px 200px;
}
#Apple-pies {
}
.apple-pie-icons{
display: inline-block;
height: 100px;
float: left;
width: 80%;
}
The icon is an image, and your CSS is defined as
img {
position: relative;
width: 100%;
height: 500px;
}
If you want to change the height, you can either change the height attribute there, or give the image a class and change the height that way (change the image tag to <img class="apple-pie-image" src="images/recipe-info.png"> and style via .apple-pie-icons .apple-pie-image { height: 1000px; }), or set the height of the image itself to 100% and then change the height of the parent, which is .apple-pie-icons in this case.
You also have this image (<img src="images/apple-pie.jpg" alt="Apple Pie" styling="width: 100%; height: 400px">) which has an inlinewidth and height style in the tag. It's worth noting that this image will not respond to height or width styles defined in your CSS since the inline styling will overwrite any other CSS.
It's possible that your image is growing the div even though you don't want it to in order to maintain it's aspect ratio. Try adding a more specific class to limit the images size or inspect in your browser to see what is overriding the divs styles.
Try targeting the image itself with the height style.
Right now you're just setting a height to the wrapping div:
.apple-pie-icons {
display: inline-block;
height: 100px;
float: left;
width: 80%;
}
Try...
.apple-pie-icons img {
height: 100px;
max-width: 100%;
}
or something like
.apple-pie-icons img {
height: 100%;
width: auto;
}
Any way to specifically target the image within the div that you're wanting to style.
Problem:
I'm trying to make a scalable view for images in a lightbox. I've got a way to make it look good on every size of screen. But, only Google Chrome's behavior to this method is different from the other browsers.
HTML:
<div class="parent">
<span class="helper"></span>
<img src="">
</div>
CSS:
I create a helper element, setting it's display to inline-block and change the vertical-align to middle for both span and img. This makes sure the image will be placed in the middle of it's parent.
To make sure the height and width of the image won't be any bigger than it's parent, I set it both to 90%. (not 100% 'cause I want some padding as well).
So my CSS looks like this:
.parent{
position: absolute;
top: 0;
right: 0;
bottom: 100px;
left: 0;
background-color: #ccc;
text-align: center;
}
.helper{
display: inline-block;
vertical-align: middle;
height: 100%;
}
img{
vertical-align: middle;
max-width: 90%;
max-height: 90%;
}
Fiddle
In this fiddle you can see that it work's in all browsers except for Google Chrome. Chrome ignores the maximum height that's set. Which will allow the image to be bigger than it's parent, not good..
Is there a work-around for this problem?
check this out with pure css , no js/jquery. just you need to wrap your content in div and give height 100% to it, as when you say max-height: 80% it takes 80% of it's parent which was not there.
.parent{
position: absolute;
top: 0;
right: 0;
bottom: 100px;
left: 0;
background-color: #ccc;
text-align: center;
}
.helper{
display: inline-block;
vertical-align: middle;
height: 100%;
}
img{
vertical-align: middle;
max-width: 90%;
max-height: 80%;
}
<div id = "parentDiv" class="parent">
<div style="height: 100%;">
<span class="helper"></span>
<img id = "imgId" src="http://3d-diva.davidmichaeldesigns.com/images/tree-01.png"/>
</div>
</div>
Hope this is what you are looking for :)
you can pass height to image tag dynamically with respect to parents div through javascript.
function setImgHt(){
var imgHeight = document.getElementById('parentDiv').clientHeight;
document.getElementById('imgId').setAttribute("style","height:"+imgHeight+"px");
}
.parent{
position: absolute;
top: 0;
right: 0;
bottom: 100px;
left: 0;
background-color: #ccc;
text-align: center;
}
.helper{
display: inline-block;
vertical-align: middle;
height: 100%;
}
img{
vertical-align: middle;
max-width: 90%;
max-height: 80%;
}
<body onload="setImgHt()">
<div id = "parentDiv" class="parent">
<span class="helper"></span>
<img id = "imgId" src="http://3d-diva.davidmichaeldesigns.com/images/tree-01.png"/>
</div>
</body>
it can be done through jquery as well on document ready call the function which is being called onLoad now.
Is there a css-only solution to scale an image into a bounding box (keeping aspect-ratio)? This works if the image is bigger than the container:
img {
max-width: 100%;
max-height: 100%;
}
Example:
Use case 1 (works): http://jsfiddle.net/Jp5AQ/2/
Use case 2 (works): http://jsfiddle.net/Jp5AQ/3/
But I want to scale up the image until a dimension is 100% of the container.
Use case 3 (doesn't work): http://jsfiddle.net/Jp5AQ/4/
Thanks to CSS3 there is a solution !
The solution is to put the image as background-image and then set the background-size to contain.
HTML
<div class='bounding-box'>
</div>
CSS
.bounding-box {
background-image: url(...);
background-repeat: no-repeat;
background-size: contain;
}
Test it here: http://www.w3schools.com/cssref/playit.asp?filename=playcss_background-size&preval=contain
Full compatibility with latest browsers: http://caniuse.com/background-img-opts
To align the div in the center, you can use this variation:
.bounding-box {
background-image: url(...);
background-size: contain;
position: absolute;
background-position: center;
background-repeat: no-repeat;
height: 100%;
width: 100%;
}
Note: Even though this is the accepted answer, the answer below is more accurate and is currently supported in all browsers if you have the option of using a background image.
Edit 2: In the modern age, using object-fit might be an even better solution: https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit
No, there is no CSS only way to do this in both directions. You could add
.fillwidth {
min-width: 100%;
height: auto;
}
To the an element to always have it 100% width and automatically scale the height to the aspect ratio, or the inverse:
.fillheight {
min-height: 100%;
width: auto;
}
to always scale to max height and relative width. To do both, you will need to determine if the aspect ratio is higher or lower than it's container, and CSS can't do this.
The reason is that CSS does not know what the page looks like. It sets rules beforehand, but only after that it is that the elements get rendered and you know exactly what sizes and ratios you're dealing with. The only way to detect that is with JavaScript.
Although you're not looking for a JS solution I'll add one anyway if someone might need it. The easiest way to handle this with JavaScript is to add a class based on the difference in ratio. If the width-to-height ratio of the box is greater than that of the image, add the class "fillwidth", else add the class "fillheight".
$('div').each(function() {
var fillClass = ($(this).height() > $(this).width())
? 'fillheight'
: 'fillwidth';
$(this).find('img').addClass(fillClass);
});
.fillwidth {
width: 100%;
height: auto;
}
.fillheight {
height: 100%;
width: auto;
}
div {
border: 1px solid black;
overflow: hidden;
}
.tower {
width: 100px;
height: 200px;
}
.trailer {
width: 200px;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tower">
<img src="http://placekitten.com/150/150" />
</div>
<div class="trailer">
<img src="http://placekitten.com/150/150" />
</div>
Here's a hackish solution I discovered:
#image {
max-width: 10%;
max-height: 10%;
transform: scale(10);
}
This will enlarge the image tenfold, but restrict it to 10% of its final size - thus bounding it to the container.
Unlike the background-image solution, this will also work with <video> elements.
Interactive example:
function step(timestamp) {
var container = document.getElementById('container');
timestamp /= 1000;
container.style.left = (200 + 100 * Math.sin(timestamp * 1.0)) + 'px';
container.style.top = (200 + 100 * Math.sin(timestamp * 1.1)) + 'px';
container.style.width = (500 + 500 * Math.sin(timestamp * 1.2)) + 'px';
container.style.height = (500 + 500 * Math.sin(timestamp * 1.3)) + 'px';
window.requestAnimationFrame(step);
}
window.requestAnimationFrame(step);
#container {
outline: 1px solid black;
position: relative;
background-color: red;
}
#image {
display: block;
max-width: 10%;
max-height: 10%;
transform-origin: 0 0;
transform: scale(10);
}
<div id="container">
<img id="image" src="https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png">
</div>
Today, just say object-fit: contain. Support is everything but IE: http://caniuse.com/#feat=object-fit
html:
<div class="container">
<img class="flowerImg" src="flower.jpg">
</div>
css:
.container{
width: 100px;
height: 100px;
}
.flowerImg{
width: 100px;
height: 100px;
object-fit: cover;
/*object-fit: contain;
object-fit: scale-down;
object-position: -10% 0;
object-fit: none;
object-fit: fill;*/
}
You can accomplish this with pure CSS and complete browser support, both for vertically-long and horizontally-long images at the same time.
Here's a snippet which works in Chrome, Firefox, and Safari (both using object-fit: scale-down, and without using it):
figure {
margin: 0;
}
.container {
display: table-cell;
vertical-align: middle;
width: 80px;
height: 80px;
border: 1px solid #aaa;
}
.container_image {
display: block;
max-width: 100%;
max-height: 100%;
margin-left: auto;
margin-right: auto;
}
.container2_image2 {
width: 80px;
height: 80px;
object-fit: scale-down;
border: 1px solid #aaa;
}
Without `object-fit: scale-down`:
<br>
<br>
<figure class="container">
<img class="container_image" src="https://i.imgur.com/EQgexUd.jpg">
</figure>
<br>
<figure class="container">
<img class="container_image" src="https://i.imgur.com/ptO8pGi.jpg">
</figure>
<br> Using `object-fit: scale-down`:
<br>
<br>
<figure>
<img class="container2_image2" src="https://i.imgur.com/EQgexUd.jpg">
</figure>
<br>
<figure>
<img class="container2_image2" src="https://i.imgur.com/ptO8pGi.jpg">
</figure>
Another solution without background image and without the need for a container (though the max sizes of the bounding box must be known):
img{
max-height: 100px;
max-width: 100px;
width: auto; /* These two are added only for clarity, */
height: auto; /* as the default is auto anyway */
}
If a container's use is required, then the max-width and max-height can be set to 100%:
img {
max-height: 100%;
max-width: 100%;
width: auto; /* These two are added only for clarity, */
height: auto; /* as the default is auto anyway */
}
div.container {
width: 100px;
height: 100px;
}
For this you would have something like:
<table>
<tr>
<td>Lorem</td>
<td>Ipsum<br />dolor</td>
<td>
<div class="container"><img src="image5.png" /></div>
</td>
</tr>
</table>
This example to stretch the image proportionally to fit the entire window.
An improvisation to the above correct code is to add $( window ).resize(function(){});
function stretchImg(){
$('div').each(function() {
($(this).height() > $(this).find('img').height())
? $(this).find('img').removeClass('fillwidth').addClass('fillheight')
: '';
($(this).width() > $(this).find('img').width())
? $(this).find('img').removeClass('fillheight').addClass('fillwidth')
: '';
});
}
stretchImg();
$( window ).resize(function() {
strechImg();
});
There are two if conditions. The first one keeps checking if the image height is less than the div and applies .fillheight class while the next checks for width and applies .fillwidth class.
In both cases the other class is removed using .removeClass()
Here is the CSS
.fillwidth {
width: 100%;
max-width: none;
height: auto;
}
.fillheight {
height: 100vh;
max-width: none;
width: auto;
}
You can replace 100vh by 100% if you want to stretch the image with in a div. This example to stretch the image proportionally to fit the entire window.
Are you looking to scale upwards but not downwards?
div {
border: solid 1px green;
width: 60px;
height: 70px;
}
div img {
width: 100%;
height: 100%;
min-height: 500px;
min-width: 500px;
outline: solid 1px red;
}
This however, does not lock aspect-ratio.
I have used table to center image inside the box. It keeps aspect ratio and scales image in a way that is totally inside the box. If the image is smaller than the box then it is shown as it is in the center. Below code uses 40px width and 40px height box. (Not quite sure how well it works because I removed it from another more complex code and simplified it little bit)
.SmallThumbnailContainer {
display: inline-block;
position: relative;
float: left;
width: 40px;
height: 40px;
border: 1px solid #ccc;
margin: 0px;
padding: 0px;
}
.SmallThumbnailContainer {
width: 40px;
margin: 0px 10px 0px 0px;
}
.SmallThumbnailContainer tr {
height: 40px;
text-align: center;
}
.SmallThumbnailContainer tr td {
vertical-align: middle;
position: relative;
width: 40px;
}
.SmallThumbnailContainer tr td img {
overflow: hidden;
max-height: 40px;
max-width: 40px;
vertical-align: middle;
margin: -1px -1px 1px -1px;
}
<table class="SmallThumbnailContainer" cellpadding="0" cellspacing="0">
<tr>
<td>
<img src="https://www.gravatar.com/avatar/bf7d39f4ed9c289feca7de38a0093250?s=32&d=identicon&r=PG" width="32" height="32" alt="OP's SO avatar image used as a sample jpg because it is hosted on SO, thus always available" />
</td>
</tr>
</table>
Note: the native thumbnail size in this snippet is 32px x 32px, which is smaller than its 40px x 40px container. If the container is instead sized smaller than the thumbnail in any dimension, say 40px x 20px, the image flows outside the container in the dimensions that are smaller than the corresponding image dimension. The container is marked by a gray 1px border.
Use Object Fit on both div and img to scale image
<div class="box"><img src="image.jpg"></div>
.box {height: auto;
object-fit: cover;}
img { height: 100%; object-fit: cover; }
This worked for my needs, doesn't flatten out the image while setting height limitation, it overflows instead.
.top-container{
width:50%;
}
.img-container {
display: flex;
justify-content: center;
align-items: center;
height: 40vh;
width: 100%;
overflow: hidden;
}
.img-container img {
max-width: 10%;
max-height: auto;
transform: scale(10);
}
<div class='top-container'>
<div class='img-container'>
<img src='image.jpg'>
</div>
</div>
First some CSS:
div.image-wrapper {
height: 230px; /* Suggestive number; pick your own height as desired */
position: relative;
overflow: hidden; /* This will do the magic */
width: 300px; /* Pick an appropriate width as desired, unless you already use a grid, in that case use 100% */
}
img {
width: 100%;
position: absolute;
left: 0;
top: 0;
height: auto;
}
The HTML:
<div class="image-wrapper">
<img src="yourSource.jpg">
</div>
.img-class {
width: <img width>;
height: <img height>;
content: url('/path/to/img.png');
}
Then on the element (you can use javascript or media queries to add responsiveness):
<div class='img-class' style='transform: scale(X);'></div>
.boundingbox {
width: 400px;
height: 500px;
border: 2px solid #F63;
}
img{
width:400px;
max-height: 500px;
height:auto;
}
With the styles set as shown above in css, now the following html div will show the image always fit width wise and will adjust hight aspect ratio to width. Thus image will scale to fit a bounding box as asked in the question.
<div class="boundingbox"><img src="image.jpg"/></div>