Fade In On Scroll
Content that fades and rises into place as it enters the viewport.
6 frameworksIntermediate
Layered shapes that drift at different depths as the pointer moves.
<!-- Pointer tracking is scoped to this container only, never the document. -->
<div class="parallax relative h-56 w-full max-w-sm overflow-hidden rounded-2xl bg-gradient-to-br from-indigo-500 to-purple-600">
<span data-depth="1" class="absolute left-8 top-8 h-16 w-16 rounded-full bg-white/20 transition-transform duration-200 ease-out will-change-transform"></span>
<span data-depth="2" class="absolute right-10 top-12 h-10 w-10 rounded-lg bg-white/30 transition-transform duration-200 ease-out will-change-transform"></span>
<span data-depth="3" class="absolute bottom-10 left-1/3 h-20 w-20 rounded-full bg-amber-300/40 transition-transform duration-200 ease-out will-change-transform"></span>
<div data-depth="1.5" class="absolute inset-0 flex items-center justify-center transition-transform duration-200 ease-out will-change-transform">
<p class="text-lg font-bold text-white">Move your cursor</p>
</div>
</div>
<script>
(function () {
var node = document.querySelector('.parallax');
if (!node) return;
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
if (!window.matchMedia('(pointer: fine)').matches) return;
var layers = node.querySelectorAll('[data-depth]');
node.addEventListener('pointermove', function (e) {
var rect = node.getBoundingClientRect();
var px = (e.clientX - rect.left) / rect.width - 0.5;
var py = (e.clientY - rect.top) / rect.height - 0.5;
layers.forEach(function (layer) {
var depth = parseFloat(layer.getAttribute('data-depth') || '0');
layer.style.transform = 'translate3d(' + px * depth * 40 + 'px,' + py * depth * 40 + 'px,0)';
});
});
node.addEventListener('pointerleave', function () {
layers.forEach(function (layer) { layer.style.transform = 'translate3d(0,0,0)'; });
});
})();
</script>| Prop | Type | Default | Description |
|---|---|---|---|
strength | number | 40 | Strength |
className | string | '' | Additional classes merged onto the root element. |
Tune `strength` for the parallax range. Pointer tracking is scoped to the container and gated on a fine pointer, so touch and reduced motion stay static.