fractalsvelte mascot fractalsvelte fractalsvelte

Svelte 5 component · fractalsvelte-ui · Motion

ShimmerEffect

A continuous diagonal light sweep overlay designed for attention highlights and loading skeleton containers. Accepts customizable angles, cycle durations, and sweep colors.

Install

ShimmerEffect is a Svelte 5 shimmer effect component in @fractaldesign/fractalsvelte-ui. It works in SvelteKit and in any Svelte 5 app.

pnpm add @fractaldesign/fractalsvelte-ui

Import

import
import { ShimmerEffect } from '@fractaldesign/fractalsvelte-ui';

Usage

Example
<ShimmerEffect active={true} duration={2} angle={45}>Click me</ShimmerEffect>

Props

Also accepts every attribute of HTMLAttributes, spread onto the root element.

NameTypeDefault
active boolean true
duration number 2
angle number 45
color string 'rgba(255, 255, 255, 0.12)'
class string ''

Snippets

NameTypeDefault
children Snippet —

Source

Show the ShimmerEffect.svelte source
ShimmerEffect.svelte
<script lang="ts">
	import type { Snippet } from 'svelte';
	import type { HTMLAttributes } from 'svelte/elements';

	interface Props extends HTMLAttributes<HTMLDivElement> {
		active?: boolean;
		duration?: number;
		angle?: number;
		color?: string;
		class?: string;
		children?: Snippet;
	}

	let {
		active = true,
		duration = 2,
		angle = 45,
		color = 'rgba(255, 255, 255, 0.12)',
		class: className = '',
		children,
		...restProps
	}: Props = $props();
</script>

<div
	class="f-shimmer-wrap {className}"
	data-active={active ? 'true' : undefined}
	style="--shimmer-duration: {duration}s; --shimmer-angle: {angle}deg; --shimmer-color: {color};"
	{...restProps}
>
	{#if children}
		{@render children()}
	{/if}

	{#if active}
		<div class="f-shimmer-sweep" aria-hidden="true"></div>
	{/if}
</div>

<style>
	@layer fractalsvelte-ui.components {
		.f-shimmer-wrap {
			position: relative;
			overflow: hidden;
			display: inline-block;
			width: 100%;
		}

		.f-shimmer-sweep {
			position: absolute;
			inset: 0;
			pointer-events: none;
			z-index: 5;
			background: linear-gradient(
				var(--shimmer-angle),
				transparent 0%,
				transparent 35%,
				var(--shimmer-color) 50%,
				transparent 65%,
				transparent 100%
			);
			background-size: 250% 250%;
			animation: f-shimmer-anim var(--shimmer-duration) infinite linear;
		}

		@keyframes f-shimmer-anim {
			0% {
				background-position: 200% 0;
			}
			100% {
				background-position: -200% 0;
			}
		}
	}
</style>