Carousel
Use CCarousel and CCarouselSlide for a named sequence of content cards, stories, or media. It uses native scrolling and Scroll Snap, so touch and trackpad navigation work without an application-widget keyboard model.
Carousel at a glance
Show code
# ruff: noqa: E501
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class CarouselAtAGlance(Component):
template = """
<c-CCarousel label="Featured observations" variant="surface"><c-CCarouselSlide value="aurora" label="Aurora observation"><c-CCard variant="subtle"><c-fill name="header"><strong>Aurora field notes</strong></c-fill><c-fill name="default">A clear night above the northern ridge.</c-fill></c-CCard></c-CCarouselSlide><c-CCarouselSlide value="tide" label="Tide observation"><c-CCard variant="subtle"><c-fill name="header"><strong>Tide field notes</strong></c-fill><c-fill name="default">A spring tide reshaped the eastern inlet.</c-fill></c-CCard></c-CCarouselSlide></c-CCarousel>
"""
preview = CarouselAtAGlance()
preview # noqa: B018
Compose content cards
Show code
# ruff: noqa: E501
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class CarouselCards(Component):
template = """
<c-CCarousel label="Research stories"><c-CCarouselSlide value="forest" label="Forest canopy story"><c-CCard variant="elevated"><c-fill name="header"><c-CBadge intent="success">Canopy</c-CBadge><h3>Listening above the forest floor</h3></c-fill><c-fill name="default">Sensors reveal the canopy's changing rhythm.</c-fill></c-CCard></c-CCarouselSlide><c-CCarouselSlide value="coast" label="Coastal story"><c-CCard variant="elevated"><c-fill name="header"><c-CBadge intent="primary">Coast</c-CBadge><h3>Mapping a moving shoreline</h3></c-fill><c-fill name="default">Field teams compare a decade of tidal change.</c-fill></c-CCard></c-CCarouselSlide></c-CCarousel>
"""
preview = CarouselCards()
preview # noqa: B018
Control the current Slide
Show code
# ruff: noqa: E501
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class ControlledCarousel(Component):
template = """
<section x-data="{index:0}"><p>Slide <strong x-text="index + 1"></strong> of 3</p><c-CCarousel label="Controlled stories" $c-props="{index,onIndexChange:(next)=>index=next}"><c-CCarouselSlide value="one" label="First story"><c-CAlert>First controlled Slide</c-CAlert></c-CCarouselSlide><c-CCarouselSlide value="two" label="Second story"><c-CAlert intent="success">Second controlled Slide</c-CAlert></c-CCarouselSlide><c-CCarouselSlide value="three" label="Third story"><c-CAlert intent="warn">Third controlled Slide</c-CAlert></c-CCarouselSlide></c-CCarousel></section>
"""
preview = ControlledCarousel()
preview # noqa: B018
Choose orientation
Show code
# ruff: noqa: E501
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class VerticalCarousel(Component):
template = """
<c-CCarousel label="Vertical updates" orientation="vertical" style="--cui-carousel-block-size:12rem"><c-CCarouselSlide value="morning" label="Morning update"><c-CAlert>Morning observations</c-CAlert></c-CCarouselSlide><c-CCarouselSlide value="evening" label="Evening update"><c-CAlert intent="info">Evening observations</c-CAlert></c-CCarouselSlide></c-CCarousel>
"""
preview = VerticalCarousel()
preview # noqa: B018
Configure controls and indicators
Show code
# ruff: noqa: E501
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class CarouselControls(Component):
template = """
<c-CStack gap="lg"><c-CCarousel label="Buttons only" c-indicators="False"><c-CCarouselSlide value="one" label="First">Previous and next controls only.</c-CCarouselSlide><c-CCarouselSlide value="two" label="Second">Second Slide.</c-CCarouselSlide></c-CCarousel><c-CCarousel label="Pickers only" c-controls="False"><c-CCarouselSlide value="alpha" label="Alpha">Choose with a named picker.</c-CCarouselSlide><c-CCarouselSlide value="beta" label="Beta">Second picker target.</c-CCarouselSlide></c-CCarousel></c-CStack>
"""
preview = CarouselControls()
preview # noqa: B018
Loop and disable
Show code
# ruff: noqa: E501
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class CarouselStates(Component):
template = """
<c-CStack gap="lg"><c-CCarousel label="Looping stories" loop><c-CCarouselSlide value="one" label="First loop Slide">Previous wraps to the end.</c-CCarouselSlide><c-CCarouselSlide value="two" label="Second loop Slide">Next wraps to the start.</c-CCarouselSlide></c-CCarousel><c-CCarousel label="Disabled stories" disabled><c-CCarouselSlide value="locked" label="Locked Slide">Owned controls are disabled.</c-CCarouselSlide></c-CCarousel></c-CStack>
"""
preview = CarouselStates()
preview # noqa: B018
Variants and sizes
Show code
# ruff: noqa: E501
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class CarouselVariants(Component):
template = """
<c-CStack gap="lg"><c-CCarousel label="Small plain" size="sm"><c-CCarouselSlide value="small" label="Small Slide"><c-CAlert>Compact content</c-CAlert></c-CCarouselSlide></c-CCarousel><c-CCarousel label="Large surface" variant="surface" size="lg"><c-CCarouselSlide value="large" label="Large Slide"><c-CAlert intent="success">Spacious content</c-CAlert></c-CCarouselSlide></c-CCarousel></c-CStack>
"""
preview = CarouselVariants()
preview # noqa: B018
Put forms in Slides
Show code
# ruff: noqa: E501
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class CarouselForms(Component):
template = """
<form><c-CCarousel label="Profile setup" c-indicators="False"><c-CCarouselSlide value="identity" label="Identity form"><c-CField><c-fill name="label">Project name</c-fill><c-fill name="default"><c-CInput name="project" /></c-fill></c-CField></c-CCarouselSlide><c-CCarouselSlide value="preferences" label="Preferences form"><c-CCheckbox name="updates">Receive updates</c-CCheckbox></c-CCarouselSlide></c-CCarousel><c-CButton type="submit">Save profile</c-CButton></form>
"""
preview = CarouselForms()
preview # noqa: B018
Customize Carousel
Show code
# ruff: noqa: E501
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class CustomCarousel(Component):
template = """
<c-CCarousel label="Aurora stories" class_="aurora-carousel" variant="surface"><c-CCarouselSlide value="ridge" label="Northern ridge"><c-CAlert intent="info">The northern ridge at blue hour.</c-CAlert></c-CCarouselSlide><c-CCarouselSlide value="lake" label="Glacial lake"><c-CAlert intent="success">Reflections on the glacial lake.</c-CAlert></c-CCarouselSlide></c-CCarousel>
"""
css = """
.aurora-carousel { --cui-carousel-radius:1.25rem; --cui-carousel-indicator-active-color:#7c3aed; --cui-carousel-control-background:#ede9fe; }
"""
preview = CustomCarousel()
preview # noqa: B018
Accessibility and interaction
Give the root a concise label and every Slide a content-specific label. Previous/next and picker controls are native Buttons that keep focus in place. The native scroll viewport is also a Tab stop, so keyboard and Safari users can focus and scroll it directly without a scripted Arrow-key model. All Slides remain in the accessibility tree; offscreen content is never incorrectly presented as hidden. Disable indicators for large collections to avoid adding too many Tab stops. Autoplay is intentionally not part of v1.
API reference
Inputs
CCarousel server inputs
Server inputs are passed in a template through <c-CCarousel ... /> or in Python through CCarousel(...).
| Input | Type | Default | Effect |
|---|---|---|---|
label | str | required | Names the carousel region without repeating the word carousel. |
id | str | None | generated | Sets root identity. |
index | int | 0 | Selects the initial zero-based Slide and uncontrolled fallback. |
orientation | "horizontal" | "vertical" (CCarouselOrientation) | "horizontal" | Sets scroll axis. |
loop | bool | False | Allows previous and next controls to wrap. |
disabled | bool | False | Disables owned controls and drag handling. |
controls | bool | True | Shows previous and next Buttons. |
indicators | bool | True | Shows the grouped picker Buttons. |
draggable | bool | True | Enables fine-pointer drag; native touch scroll remains available. |
variant | "plain" | "surface" (CCarouselVariant) | "plain" | Selects root treatment. |
size | "sm" | "md" | "lg" (CCarouselSize) | "md" | Selects complete-family geometry. |
previous_label | str | "Previous slide" | Names the previous Button for the current locale. |
next_label | str | "Next slide" | Names the next Button for the current locale. |
picker_label | str | "Choose slide" | Names the picker Button group for the current locale. |
role_description | str | None | "carousel" | Sets the localized aria-roledescription; None omits it. |
class_ | CClassValue (CClassValue) | None | Adds root classes. |
style | CStyleValue (CStyleValue) | None | Adds root inline styles. |
attrs | Mapping[str, object] | None | None | Adds allowed native and data attributes to the root. |
CCarousel client inputs
Client inputs are passed in the browser through the $c-props="{ ... }" attribute on <c-CCarousel />.
| Input | Type | Omitted behavior | Effect |
|---|---|---|---|
index | integer | Releases control and preserves the current committed index. | Controls the active zero-based Slide while supplied. |
orientation | CCarouselOrientation | Uses the server input. | Reactively changes scroll axis. |
loop | boolean | Uses the server input. | Controls boundary wrapping. |
disabled | boolean | Uses the server input. | Controls owned interaction availability. |
controls | boolean | Uses the server input. | Shows or hides previous and next controls. |
indicators | boolean | Uses the server input. | Shows or hides picker controls. |
draggable | boolean | Uses the server input. | Controls fine-pointer dragging. |
variant | CCarouselVariant | Uses the server input. | Changes root treatment. |
size | CCarouselSize | Uses the server input. | Changes complete-family geometry. |
onIndexChange | function | Does not notify a component callback. | Receives navigation scroll and structural index requests. |
CCarouselSlide server inputs
Server inputs are passed in a template through <c-CCarouselSlide ... /> or in Python through CCarouselSlide(...).
| Input | Type | Default | Effect |
|---|---|---|---|
value | str | required | Sets unique stable Slide identity. |
label | str | required | Names Slide content without repeating the word slide. |
role_description | str | None | "slide" | Sets the localized aria-roledescription; None omits it. |
class_ | CClassValue (CClassValue) | None | Adds Slide classes. |
style | CStyleValue (CStyleValue) | None | Adds Slide inline styles. |
attrs | Mapping[str, object] | None | None | Adds allowed native and data attributes to the Slide. |
Slots
Slots are passed as nested content or <c-fill> tags in a template, or through the slots={...} argument in Python.
CCarousel slots
| Slot | Required | Data | Fallback |
|---|---|---|---|
default | yes | {} (CCarouselDefaultSlotData) | none |
CCarouselSlide slots
| Slot | Required | Data | Fallback |
|---|---|---|---|
default | yes | {} (CCarouselSlideDefaultSlotData) | none |
Events
Component events are callback inputs supplied through $c-props. Native browser events remain available through Alpine @... attributes.
CCarousel events
| Event | Signature | Trigger and timing | Detail | Controlled and cancellation behavior |
|---|---|---|---|---|
onIndexChange | (index: integer, detail: CCarouselIndexChangeDetail) => void (CCarouselIndexChangeDetail) | Previous next picker native-scroll or structure requests a different index. | {index, previousIndex, value, reason, controlled, forced, source} (CCarouselIndexChangeDetail) | Uncontrolled requests commit before notification; controlled requests wait for acceptance; removal fallback is forced. |
Methods
-
CSS
CSS variables to theme the components. Set them on an ancestor or the component itself.
CCarousel CSS variables
Apply these variables to CCarousel or one of its ancestors.
| Variable | Type | Purpose | Default |
|---|---|---|---|
--cui-carousel-background | color | Root background. | transparent |
--cui-carousel-foreground | color | Root foreground. | CanvasText |
--cui-carousel-border-color | color | Surface boundaries. | Scheme-aware neutral. |
--cui-carousel-radius | length | Root viewport and Slide radius. | 0.9rem |
--cui-carousel-gap | length | Slide and region gap. | Size-derived. |
--cui-carousel-padding | length | Root padding. | Size-derived. |
--cui-carousel-block-size | length | Vertical viewport and Slide block size. | 20rem |
--cui-carousel-control-background | color | Previous and next Button background. | Scheme-aware neutral. |
--cui-carousel-control-foreground | color | Previous and next Button foreground. | CanvasText |
--cui-carousel-control-size | length | Previous and next Button size. | Size-derived. |
--cui-carousel-focus-color | color | Focus ring. | Highlight |
--cui-carousel-indicator-size | length | Picker dot size. | 0.65rem |
--cui-carousel-indicator-color | color | Inactive picker color. | Scheme-aware neutral. |
--cui-carousel-indicator-active-color | color | Current picker color. | Highlight |
--cui-carousel-duration | time | Reserved scroll transition duration and reduced-motion input. | 260ms |
--cui-carousel-easing | easing | Reserved scroll transition easing. | ease-out |
Attributes
HTML attributes defined on the components that you can refer to for CSS, inspection, and testing. Read-only.
CCarousel attributes
| Attribute | Element | Type | Meaning |
|---|---|---|---|
role | Root and Slide | "region" | "group" | Identifies carousel region and Slide groups. |
aria-label | Root Slide controls and picker group | string | Names each owned semantic surface. |
aria-roledescription | Root and Slide | "carousel" | "slide" | Supplies concise role descriptions. |
data-orientation | Root | CCarouselOrientation | Reflects scroll axis. |
data-loop | Root | present | absent | Reflects boundary wrapping. |
data-disabled | Root | present | absent | Reflects owned disabledness. |
data-draggable | Root | present | absent | Reflects fine-pointer drag availability. |
data-variant | Root | CCarouselVariant | Reflects treatment. |
data-size | Root | CCarouselSize | Reflects geometry. |
data-index | Root Slide and picker | integer string | Reflects active or collection position according to destination. |
data-value | Slide | string | Reflects stable Slide identity. |
data-active | Current Slide | present | absent | Reflects the nearest selected snap point. |
disabled | Owned Buttons | present | absent | Reflects navigation availability. |
aria-current | Current picker | "true" | Identifies the picker for the active Slide. |
tabindex | Viewport | "0" | Makes the native scroll region keyboard reachable. |
Selectors
Selectors for the DOM nodes in the components that you can use for CSS, inspection, and testing.
CCarousel selectors
| Selector | Element | Purpose |
|---|---|---|
[data-citry-ui-part="carousel"] | section | Root state and styling boundary. |
[data-citry-ui-part="controls"] | div | Previous and next control row. |
[data-citry-ui-part="previous"] | Button | Previous control. |
[data-citry-ui-part="next"] | Button | Next control. |
[data-citry-ui-part="viewport"] | div | Native Scroll Snap viewport. |
[data-citry-ui-part="track"] | div | Direct Slide layout track. |
[data-citry-ui-part="slide"] | div | Named composed Slide. |
[data-citry-ui-part="indicators"] | div | Picker Button group. |
[data-citry-ui-part="indicator"] | Button | Runtime picker for one Slide. |
Interfaces
Aliases and data shapes referenced above.
Input type aliases
| Interface | Definition |
|---|---|
CClassValue | str | Mapping[str, bool] | Sequence[CClassValue] |
CStyleValue | str | Mapping[str, str | int | float | bool | None] | Sequence[CStyleValue] |
CCarouselOrientation | Literal["horizontal", "vertical"] |
CCarouselVariant | Literal["plain", "surface"] |
CCarouselSize | Literal["sm", "md", "lg"] |
CCarouselDefaultSlotData
Empty dataclass: {}.
CCarouselSlideDefaultSlotData
Empty dataclass: {}.
CCarouselIndexChangeDetail
| Field | Type | Default | Meaning |
|---|---|---|---|
index | int | - | Requested active index. |
previousIndex | int | - | Previously effective index. |
value | str | - | Stable requested Slide value. |
reason | string | - | Request source. |
controlled | boolean | - | Whether client index owns state. |
forced | boolean | - | Whether structure forced fallback. |
source | EventTarget | null | - | Browser source. |
Translation keys
Catalog keys used by this family. An explicit component input or slot listed in Override takes precedence over the catalog for that instance.
CCarousel translation keys
| Key | Purpose | Variables | Override | Browser updates |
|---|---|---|---|---|
citry-ui-carousel-previous | Names the previous-slide control. | None | previous_label input | $c-tr updates aria-label. |
citry-ui-carousel-next | Names the next-slide control. | None | next_label input | $c-tr updates aria-label. |
citry-ui-carousel-picker | Names the slide-picker group. | None | picker_label input | $c-tr updates aria-label. |
citry-ui-carousel-role | Describes the carousel region role. | None | role_description input | $c-tr updates aria-roledescription. |
CCarouselSlide translation keys
| Key | Purpose | Variables | Override | Browser updates |
|---|---|---|---|---|
citry-ui-carousel-slide-role | Describes each slide group role. | None | role_description input | $c-tr updates aria-roledescription. |