I am using NextJS for a personal website. I am trying to have both smooth scroll and a transform animation which increases the size of the selected item. Here you have a simple demo of what I am trying to achieve:
const items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
function ScrollContainer() {
const [selectedIndex, setSelectedIndex] = React.useState(0)
const itemRefs = React.useRef([])
React.useEffect(() => {
itemRefs.current = itemRefs.current.slice(0, items.length)
}, [])
const handleItemClick = (index) => {
if (index !== selectedIndex) {
setSelectedIndex(index)
itemRefs.current[index].scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'center'
})
}
}
return (
<div className="w-full h-screen flex items-center justify-center bg-gray-100">
<div className="w-full max-w-3xl overflow-hidden">
<div className="flex space-x-4 px-4 py-8 overflow-x-auto snap-x snap-mandatory scrollbar-hide">
{items.map((item, index) => (
<div
key={item}
ref={el => itemRefs.current[index] = el}
className={`flex-shrink-0 w-32 h-32 flex items-center justify-center text-2xl font-bold text-white rounded-lg snap-center transition-all duration-300 ease-in-out cursor-pointer
${index === selectedIndex ? 'bg-blue-500 scale-110' : 'bg-gray-400 scale-100 hover:bg-gray-500'}`}
onClick={() => handleItemClick(index)}
>
{item}
</div>
))}
</div>
</div>
</div>
)
}
ReactDOM.createRoot(
document.getElementById("root")
).render(
<ScrollContainer />
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>
EDIT: The smooth scroll works fine in Firefox, but not in Chrome 🙁
2
Answers
have you tried scroll-smooth with Tailwind and are you using the latest version? Try this code:
<div className="flex space-x-4 px-4 py-8 overflow-x-auto snap-x snap-mandatory scrollbar-hide scroll-smooth">
Combining
overflow-x-auto
withsnap
on the same carousel container seems to break the scroll animation in Chrome.One way to fix this is by moving
overflow-x-auto
to the parent div.Playground: https://stackblitz.com/edit/stackblitz-starters-vw5ksu?file=app%2Fpage.tsx