It's not possible to transition the background-image
property directly, but you can achieve a similar effect by setting the background-image
to a :after
pseudo-element and transitioning its opacity
instead.
Here is a simple example:
#image {
position: relative;
width: 300px;
height: 100px;
text-align: center;
line-height: 100px;
}
#image:after {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url(http://www.lorempixel.com/300/100);
opacity: 0;
transition: opacity 1s;
z-index: -1;
}
#image:hover:after {
opacity: 1;
}
<div id="image">Some Content</div>
If you prefer a delay instead of using :hover
, you can define @keyframes
and incorporate a delay
(e.g., 3s
in the example below) to the animation. Afterwards, you can use JavaScript to set the opacity
of #image:after
to 1
once the animation has finished.
animation: fadeIn 1s 1 3s
- Here, fadeIn
represents the animation-name
, 1s
is the animation-duration
, 1
is the animation-iteration
, and 3s
is the animation-delay
.
var img = document.getElementById('image');
var event = ['webkitAnimationEnd', 'animationend'];
for (i = 0; i < event.length; i++) {
img.addEventListener(event[i], function() {
var ss = document.styleSheets;
for (j = 0; j < ss.length; j++) {
var rules = ss[j];
for (k = 0; k < rules.cssRules.length; k++) {
var r = rules.cssRules[k];
if (r.selectorText == "#image::after" || r.selectorText == "#image:after") {
r.style.opacity = 1;
}
}
}
});
}
#image {
position: relative;
width: 300px;
height: 100px;
text-align: center;
line-height: 100px;
}
#image:after {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url(http://www.lorempixel.com/300/100);
-webkit-animation: fadeIn 1s 1 3s;
animation: fadeIn 1s 1 3s;
z-index: -1;
opacity: 0;
}
@-webkit-keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<div id="image">Some Content</div>
Another approach would be to create a pure JavaScript animation using setTimeout()
for the delay and setInterval()
for the animation, without relying on transition
or @keyframes
.
var ss = document.styleSheets;
for (i = 0; i < ss.length; i++) {
var rules = ss[i];
for (j = 0; j < rules.cssRules.length; j++) {
var r = rules.cssRules[j];
if (r.selectorText == "#image::after" || r.selectorText == "#image:after") {
var op = 0;
setTimeout(function() {
var fadeIn = setInterval(function() {
r.style.opacity = op;
op += 0.005;
if (op > 1) {
clearTimeout(fadeIn);
}
}, 7)
}, 3000)
}
}
}
#image {
position: relative;
width: 300px;
height: 100px;
text-align: center;
line-height: 100px;
}
#image:after {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url(http://www.lorempixel.com/300/100);
z-index: -1;
opacity: 0;
}
<div id="image">Some Content</div>