Reputation: 43893
I have an image that has a dynamic width and height using this css:
.sm_item_image {
width:100%;
height:auto;
max-width:400px;
}
The problem is the image can take a while to download, and while its not there yet, the height is at 0. There basically is a flash of unwanted content. I am looking for a way to set the height to something so it would take up the same space as it's current width.
Does anyone know of a way?
Thanks
Upvotes: 4
Views: 8106
Reputation: 90188
A) use width
and height
on <img>
This is what width
and height
attributes of <img>
are for. If you know the image dimensions on server side when you create the <img>
tag, put them in, even if you override them using CSS
. The browser will know to calculate the proportional height and will size your page correctly before image is loaded.
B) use invisible thumbnails
Another option is to have small thumbnails of your images which you only load for the sole purpose of generating the right proportions fast. They can be 20 times smaller, it doesn't matter, because you're not displaying them. You're only displaying the full image, as background of the image placeholder, when it loads.
Example:
.imgContainer {
background: #eee no-repeat 50% 50% /cover;
overflow: hidden;
}
.imgContainer > img {
opacity: 0;
width: 100%;
float: left;
}
<div class="imgContainer" style="background-image: url('//path/to/full/image')">
<img class="img-responsive" src="//path/to/thumbnail" />
</div>
A small "bonus" of B) is the surprise users get when trying to download your crispy image and end up with the tiny thumbnail on right-click > "Save image as..."
Here's a live example, using a huge image:
$('.imgContainer>img').on('click', function(){
$(this).toggleClass('visible');
})
.imgContainer {
background: #eee no-repeat 50% 50% /cover;
overflow: hidden;
}
.imgContainer > img {
opacity: 0;
width: 100%;
float: left;
transition: opacity .3s ease-in-out;
cursor: pointer;
}
.imgContainer > img.visible {
opacity: 1;
}
/* SO reset, you don't need what's below, it's just positioning and reset */
body {
padding: 0; margin: 0;
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-moz-box-orient: vertical;
-moz-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: center;
-webkit-justify-content: center;
-moz-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-webkit-align-items: center;
-moz-box-align: center;
-ms-flex-align: center;
align-items: center;
min-height: 100vh;
}
.imgContainer {
width: 60%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="imgContainer" style="background-image: url('http://wallpapercave.com/wp/wc1756933.jpg'), url('https://i.sstatic.net/26mip.png');">
<img class="img-responsive" src="https://i.sstatic.net/26mip.png" />
</div>
I added a small script on this one that toggles the opacity
of thumbnail on click, so you see the difference.
If the full image takes too long to load and you don't mind the user seeing the thumbnail while they wait, add the thumbnail to the background-image
property, like I did in the example above:
<div class="imgContainer" style="background-image:
url('//path/to/full/image/'), url('//path/to/thumbnail/image/');">
<img src="//path/to/thumbnail/image/" class="img-responsive" />
</div>
You can set multiple images in background-image
property and they will all load (if found), the first one on top and last one at the bottom. So the user will see the blurred thumb until the full size loads and image will suddenly clear up and become sharp.
Upvotes: 5
Reputation: 2132
I actually think there's a very simple solution to this problem: just divide the container width by the image aspect ratio. The only trick to it is that the container width needs to be expressed in vw units. So, for instance, if you had a 16:9 aspect ratio image, and the container was the full width of the viewport, the code would be:
img.responsive {
width: 100%;
height: auto;
min-height: calc(100vw / 1.77777);
}
For different sized containers, you would just change 100vw to your actual container size. So for instance, if your container was 50% of the page width, the image min-height would be calc(50vw / 1.77777)
.
Upvotes: 3
Reputation: 16311
You will have to set a certain min-height
value like this:
.sm_item_image {
width:100%;
height:auto;
max-width:400px;
min-height: 200px; /* replace 200px with whatever height that you want that you want while it's loading */
}
Upvotes: -1