<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
body {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
position: relative;
box-sizing: border-box;
}
.container {
max-width: 960px;
display: flex;
overflow: scroll;
margin: 0 auto;
gap: 10px;
}
.item.focused {
background-color: #9288FF;
filter: grayscale(0);
}
.item {
background-color: #dcdcdc;
display: flex;
flex-shrink: 0;
width: 300px;
height: 200px;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0;
margin: 0;
text-align: center;
filter: grayscale(1);
transition: filter 300ms ease-in-out;
}
let root = document.querySelector(".container");
let elements = document.querySelectorAll(".container .item");
let rootWidth = root.offsetWidth;
let itemWidth = elements[0].offsetWidth;
let rootMargin = (rootWidth - itemWidth) / 2;
elements[0].style.marginLeft = rootMargin + "px";
elements[elements.length - 1].style.marginRight = rootMargin + "px";
// hide left filler item
root.scrollLeft = rootMargin;
let centerObserver = new IntersectionObserver(
function (entries) {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add("focused");
} else {
entry.target.classList.remove("focused");
}
});
},
{
root: root,
threshold: [0.51],
rootMargin: `0px -${rootMargin}px 0px -${rootMargin}px`
}
);
elements.forEach((element) => {
centerObserver.observe(element);
});
let documentObserver = new IntersectionObserver(
([root]) => {
// when items go out of viewport, hide left filler item
if (!root.isIntersecting) root.scrollLeft = rootMargin;
},
{ threshold: 0 }
);
documentObserver.observe(root);
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.