Animate element A based on element B using CSS scroll animations
Is it possible to animate element A based on element B's presence in the viewport? I've tried running this in a codepen, but I might be misunderstanding the properties because all element A does now is run the animation on page load and then nothing when element B appears...
<div class="spacer">scroll down</div>
<div class="target">
Element B (scroll target)
</div>
<div class="spacer"></div>
<div class="animated">
Element A (fixed HUD)
</div>
<div class="spacer"></div><div class="spacer">scroll down</div>
<div class="target">
Element B (scroll target)
</div>
<div class="spacer"></div>
<div class="animated">
Element A (fixed HUD)
</div>
<div class="spacer"></div>body {
margin: 0;
font-family: system-ui, sans-serif;
}
.spacer {
height: 100vh;
background: #eee;
display: grid;
place-items: center;
font-size: 2rem;
}
/* Element B */
.target {
height: 60vh;
margin: 20vh 0;
background: #111;
color: white;
display: grid;
place-items: center;
font-size: 2rem;
/* Create the view timeline */
view-timeline-name: --target;
view-timeline-axis: block;
}
/* Element A (fixed) */
.animated {
position: fixed;
top: 20px;
left: 20px;
padding: 1rem 1.5rem;
background: crimson;
color: white;
border-radius: 8px;
animation-name: hudMove;
animation-timing-function: linear;
animation-fill-mode: both;
/* REQUIRED even for scroll-driven */
animation-duration: 1s;
/* Hook into B’s visibility */
animation-timeline: view(--target);
animation-range: entry 0% exit 100%;
}
@keyframes hudMove {
from {
transform: translateX(0);
opacity: 0.2;
}
to {
transform: translateX(300px);
opacity: 1;
}
}body {
margin: 0;
font-family: system-ui, sans-serif;
}
.spacer {
height: 100vh;
background: #eee;
display: grid;
place-items: center;
font-size: 2rem;
}
/* Element B */
.target {
height: 60vh;
margin: 20vh 0;
background: #111;
color: white;
display: grid;
place-items: center;
font-size: 2rem;
/* Create the view timeline */
view-timeline-name: --target;
view-timeline-axis: block;
}
/* Element A (fixed) */
.animated {
position: fixed;
top: 20px;
left: 20px;
padding: 1rem 1.5rem;
background: crimson;
color: white;
border-radius: 8px;
animation-name: hudMove;
animation-timing-function: linear;
animation-fill-mode: both;
/* REQUIRED even for scroll-driven */
animation-duration: 1s;
/* Hook into B’s visibility */
animation-timeline: view(--target);
animation-range: entry 0% exit 100%;
}
@keyframes hudMove {
from {
transform: translateX(0);
opacity: 0.2;
}
to {
transform: translateX(300px);
opacity: 1;
}
}
front-end