DocsBlog
  • 1.4.0

  • light

    dark

    system

    Switch mode
  • Cerberus

    Acheron

    Elysium

Get Started
Components
Data Grid
Signals
Styling
Theming

Concepts

OverviewCompositionCerberus ContextTesting

Layout

Aspect RatioBleedBoxCenterContainerDividerFlexFloatGridGroupLink OverlayScrollableStackWrap

Components

AccordionAdmonitionAvatarButtonCarouselCheckboxClipboardCollapsibleComboboxConfirm ModalCTAModalDate PickerDialogFieldFieldsetFile UploaderIcon ButtonInputLoading StatesMarqueeNotificationsNumber InputPaginationPin InputPopoverProgressPrompt ModalRadioRatingSelectSplit ButtonSwitchTableTabsTagTextTextareaToggleTooltip

Utilities

Client OnlyDownload TriggerEnvironmentFeature FlagsFocus TrapForFormat ByteFormat NumberFormat Relative TimeFrameHighlightJSON Tree ViewLocaleLocal StoragePortalPresenceShowsplitPropsTheme

Marquee

A marquee component that scrolls text horizontally.

  • npm
  • source
  • recipe
  • Ark
import { Marquee } from "@cerberus/react"

Usage

The Marquee is an abracted API that combines multiple primitives into a single root component.

Spacing

Use the spacing prop to control the gap between content instances.

Reverse

Use the reverse prop to reverse the direction of the marquee.

Vertical Animation

Use the side prop to animate the marquee vertically. The options are top and bottom.

Speed

Use the speed prop to control the animation speed in pixels per second.

Edges

Use the edges prop to display stylized edges on the marquee. The options are both, start, and end.

Pause on Interaction

Use the pauseOnInteraction prop to pause the marquee when users hover or focus on it, improving accessibility.

Context

Access the combobox's state with ComboboxContext or the useComboboxContext hook—useful for displaying the selected value or building custom UI.

Note

Since combobox is an abstracted API, you'll need to build your own to obtain the context as we do in the example below.

Finite Loops

To loop the marquee a finite number of times, set the loopCount prop on Marquee. Alternatively, use the onLoopComplete and onComplete callbacks to track the number of completed loops or when the animation fully finishes.

Guides

CSS Variables

The marquee component exposes CSS variables that can be used to customize its behavior and appearance.

<Marquee
  css={{
    "--marquee-duration": "30s",
    "--marquee-delay": "0s",
    "--marquee-loop-count": "infinite",
    "--marquee-edge-color": "colors.bg",
    "--marquee-edge-size": "20%",
  }}
>
  {/* ... */}
</Marquee>
VariableDescriptionDefault
--marquee-durationAnimation durationComputed
--marquee-delayAnimation delay before starting0s
--marquee-loop-countNumber of animation iterationsinfinite
--marquee-edge-colorColor for the edge gradient overlaypage.surface.initial
--marquee-edge-sizeSize of the edge gradient20%

Primitives

You can utilize the primitive components or the css prop to customize the Marquee.

ComponentDescription
MarqueeRootThe context provider for the Marquee family
MarqueeEdgeThe stylistic edge of the Marquee
MarqueeViewportThe viewport container that holds the Marquee content
MarqueeContentThe content of the Marquee
MarqueeItemThe item to be displayed in the Marquee

API

Root Props

PropTypeRequiredDescription
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.
autoFillbooleanNoWhether to automatically duplicate content to fill the container.
defaultPausedbooleanNoWhether the marquee is paused by default.
delaynumberNoThe delay before the animation starts (in seconds).
idsPartial<{ root: string; viewport: string; content: (index: number) => string }>NoThe ids of the elements in the marquee. Useful for composition.
loopCountnumberNoThe number of times to loop the animation (0 = infinite).
onComplete() => voidNoFunction called when the marquee completes all loops and stops. Only fires for finite loops (loopCount > 0).
onLoopComplete() => voidNoFunction called when the marquee completes one loop iteration.
onPauseChange(details: PauseStatusDetails) => voidNoFunction called when the pause status changes.
pausedbooleanNoWhether the marquee is paused.
pauseOnInteractionbooleanNoWhether to pause the marquee on user interaction (hover, focus).
reversebooleanNoWhether to reverse the animation direction.
sideSideNoThe side/direction the marquee scrolls towards.
spacingstringNoThe spacing between marquee items.
speednumberNoThe speed of the marquee animation in pixels per second.
translationsIntlTranslationsNoThe localized messages to use.

Root Data Attributes:

AttributeValue
[data-scope]marquee
[data-part]root
[data-state]"paused" | "idle"
[data-orientation]The orientation of the marquee
[data-paused]Present when paused

Root CSS Variables:

VariableDescription
--marquee-durationThe marquee duration value for the Root
--marquee-spacingThe marquee spacing value for the Root
--marquee-delayThe marquee delay value for the Root
--marquee-loop-countThe marquee loop count value for the Root
--marquee-translateThe marquee translate value for the Root

Content Props:

PropTypeRequiredDescription
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.

Content Data Attributes:

AttributeValue
[data-scope]marquee
[data-part]
[data-index]The index of the item
[data-orientation]The orientation of the content
[data-side]
[data-reverse]
[data-clone]

Edge Props:

PropTypeRequiredDescription
sideSideYesThe side where the edge gradient should appear.
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.

Edge Data Attributes:

AttributeValue
[data-scope]marquee
[data-part]
[data-side]
[data-orientation]The orientation of the edge

Item Props:

PropTypeRequiredDescription
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.

Viewport Props:

PropTypeRequiredDescription
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.

Viewport Data Attributes:

AttributeValue
[data-scope]marquee
[data-part]
[data-orientation]The orientation of the viewport
[data-side]

RootProvider Props:

PropTypeRequiredDescription
valueUseMarqueeReturnYes
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.

Parts

The Marquee API is an Object containing the full family of components.

NameDescription
RootThe context provider for the Marquee family
EdgeThe stylistic edge of the Marquee
ViewportThe viewport container that holds the Marquee content
ContentThe content of the Marquee
ItemThe item to be displayed in the Marquee

On this page

Loading...

Loading...

Loading...

Loading...

Copy
Copy
Apple 🍎
Banana 🍌
Cherry 🍒
Grape 🍇
Watermelon 🍉
Strawberry 🍓
Apple 🍎
Banana 🍌
Cherry 🍒
Grape 🍇
Watermelon 🍉
Strawberry 🍓
Copy
Copy
Copy
'use client'

import { Box, Square, Stack } from '@/styled-system/jsx'
import { Button, For, Marquee, Show, useMarquee } from '@cerberus/react'
import { socials } from './data'
import { Pause, Play } from '@carbon/icons-react'

export function StoreDemo() {
  const marquee = useMarquee({
    autoFill: true,
    spacing: '5rem',
  })

  return (
    <Stack gap="lg" w="full">
      <Marquee.RootProvider value={marquee}>
        <Marquee.Viewport>
          <Marquee.Content>
            <For each={socials}>
              {(item) => (
                <Marquee.Item key={item.label}>
                  <Square size="4rem" style={{ color: item.color }}>
                    <item.icon size="3rem" />
                  </Square>
                </Marquee.Item>
              )}
            </For>
          </Marquee.Content>
        </Marquee.Viewport>
      </Marquee.RootProvider>

      <Box ps="md">
        <Show
          when={marquee.paused}
          fallback={
            <Button onClick={marquee.pause} size="sm">
              <Pause />
              Pause
            </Button>
          }
        >
          <Button onClick={marquee.resume} size="sm" usage="outlined-subtle">
            <Play />
            Resume
          </Button>
        </Show>
      </Box>
    </Stack>
  )
}

Loop completed: 0

Animation completed: 0

Copy
'use client'

import { Square, Stack } from '@/styled-system/jsx'
import { For, Marquee } from '@cerberus/react'
import { createSignal, ReactiveText } from '@cerberus/signals'
import { socials } from './data'

function finiteStore() {
  const [loopCount, setLoopCount] = createSignal(0)
  const [completedCount, setCompletedCount] = createSignal(0)
  return { loopCount, setLoopCount, completedCount, setCompletedCount }
}

const store = finiteStore()

export function FiniteDemo() {
  return (
    <Stack gap="lg" px="md" w="full">
      <Marquee
        loopCount={3}
        onLoopComplete={() => store.setLoopCount((prev) => prev + 1)}
        onComplete={() => store.setCompletedCount((prev) => prev + 1)}
        spacing="5rem"
      >
        <For each={socials}>
          {(item) => (
            <Marquee.Item key={item.label}>
              <Square size="4rem" style={{ color: item.color }}>
                <item.icon size="3rem" />
              </Square>
            </Marquee.Item>
          )}
        </For>
      </Marquee>

      <Stack m="4" textStyle="label-sm">
        <p>
          Loop completed: <ReactiveText data={store.loopCount} />
        </p>
        <p>
          Animation completed: <ReactiveText data={store.completedCount} />
        </p>
      </Stack>
    </Stack>
  )
}
Apple 🍎
Banana 🍌
Cherry 🍒
Grape 🍇
Watermelon 🍉
Strawberry 🍓
Apple 🍎
Banana 🍌
Cherry 🍒
Grape 🍇
Watermelon 🍉
Strawberry 🍓
Copy
Copy
Apple 🍎
Banana 🍌
Cherry 🍒
Grape 🍇
Watermelon 🍉
Strawberry 🍓
Apple 🍎
Banana 🍌
Cherry 🍒
Grape 🍇
Watermelon 🍉
Strawberry 🍓
Copy

Slow (25pxps)

Normal (50pxps)

Fast (100pxps)

import { Square } from '@/styled-system/jsx'
import { For, Marquee } from '@cerberus/react'
import { socials } from './data'

export function BasicDemo() {
  return (
    <Marquee spacing="5rem">
      <For each={socials}>
        {(item) => (
          <Marquee.Item key={item.label}>
            <Square size="4rem" style={{ color: item.color }}>
              <item.icon size="3rem" />
            </Square>
          </Marquee.Item>
        )}
      </For>
    </Marquee>
  )
}
import { Square } from '@/styled-system/jsx'
import { For, Marquee } from '@cerberus/react'
import { socials } from './data'

export function PauseDemo() {
  return (
    <Marquee pauseOnInteraction spacing="5rem">
      <For each={socials}>
        {(item) => (
          <Marquee.Item key={item.label}>
            <Square size="4rem" style={{ color: item.color }}>
              <item.icon size="3rem" />
            </Square>
          </Marquee.Item>
        )}
      </For>
    </Marquee>
  )
}
import { HStack } from '@/styled-system/jsx'
import { For, Marquee } from '@cerberus/react'
import { items } from './data'

export function SpacingDemo() {
  return (
    <Marquee spacing="2rem">
      <For each={items}>
        {(item) => (
          <Marquee.Item key={item.name}>
            <HStack
              bgColor="page.surface.100"
              borderColor="page.border.initial"
              gap="sm"
              h="5rem"
              layerStyle="outline.subtle"
              px="md"
              rounded="md"
              shadow="md"
              w="full"
            >
              {item.name} {item.logo}
            </HStack>
          </Marquee.Item>
        )}
      </For>
    </Marquee>
  )
}
import { Square } from '@/styled-system/jsx'
import { For, Marquee } from '@cerberus/react'
import { socials } from './data'

export function ReverseDemo() {
  return (
    <Marquee reverse spacing="5rem">
      <For each={socials}>
        {(item) => (
          <Marquee.Item key={item.label}>
            <Square size="4rem" style={{ color: item.color }}>
              <item.icon size="3rem" />
            </Square>
          </Marquee.Item>
        )}
      </For>
    </Marquee>
  )
}
import { Center, HStack, Square, Stack } from '@/styled-system/jsx'
import { For, Marquee } from '@cerberus/react'
import { items, socials } from './data'

export function EdgesDemo() {
  return (
    <Stack gap="lg" w="full">
      <Marquee edges={['both']} spacing="5rem">
        <For each={socials}>
          {(item) => (
            <Marquee.Item key={item.label}>
              <Square size="4rem" style={{ color: item.color }}>
                <item.icon size="3rem" />
              </Square>
            </Marquee.Item>
          )}
        </For>
      </Marquee>

      <Marquee edges={['both']} side="bottom" spacing="2rem" maxH="15rem" px="lg">
        <For each={items}>
          {(item) => (
            <Marquee.Item key={item.name}>
              <Center
                bgColor="page.surface.100"
                borderColor="page.border.initial"
                h="5rem"
                layerStyle="outline.subtle"
                rounded="md"
                shadow="md"
              >
                <HStack gap="sm" h="full">
                  {item.name} {item.logo}
                </HStack>
              </Center>
            </Marquee.Item>
          )}
        </For>
      </Marquee>
    </Stack>
  )
}
import { Stack } from '@/styled-system/jsx'
import { For, Marquee, Text } from '@cerberus/react'
import { socials, speeds } from './data'

export function SpeedDemo() {
  return (
    <Stack gap="12" px="md" w="full">
      <For each={speeds}>
        {(speed) => (
          <Stack key={speed.value} gap="4">
            <Text textStyle="label-sm">{speed.label}</Text>
            <Marquee speed={speed.value}>
              <For each={socials}>
                {(platform) => (
                  <Marquee.Item key={platform.label} px="2rem">
                    <platform.icon color={platform.color} size="3rem" />
                  </Marquee.Item>
                )}
              </For>
            </Marquee>
          </Stack>
        )}
      </For>
    </Stack>
  )
}
import { Center, HStack } from '@/styled-system/jsx'
import { For, Marquee } from '@cerberus/react'
import { items } from './data'

export function SideDemo() {
  return (
    <Marquee side="bottom" spacing="2rem" maxH="15rem" px="lg">
      <For each={items}>
        {(item) => (
          <Marquee.Item key={item.name}>
            <Center
              bgColor="page.surface.100"
              borderColor="page.border.initial"
              h="5rem"
              layerStyle="outline.subtle"
              rounded="md"
              shadow="md"
            >
              <HStack gap="sm" h="full">
                {item.name} {item.logo}
              </HStack>
            </Center>
          </Marquee.Item>
        )}
      </For>
    </Marquee>
  )
}

On this page

  • Usage
  • Spacing
  • Reverse
  • Vertical Animation
  • Speed
  • Edges
  • Pause on Interaction
  • Context
  • Finite Loops
  • Guides
  • CSS Variables
  • Primitives
  • API
  • Root Props
  • Content Props:
  • Edge Props:
  • Item Props:
  • Viewport Props:
  • RootProvider Props:
  • Parts
  • Edit this page on Github