I've been reading all night and can't seem to come to any sort of concrete answer on what the best way to do this is. The two things that I know do work are these—
Use an image wrapper and an <img>
tag like this:
<div class="imageWrapper">
<img src="img.jpg" alt="" onload="imageLoaded(this)">
</div>
and the css looks like
.imageWrapper {
opacity: 0
}
.loaded {
opacity: 1
}
and then have in your js file something like
var imageLoaded = (img) => {
var imgWrapper = img.parentNode;
imgWrapper.className += ' loaded';
}
@media screen only and (min-device-width: 0) and (max-device-width: 450px) {
.backgroundImage {
background: url('small_background_image.jpg');
}
}
@media screen only and (min-device-width: 451px) and (max-device-width: 1024px) {
.backgroundImage {
background: url('medium_background_image.jpg');
}
}
@media screen only and (min-device-width: 1025px) {
.backgroundImage {
background: url('large_background_image.jpg');
}
}
I can do both of these things separately (fade in an image when it is loaded, change a background-image when the browser detects a smaller screen size), but I can't seem to find a solution that incorporates both. I need to be able to specify a different image for different screen sizes, and also be able to detect when that image is loaded and fade it in.
Is there a good way to do this?
I ended up using a variation of guest271314's answer in order to load the correct images. This works on all latest version of each browser and is very easily implemented.
First, I have an inline script placed right underneath my opening <body>
tag so that if my browser is slow with loading my js file it can load the images right away anyways.
<body>
<script>
function imageLoaded(img) {
if ((" " + img.className + " ").indexOf(" "+'loaded'+" ") > -1 ) {
return true;
} else {
img.className += ' loaded';
}
}
</script>
and then I have my <picture>
tag like so:
<picture class="backgroundContainer">
<source srcset="img-1024.jpg" media="(min-width: 0px) and (max-width:1024px)">
<source srcset="img-1920.jpg" media="(min-width: 1025px) and (max-width: 1920px)">
<source srcset="img-2560.jpg" media="(min-width: 1921px)">
<img class="backgroundImage" onload="imageLoaded(this)" src="img-1920.jpg" alt="">
</picture>
and my sass looks like this:
@keyframes fadeIn
0%
opacity: 0
100%
opacity: 1
.backgroundContainer
width: 100%
height: 100%
.backgroundImage
opacity: 0
.loaded
opacity: 1
animation: fadeIn 3s
And this allows the browser (regardless of speed) to wait until the correctly-sized image is done loading, and then fades it in over 3s
, with a safe fallback using the <img>
tag for older browsers.
I basically need to be able to fade in a
background-image
when it loads, or be able to change an<img>
tag's src before it loads depending on screen size, or do something that incorporates both of these things using a method I'm unaware of.
You can use css
content
property with value set to url()
function having URL of image to display, or change displayed image source; css
animation
, @keyframes
to fade in background-image
when the source image loads.
html
<picture class="backgroundImage"></picture>
css
.backgroundImage {
opacity: 0; /* set `opacity` to `0` */
width: 50px;
width: 50px;
content: url(http://lorempixel.com/50/50/technics); /* set intial image */
animation-name: fadein;
animation-iteration-count: 1;
animation-duration: 2500ms;
animation-fill-mode: both;
}
@keyframes fadein {
to {
opacity: 1; /* fade in image */
}
}
/* set media queries */
@media screen only and (min-device-width: 0) and (max-device-width: 450px) {
.backgroundImage {
opacity: 0; /* set `opacity` to `0` */
content: url(http://lorempixel.com/50/50/cats); /* set image */
animation-name: first;
}
@keyframes first {
to {
opacity: 1; /* fade in image */
}
}
}
@media screen only and (min-device-width: 451px) and (max-device-width: 1024px) {
.backgroundImage {
opacity: 0; /* set `opacity` to `0` */
content: url(http://lorempixel.com/50/50/city); /* set image */
animation-name: second;
}
@keyframes second {
to {
opacity: 1; /* fade in image */
}
}
}
@media screen only and (min-device-width: 1025px) {
.backgroundImage {
opacity: 0; /* set `opacity` to `0` */
content: url(http://lorempixel.com/50/50/sports); /* set image */
animation-name: third;
}
@keyframes third {
to {
opacity: 1; /* fade in image */
}
}
}
jsfiddle https://jsfiddle.net/yayd5Lma/3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With