## Carousel Use the Carousel component to cycle through elements like a slideshow. Category: Data Display ### CSS Extensions As of DMC 1.2.0, `Carousel` component styles are bundled automatically, so you no longer need to include a separate CSS file. If you're using an older version of DMC, refer to the [migration guide](/migration) for instructions on including optional stylesheets. ### Simple Example ```python import dash_mantine_components as dmc component = dmc.Carousel( [ dmc.CarouselSlide(dmc.Center("Slide-1", bg="blue", c="white", p=60)), dmc.CarouselSlide(dmc.Center("Slide-2", bg="blue", c="white", p=60)), dmc.CarouselSlide(dmc.Center("Slide-3", bg="blue", c="white", p=60)), ], id="carousel-simple", ) ``` ### Options ### Size and Gap Set `slideSize` and `slideGap` on `Carousel` component to control size and gap of every slide: ```python import dash_mantine_components as dmc component = dmc.Carousel( [ dmc.CarouselSlide(dmc.Center(f"Slide {i}", bg="blue", c="white", h="100%")) for i in range(1, 7) ], id="carousel-size", withIndicators=True, height=200, slideSize="33.3333%", slideGap="md", emblaOptions = {"loop": True, "align": "start", "slidesToScroll": 3}, ) ``` ### Responsive styles `slideSize` and `slideGap` props work the same way as `style` props, you can pass an object with values for different breakpoints: ```python import dash_mantine_components as dmc component = dmc.Carousel( [ dmc.CarouselSlide( dmc.Center(f"Slide {i}", ta="center", bg="blue", c="white", h="100%") ) for i in range(1, 7) ], id="carousel-responsive", withIndicators=True, height=200, slideSize={"base": "100%", "sm": "50%", "md": "33.333333%"}, slideGap={"base": 0, "sm": "md"}, emblaOptions = {"loop": True, "align": "start"}, ) ``` ### Drag free `dragFree` will disable slides snap points – user will be able to stop dragging at any position: ```python import dash_mantine_components as dmc component = dmc.Carousel( [ dmc.CarouselSlide( dmc.Center(f"Slide {i}", ta="center", bg="blue", c="white", h="100%") ) for i in range(1, 7) ], id="carousel-drag-free", withIndicators=True, height=200, slideGap="md", emblaOptions = {"loop": True, "align": "start", "dragFree": True}, ) ``` ### Vertical orientation Carousel with `orientation="vertical"` requires `height` prop to be set: ```python import dash_mantine_components as dmc component = dmc.Carousel( [ dmc.CarouselSlide( dmc.Center(f"Slide {i}", ta="center", bg="blue", c="white", h="100%") ) for i in range(1, 7) ], id="carousel-vertical", orientation="vertical", withIndicators=True, height=200, emblaOptions={"loop": True}, ) ``` ### Controls icons You can replace default next/previous controls icons with any component: ```python import dash_mantine_components as dmc from dash_iconify import DashIconify component = dmc.Carousel( [ dmc.CarouselSlide( dmc.Center(f"Slide {i}", ta="center", bg="blue", c="white", h="100%") ) for i in range(1, 7) ], id="carousel-controls_icons", withIndicators=True, height=180, nextControlIcon=DashIconify(icon="bi:arrow-right-circle-fill", width=30), previousControlIcon=DashIconify(icon="bi:arrow-left-circle-fill", width=30), emblaOptions = {"loop": True}, ) ``` ### Autoscroll Enable autoscroll by setting `autoScroll=True` or by passing in a `dict` with options. Refer to [Embla Carousel Auto Scroll Options](https://www.embla-carousel.com/plugins/auto-scroll/#options) to learn more. ```python import dash_mantine_components as dmc component = dmc.Carousel( [ dmc.CarouselSlide(dmc.Center("Slide-1", bg="blue", c="white", p=60)), dmc.CarouselSlide(dmc.Center("Slide-2", bg="blue", c="white", p=60)), dmc.CarouselSlide(dmc.Center("Slide-3", bg="blue", c="white", p=60)), ], id="carousel-autoscroll", emblaOptions={"loop": True}, autoScroll=True, ) ``` ### Autoplay Enable autoplay by setting `autoplay=True` or by passing in a `dict` with options. Refer to [Embla Carousel Autoplay Options](https://www.embla-carousel.com/plugins/autoplay/#options) to learn more. ```python import dash import dash_mantine_components as dmc from dash import html, callback, Input, Output component = html.Div([ dmc.Carousel( [ dmc.CarouselSlide(dmc.Center("Slide-1", bg="blue", c="white", p=60)), dmc.CarouselSlide(dmc.Center("Slide-2", bg="blue", c="white", p=60)), dmc.CarouselSlide(dmc.Center("Slide-3", bg="blue", c="white", p=60)), ], id="carousel-autoplay", mt="sm", emblaOptions={"loop": True}, autoplay=True, # Default delay is 4000ms ) ]) ``` Here’s an example of passing props to the Embla component. In this example, the `delay` is set to 2000ms, and autoplay pauses when hovering over a slide: ```python autoplay={"delay": 2000, "stopOnMouseEnter": True, "stopOnInteraction":False} ``` ### Carousel Styles API Carousel supports Styles API, you can add styles to any inner element of the component with `classNames` prop. Refer to the [Styles API documentation](/styles-api) to learn more. ### Carousel Indicator styles This example styles the indicators to emphasize the active slide. ```python import dash_mantine_components as dmc component = dmc.Carousel( [ dmc.CarouselSlide(dmc.Center(f"Slide {i}", bg="blue", c="white", h="100%")) for i in range(1, 4) ], id="carousel-indicator-styles", withIndicators=True, height=200, emblaOptions = {"loop": True}, classNames={"indicator": "dmc-indicator"}, ) ``` Put the following in a .css file in the `assets` folder: ```css .dmc-indicator { width: 12px; height: 4px; transition: width 250ms ease; &[data-active] { width: 40px; } } ``` ### Hide inactive controls ```python import dash_mantine_components as dmc component = dmc.Carousel( [ dmc.CarouselSlide(dmc.Center(f"Slide {i}", bg="blue", c="white", h="100%")) for i in range(1, 4) ], id="carousel-hide-inactive-controls", height=200, classNames={"control": "dmc-control"}, ) ``` Put the following in a .css file in the `assets` folder: ```css .dmc-control { &[data-inactive] { opacity: 0; cursor: default; } } ``` ### Show controls on hover ```python import dash_mantine_components as dmc component = dmc.Carousel( [ dmc.CarouselSlide(dmc.Center(f"Slide {i}", bg="blue", c="white", h="100%")) for i in range(1, 4) ], id="carousel-show-controls-on-hover", height=200, classNames={"controls": "dmc-controls", "root": "dmc-root"}, ) ``` Put the following in a .css file in the `assets` folder: ```css .dmc-controls { transition: opacity 150ms ease; opacity: 0; } .dmc-root { &:hover { .dmc-controls { opacity: 1; } } } ``` ### Set initial slide To set the initial slide to display, use the index number of the slide. ```python import dash_mantine_components as dmc from dash import Input, Output, callback, no_update component = dmc.Paper( [ dmc.Select( label="Set initial slide", data=[str(i) for i in range(6)], value="0", id="carousel-input", mb=10, ), dmc.Carousel( [ dmc.CarouselSlide( dmc.Center( f"Slide {i}", ta="center", bg="blue", c="white", h="100%" ) ) for i in range(6) ], id="carousel-initial", height=200, emblaOptions = {"loop": True, "align": "start"}, ), ] ) @callback( Output("carousel-initial", "initialSlide"), Input("carousel-input", "value"), ) def go_to_slide(value): return int(value) ``` ### Container queries To use container queries instead of media queries, set `type="container"`. With container queries, slides size and gap will be adjusted based on the container width, not the viewport width. Note that, when using container queries, `slideSize` and `slideGap` props cannot reference `theme.breakpoints` values in keys. It is required to use exact `px` or `em` values. To see how the slides size and gap changes, resize the root element of the demo with the resize handle located at the bottom right corner of the demo: ```python import dash_mantine_components as dmc from dash import html component = html.Div( # Wrapper div is added for demonstration purposes only, # It is not required in real projects dmc.Carousel( [ dmc.CarouselSlide(dmc.Center("Slide-1", bg="blue", c="white", p=60)), dmc.CarouselSlide(dmc.Center("Slide-2", bg="blue", c="white", p=60)), dmc.CarouselSlide(dmc.Center("Slide-3", bg="blue", c="white", p=60)), ], id="carousel-container", type="container", slideSize = {"base": '100%', '300px': '50%', '500px': '33.333333%'}, slideGap = {"base": 0, '300px': 'md', '500px': 'lg'}, emblaOptions = {"loop": True, "align": "start"}, ), style={ "resize": 'horizontal', "overflow": 'hidden', "maxWidth": '100%', "minWidth": 250, "padding": 10, } ) ``` ### Active prop for callbacks The `active` prop represents the index of the currently displayed slide and can be used to trigger Dash callbacks. Note that this prop is read-only. To set the initially displayed slide, use the `initialSlide` prop instead. ### Example Image Carousel ```python import dash_mantine_components as dmc images = [ "https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/images/bg-1.png", "https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/images/bg-2.png", "https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/images/bg-3.png", "https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/images/bg-4.png", "https://raw.githubusercontent.com/mantinedev/mantine/master/.demo/images/bg-5.png", ] component = dmc.Carousel( [dmc.CarouselSlide(dmc.Image("Slide 1", src=image)) for image in images], id="carousel-images", withIndicators=True, w=400, ) ``` ### Example Card Carousel ```python import dash_mantine_components as dmc from dash import html data = [ { "image": "https://images.unsplash.com/photo-1508193638397-1c4234db14d8?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80", "title": "Best forests to visit in North America", "category": "NATURE", }, { "image": "https://images.unsplash.com/photo-1559494007-9f5847c49d94?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80", "title": "Hawaii beaches review: better than you think", "category": "BEACH", }, { "image": "https://images.unsplash.com/photo-1608481337062-4093bf3ed404?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80", "title": "Mountains at night: 12 best locations to enjoy the view", "category": "NATURE", }, { "image": "https://images.unsplash.com/photo-1510798831971-661eb04b3739?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80", "title": "Best places to visit this winter", "category": "TOURISM", }, { "image": "https://images.unsplash.com/photo-1582721478779-0ae163c05a60?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80", "title": "Active volcanos reviews: travel at your own risk", "category": "NATURE", }, ] def make_card(image, title, category): return dmc.Paper( [ html.Div( [ dmc.Text(category, c="white", opacity=0.7, fw=700), dmc.Title(title, lh=1.2, order=3, mt="xs", fw=900, c="white"), ] ), dmc.Button("Read Article", variant="white", color="dark"), ], shadow="md", p="xl", radius="md", style={ "backgroundImage": f"url({image})", "height": 440, "display": "flex", "flexDirection": "column", "justifyContent": "space-between", "alignItems": "flex-start", "backgroundSize": "cover", "backgroundPosition": "center", }, ) component = dmc.Carousel( [dmc.CarouselSlide(make_card(d["image"], d["title"], d["category"])) for d in data], id="carousel-cards", w=400, emblaOptions={"loop": True, "align": "start"}, ) ``` ### Limitation: Carousel in Tabs When a Carousel is placed inside a tab, it may not render correctly. For more details, refer to [GitHub Issue #299]((https://github.com/snehilvj/dash-mantine-components/issues/299). As a workaround, you can update the carousel within the tabs using a callback. Be sure to give a unique id to each carousel in the app. ```python import dash_mantine_components as dmc from dash import html, Input, Output, callback def make_carousel(id): return dmc.Carousel( emblaOptions={"loop": True}, withIndicators=True, children=[ dmc.CarouselSlide( dmc.Center( slide, bg="blue", c="white", p=60, ) ) for slide in ["Slide 1", "Slide 2", "Slide 3"] ], id=id, ) component = html.Div( [ dmc.Tabs( [ dmc.TabsList( [ dmc.TabsTab("Tab one", value="1"), dmc.TabsTab("Tab two", value="2"), ] ), ], id="tabs-carousel-example", value="1", ), html.Div(id="tabs-carousel-content", style={"paddingTop": 10}), ] ) @callback( Output("tabs-carousel-content", "children"), Input("tabs-carousel-example", "value") ) def render_content(active): if active == "1": return [dmc.Text("Tab One selected", my=10), make_carousel("carousel-tab1")] else: return [dmc.Text("Tab Two selected", my=10), make_carousel("carousel-tab2")] ``` ### Limitation: draggable and speed Props As of DMC v0.14.7, the `draggable` and `speed` props no longer work because Embla Carousel v8 has removed them. These props will be removed in DMC v1.0.0 ### Styles API This component supports Styles API. With Styles API, you can customize styles of any inner element. See the Styling and Theming sections of these docs for more information. #### Carousel selectors | Selector | Static selector | Description | |------------|------------------------------|----------------------------------------------------------| | root | .mantine-Carousel-root | Root element | | slide | .mantine-Carousel-slide | Carousel.Slide root element | | container | .mantine-Carousel-container | Slides container | | viewport | .mantine-Carousel-viewport | Main element, contains slides container and all controls | | controls | .mantine-Carousel-controls | Next/previous controls container | | control | .mantine-Carousel-control | Next/previous control | | indicators | .mantine-Carousel-indicators | Indicators container | | indicator | .mantine-Carousel-indicator | Indicator button | #### Carousel CSS variables | Selector | Variable | Description | |----------|----------------------------|------------------------------------------------------------| | root | --carousel-control-size | Controls `width` and `height` of the next/previous buttons | | root | --carousel-controls-offset | Controls offsets of the next/previous buttons | | root | --carousel-height | Controls height of the carousel | #### Carousel data attributes | Selector | Attribute | Condition | Value | |------------|------------------------------|------------------------------------------|------------------------------| | root | data-orientation | – | Value of `orientation` prop | | root | data-include-gap-in-size | `includeGapInSize` prop is set | – | | control | data-inactive | No previous/next slides are available | – | | indicator | data-active | Associated slide is active | – | ### Keyword Arguments #### Carousel - children (a list of or a singular dash component, string or number; optional): components. - id (string; optional): Unique ID to identify this component in Dash callbacks. - active (number; default 0): The index of the current slide. Read only. Use initialSlide to set the current slide. - aria-* (string; optional): Wild card aria attributes. - attributes (boolean | number | string | dict | list; optional): Passes attributes to inner elements of a component. See Styles API docs. - autoScroll (boolean; optional): Enables autoScroll with optional configuration. - autoplay (boolean; optional): Enables autoplay with optional configuration. - className (string; optional): Class added to the root element, if applicable. - classNames (dict; optional): Adds custom CSS class names to inner elements of a component. See Styles API docs. - controlSize (string | number; optional): Controls size of the next and previous controls, `26` by default. - controlsOffset (number; optional): Controls position of the next and previous controls, key of `theme.spacing` or any valid CSS value, `'sm'` by default. - darkHidden (boolean; optional): Determines whether component should be hidden in dark color scheme with `display: none`. - data-* (string; optional): Wild card data attributes. - emblaOptions (dict; optional): options to pass to the embla component. - height (string | number; optional): Slides container `height`, required for vertical orientation. - hiddenFrom (string; optional): Breakpoint above which the component is hidden with `display: none`. - includeGapInSize (boolean; optional): Determines whether gap between slides should be treated as part of the slide size, `True` by default. - initialSlide (number; default 0): Index of initial slide. - lightHidden (boolean; optional): Determines whether component should be hidden in light color scheme with `display: none`. - loading_state (dict; optional): Object that holds the loading state object coming from dash-renderer. For use with dash<3. `loading_state` is a dict with keys: - mod (string | dict | list of string | dicts; optional): Element modifiers transformed into `data-` attributes. For example: "xl" or {"data-size": "xl"}. Can also be a list of strings or dicts for multiple modifiers. Falsy values are removed. - nextControlIcon (a list of or a singular dash component, string or number; optional): Icon of the next control. - orientation (a value equal to: 'horizontal', 'vertical'; optional): Carousel orientation, `'horizontal'` by default. - previousControlIcon (a list of or a singular dash component, string or number; optional): Icon of the previous control. - slideGap (number; optional): Key of theme.spacing or number to set gap between slides. - slideSize (string | number; optional): Controls slide width based on viewport width, `'100%'` by default. - styles (boolean | number | string | dict | list; optional): Adds inline styles directly to inner elements of a component. See Styles API docs. - tabIndex (number; optional): tab-index. - type (a value equal to: 'media', 'container'; optional): Determines typeof of queries that are used for responsive styles, 'media' by default. - variant (string; optional): variant. - visibleFrom (string; optional): Breakpoint below which the component is hidden with `display: none`. - withControls (boolean; optional): Determines whether next/previous controls should be displayed, True by default. - withIndicators (boolean; optional): Determines whether indicators should be displayed, `False` by default. - withKeyboardEvents (boolean; optional): Determines whether arrow key should switch slides, `True` by default. #### CarouselSlide - children (a list of or a singular dash component, string or number; optional): Content. - id (string; optional): Unique ID to identify this component in Dash callbacks. - aria-* (string; optional): Wild card aria attributes. - attributes (boolean | number | string | dict | list; optional): Passes attributes to inner elements of a component. See Styles API docs. - className (string; optional): Class added to the root element, if applicable. - classNames (dict; optional): Adds custom CSS class names to inner elements of a component. See Styles API docs. - darkHidden (boolean; optional): Determines whether component should be hidden in dark color scheme with `display: none`. - data-* (string; optional): Wild card data attributes. - hiddenFrom (string; optional): Breakpoint above which the component is hidden with `display: none`. - lightHidden (boolean; optional): Determines whether component should be hidden in light color scheme with `display: none`. - loading_state (dict; optional): Object that holds the loading state object coming from dash-renderer. For use with dash<3. `loading_state` is a dict with keys: - mod (string | dict | list of string | dicts; optional): Element modifiers transformed into `data-` attributes. For example: "xl" or {"data-size": "xl"}. Can also be a list of strings or dicts for multiple modifiers. Falsy values are removed. - styles (boolean | number | string | dict | list; optional): Adds inline styles directly to inner elements of a component. See Styles API docs. - tabIndex (number; optional): tab-index. - variant (string; optional): variant. - visibleFrom (string; optional): Breakpoint below which the component is hidden with `display: none`.