Marquee
A customizable scrolling component that loops its content horizontally or vertically, with configurable direction, hover pause, and repeat options.
Installation
Copy and paste the following code into your project:
vue
<script setup lang='ts'>
import { cn } from '@/lib/utils'
interface MarqueeProps {
class?: string
reverse?: boolean
pauseOnHover?: boolean
vertical?: boolean
repeat?: number
[key: string]: any
};
const props = withDefaults(defineProps<MarqueeProps>(), {
pauseOnHover: false,
vertical: false,
repeat: 4,
})
const className = cn(
'flex shrink-0 justify-around [gap:var(--gap)]',
{
'animate-marquee-vertical flex-col': props.vertical,
'animate-marquee flex-row': !props.vertical,
'[animation-direction:reverse]': props.reverse,
'group-hover:[animation-play-state:paused]': props.pauseOnHover,
},
)
</script>
<template>
<div
v-bind="props" :class="cn('group flex overflow-hidden p-2 [--duration:40s] [--gap:1rem] [gap:var(--gap)]',
{
'flex-row': !props.vertical,
'flex-col': props.vertical,
},
props.class,
)"
>
<div v-for="i in Array(props.repeat).fill(0)" :key="i">
<div :key="i" :class="className">
<slot />
</div>
</div>
</div>
</template>
vue
<script setup lang='ts'>
import { cn } from '@/lib/utils'
const props = defineProps<{
img: string
name: string
username: string
body: string
}>()
</script>
<template>
<div
:class="cn(
'relative w-64 cursor-pointer overflow-hidden h-36 flex flex-col space-y-1 rounded-xl px-4',
' border-gray-950/[.1] bg-gray-950/[.01] border-parent hover:bg-gray-950/[.05]',
)"
>
<div class="flex items-center space-x-2">
<img class="rounded-full" width="32" height="32" :src="props.img">
<p class="flex flex-col space-y-1">
<span class="text-sm font-medium dark:text-white">
{{ props.name }}
</span>
<span class="text-xs font-medium dark:text-white/40">
{{ props.username }}
</span>
</p>
</div>
<div>
<span leading-none class="text-sm font-medium dark:text-white/40">
{{ props.body }}
</span>
</div>
</div>
</template>
<style scoped>
.border-parent {
border: 1px solid #ecedee;
}
</style>
Add the following animations to your tailwind.config.js
file:
js
module.exports = {
theme: {
extend: {
animation: {
'marquee': 'marquee var(--duration) linear infinite',
'marquee-vertical': 'marquee-vertical var(--duration) linear infinite',
},
keyframes: {
'marquee': {
from: { transform: 'translateX(0)' },
to: { transform: 'translateX(calc(-100% - var(--gap)))' },
},
'marquee-vertical': {
from: { transform: 'translateY(0)' },
to: { transform: 'translateY(calc(-100% - var(--gap)))' },
},
},
},
},
}
Examples
Vertical Marquee
3D Marquee
Props
Prop | Type | Default | Description |
---|---|---|---|
class | string | The class to apply to the component. | |
reverse | boolean | false | Whether or not to reverse the direction of the marquee. |
pauseOnHover | boolean | false | Whether or not to pause the marquee when the user hovers over the component. |
vertical | boolean | false | Whether or not to display the marquee vertically. |
repeat | number | 1 | The number of times to repeat the content. |