Although this may deviate from the original question, I highly recommend using actual images instead of background-images. This approach offers more flexibility in implementation (such as animations), enables optimization for different resolutions and devices (using srcset), enhances accessibility through alt tags, and makes event listening easier.
To achieve a similar effect to background images, you can simply wrap the image in a container and apply some CSS (like object-fit: cover).
Below is a brief example demonstrating how to use onload event to trigger an animation:
function onImageLoaded() {
document.querySelector('header').classList.add('loaded')
}
function onImageError() {
alert('I\'m starting to work up some anxiety about this whole thing!')
}
* {
box-sizing: border-box;
position: relative;
}
header {
aspect-ratio: 21/9;
display: flex;
justify-content: center;
align-items: center;
font-size: 1rem;
color: white;
text-shadow: 0 0 .25em rgba(0, 0, 0, 0.4);
background: #869F63;
z-index: 0;
overflow: hidden;
}
picture {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: block;
z-index: -1;
overflow: hidden;
}
picture img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
h1 {
will-change: transform;
transition: transform 2000ms;
transform: translateY(50vh);
opacity: 0;
}
img {
will-change: transform;
transition: transform 2000ms;
transform: scale(2);
opacity: 0;
}
.loaded h1,
.loaded img {
transform: none;
opacity: 1
}
<header>
<picture>
<img src="https://assets.codepen.io/68939/rickandmorty.png" width="680" height="380" alt="Rick & Morty...." onload="onImageLoaded()" onerror="onImageError()" />
</picture>
<h1>Rick & Morty</h1>
</header>