I'm using useIntersectionObserver
from VueUse to apply a fade-in
transition on elements when they come into view. However, on initial page load, the elements briefly appear before the intersection observer triggers, causing a flash and applying the fade-in
effect with a delay.
I want the elements to fade in smoothly as soon as the page loads, without this initial flash. Here’s the reproduction: https://stackblitz.com/edit/nuxt-starter-vd6hka?file=app%2Fpages%2Findex.vue
Observer component:
<template>
<div>
<div ref="observerRef">
<div :class="{ 'fade-in': isVisible }">
<img crossOrigin="anonymous" src="https://unsplash.it/600/400" />
</div>
</div>
</div>
</template>
<script setup>
import { useIntersectionObserver } from '@vueuse/core';
const observerRef = ref(null);
const isVisible = ref(false);
const { stop } = useIntersectionObserver(
observerRef,
([{ isIntersecting }]) => {
isVisible.value = isIntersecting;
if (isIntersecting) stop();
}
);
</script>
Looking for a possible solution.
DOM APIs like IntersectionObserver
are not guaranteed to be synchronous. It takes some time between an element being visible on the screen and an observer being triggered.
div
that needs a transition should have visible: hidden
style when it have fade-in
, either through CSS class or dynamic styles:
<div
:class="{ 'fade-in': isVisible }"
:style="{ visibility: isVisible ? 'visible' : 'hidden' }"
>