A) Implementing width
and height
on <img>
The purpose of using the width
and height
attributes in the <img>
tag is to specify the dimensions of the image. Even if these values are later modified with CSS
, providing them initially helps the browser calculate the appropriate proportions and size the page correctly before the image loads.
B) Utilizing invisible thumbnails
Another approach is to use small thumbnail images that are loaded solely for quickly generating correct proportions. These thumbnail images can be significantly smaller because they are not meant for display. Instead, the full-size image serves as the background of the 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>
An added benefit of approach B) is surprising users who attempt to download the image but end up with a tiny thumbnail instead when using "Save image as..." from the context menu.
Check out this live demonstration featuring a large 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;
}
/* CSS reset not relevant here, only positioning */
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.stack.imgur.com/26mip.png');">
<img class="img-responsive" src="https://i.stack.imgur.com/26mip.png" />
</div>
In this example, a script has been included to toggle the opacity
of the thumbnail upon clicking for visual clarity.
If the full-size image load time becomes an issue and displaying the thumbnail temporarily is acceptable, consider adding the thumbnail to the background-image
property as shown 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 specify multiple images in the background-image
property, and they will all load (if available), stacking from top to bottom. This results in the user first seeing the blurred thumbnail while waiting, then witnessing a clear transition as the full-sized image loads and sharpens.