CSS animation with ‘IntersectionObserver’ doesn’t work (Vanilla JS)

I’m having issues with my InsersectionObserver code: The content of the .timeline-graphs class should be appearing from bellow (@keyframes animation in CSS), but only when the the viewport intersects with it, thanks to InsersectionObserver (JS). Simple enough, but I can’t manage it to work. This is the code:


const elementsToExpand = document.querySelectorAll('.timeline-graphs');

let expansionObserver = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.intersectionRatio > 0) {
    } else {


elementsToExpand.forEach((element) => {
.timeline-graphs {
    display: flex;
    flex-flow: row no-wrap;
    justify-content: center;
    text-align: center;
    align-items: center;


.timeline-graphs.isVisible {
    animation-name: fadeIn;
    animation-duration: 2.5s;
    animation-fill-mode: both; 

@keyframes fadeIn {

    0% {
    opacity: 0;
    -webkit-transform: translate3d(0,40%,0);
    transform: translate3d(0,40%,0);

    100% {
    opacity: 1;
    -webkit-transform: translate3d(0,0,0);
    transform: translate3d(0,0,0);
<section class="timeline-graph-section">
    <article class="timeline-graphs">
        <h1>This is a title</h1>

I appreciate any support on this!


Solved! After seeing the code working everywhere for everybody (including seeing it work in Codepen with my own eyes) but never in my local ropository, I suspected it had to be one of two things: There was an implicit library/framework at work in stackOverflow/CodePen that I wasn’t using… or something was up with the HTML code I didn’t include in here.

And that was exactly it: I took the script out of the head element and placed it on the last line inside the body element, right before the closing tag. Now the code works! Thank you all for you help with this!