---
title: Carousel
---
The QCarousel component allows you to display more information with less real estate, using slides. Useful for creating Wizards or an image gallery too.

## QCarousel API

### Props

- `fullscreen` (boolean, optional, syncable)
  Fullscreen mode
  Required to be used with v-model.
  Examples: `v-model:fullscreen="isFullscreen"`
- `no-route-fullscreen-exit` (boolean, optional)
  Changing route app won't exit fullscreen
- `model-value` (any, required)
  Model of the component defining the current panel's name; If a Number is used, it does not define the panel's index, but rather the panel's name which can also be an Integer; Either use this property (along with a listener for 'update:model-value' event) OR use the v-model directive.
  Examples: `v-model="panelName"`
- `keep-alive` (boolean, optional)
  Equivalent to using Vue's native <keep-alive> component on the content
- `keep-alive-include` (string | any[] | RegExp, optional)
  Equivalent to using Vue's native include prop for <keep-alive>; Values must be valid Vue component names
  Examples:
    - `'a,b'`
    - `/a|b/`
    - `['a', 'b']`
- `keep-alive-exclude` (string | any[] | RegExp, optional)
  Equivalent to using Vue's native exclude prop for <keep-alive>; Values must be valid Vue component names
  Examples:
    - `'a,b'`
    - `/a|b/`
    - `['a', 'b']`
- `keep-alive-max` (number, optional)
  Equivalent to using Vue's native max prop for <keep-alive>
- `animated` (boolean, optional)
  Enable transitions between panel (also see 'transition-prev' and 'transition-next' props)
- `infinite` (boolean, optional)
  Makes component appear as infinite (when reaching last panel, next one will become the first one)
- `swipeable` (boolean, optional)
  Enable swipe events (may interfere with content's touch/mouse events)
- `vertical` (boolean, optional)
  Default transitions and swipe actions will be on the vertical axis
- `transition-prev` (string, optional), default `'fade'`
  One of Quasar's embedded transitions (has effect only if 'animated' prop is set)
  Examples: `'fade'`, `'slide-down'`
- `transition-next` (string, optional), default `'fade'`
  One of Quasar's embedded transitions (has effect only if 'animated' prop is set)
  Examples: `'fade'`, `'slide-down'`
- `transition-duration` (string | number, optional), default `300`
  Transition duration (in milliseconds, without unit)
- `dark` (boolean, optional), default `null`
  Notify the component that the background is a dark color
- `height` (string, optional)
  Height of Carousel in CSS units, including unit name
  Examples: `'16px'`, `'2rem'`
- `padding` (boolean, optional)
  Applies a default padding to each slide, according to the usage of 'arrows' and 'navigation' props
- `control-color` (string, optional)
  Color name for QCarousel button controls (arrows, navigation) from the Quasar Color Palette
  Examples: `'primary'`, `'teal'`, `'teal-10'`
- `control-text-color` (string, optional)
  Color name for text color of QCarousel button controls (arrows, navigation) from the Quasar Color Palette
  Examples: `'primary'`, `'teal'`, `'teal-10'`
- `control-type` (string, optional), default `'flat'`
  Type of button to use for controls (arrows, navigation)
  Accepts: `'regular'`, `'flat'`, `'outline'`, `'push'`, `'unelevated'`
- `autoplay` (number | boolean, optional)
  Jump to next slide (if 'true' or val > 0) or previous slide (if val < 0) at fixed time intervals (in milliseconds); 'false' disables autoplay, 'true' enables it for 5000ms intervals
  Examples: `true`, `false`, `2500`
- `arrows` (boolean, optional)
  Show navigation arrow buttons
- `prev-icon` (string, optional)
  Icon name following Quasar convention; Make sure you have the icon library installed unless you are using 'img:' prefix; If 'none' (String) is used as value then no icon is rendered (but screen real estate will still be used for it)
  Examples: `'map'`, `'ion-add'`, `'img:https://cdn.quasar.dev/logo-v2/svg/logo.svg'`, `'img:path/to/some_image.png'`
- `next-icon` (string, optional)
  Icon name following Quasar convention; Make sure you have the icon library installed unless you are using 'img:' prefix; If 'none' (String) is used as value then no icon is rendered (but screen real estate will still be used for it)
  Examples: `'map'`, `'ion-add'`, `'img:https://cdn.quasar.dev/logo-v2/svg/logo.svg'`, `'img:path/to/some_image.png'`
- `navigation` (boolean, optional)
  Show navigation dots
- `navigation-position` (string, optional), default `'bottom'/'right'`
  Side to stick navigation to
  Accepts: `'top'`, `'right'`, `'bottom'`, `'left'`
- `navigation-icon` (string, optional)
  Icon name following Quasar convention; Make sure you have the icon library installed unless you are using 'img:' prefix; If 'none' (String) is used as value then no icon is rendered (but screen real estate will still be used for it)
  Examples: `'map'`, `'ion-add'`, `'img:https://cdn.quasar.dev/logo-v2/svg/logo.svg'`, `'img:path/to/some_image.png'`
- `navigation-active-icon` (string, optional)
  Icon name following Quasar convention for the active (current slide) navigation icon; Make sure you have the icon library installed unless you are using 'img:' prefix
  Examples: `'map'`, `'ion-add'`, `'img:https://cdn.quasar.dev/logo-v2/svg/logo.svg'`, `'img:path/to/some_image.png'`
- `thumbnails` (boolean, optional)
  Show thumbnails

### Methods

- `toggleFullscreen(): void`
  Toggle the view to be fullscreen or not fullscreen
- `setFullscreen(): void`
  Enter the fullscreen view
- `exitFullscreen(): void`
  Leave the fullscreen view
- `next(): void`
  Go to next panel
- `previous(): void`
  Go to previous panel
- `goTo(panelName: string | number): void`
  Go to specific panel
  Params:
    - `panelName` (string | number, required)
      Panel's name, which may be a String or Number; Number does not refers to panel index, but to its name, which may be an Integer
      Examples: `'dashboard'`

### Events

- `@fullscreen`
  Emitted when fullscreen state changes
  Params:
    - `value` (boolean, optional)
      Fullscreen state (showing/hidden)
- `@update:fullscreen`
  Used by Vue on 'v-model:fullscreen' prop for updating its value
  Params:
    - `value` (boolean, optional)
      Fullscreen state (showing/hidden)
- `@update:model-value`
  Emitted when the component changes the model; This event _isn't_ fired if the model is changed externally; Is also used by v-model
  Params:
    - `value` (string | number, optional)
      New current panel name
      Examples: `'dashboard'`
- `@before-transition`
  Emitted before transitioning to a new panel
  Params:
    - `newVal` (string | number, optional)
      Panel name towards transition is going
      Examples: `'dashboard'`
    - `oldVal` (string | number, optional)
      Panel name from which transition is happening
      Examples: `'dashboard'`
- `@transition`
  Emitted after component transitioned to a new panel
  Params:
    - `newVal` (string | number, optional)
      Panel name towards transition has occurred
      Examples: `'dashboard'`
    - `oldVal` (string | number, optional)
      Panel name from which transition has happened
      Examples: `'dashboard'`

### Slots

- `#default`
  Suggestion: QCarouselSlide
- `#control`
  Slot specific for QCarouselControl

### Scoped Slots

- `#navigation-icon`
  Slot for navigation icon/btn; Suggestion: QBtn
  Scope:
    - `index` (number, optional)
      The 0-based index of corresponding slide
    - `maxIndex` (number, optional)
      The available number of slides
    - `name` (any, optional)
      The name of the corresponding slide
    - `active` (boolean, optional)
      Is this the current slide?
    - `btnProps` (object, optional)
      Default QBtn props that can be binded to your own QBtn
    - `onClick` (Function, optional)
      Default trigger when clicked/tapped on
      Function signature: `(evt: Event) => void`
      Params:
        - `evt` (Event, required)
          JS event object

## QCarouselControl API

### Props

- `position` (string, optional), default `'bottom-right'`
  Side/corner to stick to
  Accepts: `'top-right'`, `'top-left'`, `'bottom-right'`, `'bottom-left'`, `'top'`, `'right'`, `'bottom'`, `'left'`
- `offset` (any[], optional), default `[18, 18]`
  An array of two numbers to offset the component horizontally and vertically (in pixels)
  Examples:
    - `[8, 8]`
    - `[5, 10]`

### Slots

- `#default`
  Default slot in the devland unslotted content of the component

## QCarouselSlide API

### Props

- `name` (any, required)
  Slide name
  Examples: `'accounts'`, `'firstPanel'`, `1`
- `disable` (boolean, optional)
  Put component in disabled mode
- `img-src` (string, optional)
  URL pointing to a slide background image (use public folder)
  Examples: `(public folder) src="img/my-bg.png"`, `(assets folder) src="~@/assets/my-img.png"`, `(relative path format) :src="require('./my_img.jpg')"`, `(URL) src="https://picsum.photos/500/300"`

### Slots

- `#default`
  Default slot in the devland unslotted content of the component

## Usage

> [!TIP]
> If the QCarouselSlide content also has images and you want to use swipe actions to navigate, you might want to add `draggable="false"` to them, otherwise the native browser behavior might interfere in a negative way.

> [!IMPORTANT]
> **Keep Alive**
>
> - Please take notice of the Boolean `keep-alive` prop for QCarousel, if you need this behavior. Do NOT use Vue's native `<keep-alive>` component over QCarouselSlide.
> - Should you need the `keep-alive-include` or `keep-alive-exclude` props then the QCarouselSlide `name`s must be valid Vue component names (no spaces allowed, don't start with a number etc).

### Basic

Below is an almost stripped down basic Carousel (it is just animated and only has custom transitions specified) with no navigation embedded. For this reason, we are controlling the current slide through the model.

```vue
<template>
  <q-carousel
    v-model="slide"
    transition-prev="slide-right"
    transition-next="slide-left"
    animated
    control-color="primary"
    class="rounded-borders"
  >
    <q-carousel-slide name="style" class="column no-wrap flex-center">
      <q-icon name="style" color="primary" size="56px" />
      <div class="q-mt-md text-center">
        {{ lorem }}
      </div>
    </q-carousel-slide>
    <!-- ... -->
  </q-carousel>

  <div class="row justify-center">
    <q-btn-toggle
      glossy
      v-model="slide"
      :options="[
        { label: 1, value: 'style' },
        { label: 2, value: 'tv' },
        { label: 3, value: 'layers' },
        { label: 4, value: 'map' }
      ]"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const slide = ref('style')
const lorem =
  'Lorem ipsum dolor, sit amet consectetur adipisicing elit. Itaque voluptatem totam, architecto cupiditate officia rerum, error dignissimos praesentium libero ab nemo provident incidunt ducimus iusto perferendis porro earum. Totam, numquam?'
</script>
```

### Transitions

In the example below:

- There are just a few transitions demoed. For a complete list of transitions, head to the [Transitions](../options/transitions.md) page.
- You can also swipe with your finger (or swiping with the mouse -- clicking and quickly dragging to left/right then releasing).

Example "Transitions, bottom navigation, arrows and auto padding":

```vue
<template>
  <div class="q-gutter-md">
    <q-carousel
      v-model="slide"
      transition-prev="scale"
      transition-next="scale"
      swipeable
      animated
      control-color="white"
      navigation
      padding
      arrows
      height="300px"
      class="bg-primary text-white shadow-1 rounded-borders"
    >
      <q-carousel-slide name="style" class="column no-wrap flex-center">
        <q-icon name="style" size="56px" />
        <div class="q-mt-md text-center">
          {{ lorem }}
        </div>
      </q-carousel-slide>
      <!-- ... -->
    </q-carousel>

    <q-carousel
      v-model="slide"
      transition-prev="jump-right"
      transition-next="jump-left"
      swipeable
      animated
      control-color="white"
      prev-icon="arrow_left"
      next-icon="arrow_right"
      navigation-icon="radio_button_unchecked"
      navigation
      padding
      arrows
      height="300px"
      class="bg-purple text-white shadow-1 rounded-borders"
    >
      <q-carousel-slide name="style" class="column no-wrap flex-center">
        <q-icon name="style" size="56px" />
        <div class="q-mt-md text-center">
          {{ lorem }}
        </div>
      </q-carousel-slide>
      <!-- ... -->
    </q-carousel>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const slide = ref('style')
const lorem =
  'Lorem ipsum dolor, sit amet consectetur adipisicing elit. Itaque voluptatem totam, architecto cupiditate officia rerum, error dignissimos praesentium libero ab nemo.'
</script>
```

### Vertical

Example "Vertical mode":

```vue
<template>
  <q-carousel
    v-model="slide"
    vertical
    transition-prev="slide-down"
    transition-next="slide-up"
    swipeable
    animated
    control-color="white"
    navigation-icon="radio_button_unchecked"
    navigation
    padding
    arrows
    height="300px"
    class="bg-purple text-white shadow-1 rounded-borders"
  >
    <q-carousel-slide name="style" class="column no-wrap flex-center">
      <q-icon name="style" size="56px" />
      <div class="q-mt-md text-center">
        {{ lorem }}
      </div>
    </q-carousel-slide>
    <!-- ... -->
  </q-carousel>
</template>

<script setup>
import { ref } from 'vue'

const slide = ref('style')
const lorem =
  'Lorem ipsum dolor, sit amet consectetur adipisicing elit. Itaque voluptatem totam, architecto cupiditate officia rerum, error dignissimos praesentium libero ab nemo.'
</script>
```

### Control type

The notion of "control" here refers to the arrows and navigation buttons. Since they are buttons, you can also pick their type to better match your design. You also benefit from the `control-color` and `control-text-color` props.

```vue
<template>
  <q-option-group
    v-model="controlType"
    :options="controlTypeOptions"
    color="purple"
    inline
    class="q-mb-md"
  />

  <q-carousel
    v-model="slide"
    swipeable
    animated
    :control-type="controlType"
    control-color="purple"
    navigation
    padding
    arrows
    height="300px"
    class="text-purple rounded-borders"
  >
    <q-carousel-slide name="style" class="column no-wrap flex-center">
      <q-icon name="style" size="56px" />
      <div class="q-mt-md text-center">
        {{ lorem }}
      </div>
    </q-carousel-slide>
    <!-- ... -->
  </q-carousel>
</template>

<script setup>
import { ref } from 'vue'

const controlType = ref('flat')
const controlTypeOptions = [
  { value: 'regular', label: 'regular' },
  { value: 'unelevated', label: 'unelevated' },
  { value: 'flat', label: 'flat (default)' },
  { value: 'outline', label: 'outline' },
  { value: 'push', label: 'push' }
]

const slide = ref('style')
const lorem =
  'Lorem ipsum dolor, sit amet consectetur adipisicing elit. Itaque voluptatem totam, architecto cupiditate officia rerum, error dignissimos praesentium libero ab nemo.'
</script>
```

### Navigation position

```vue
<template>
  <q-option-group
    v-model="navPos"
    :options="navigationPositions"
    color="purple"
    inline
    class="q-mb-md"
  />

  <q-carousel
    v-model="slide"
    swipeable
    animated
    :navigation-position="navPos"
    navigation
    padding
    height="300px"
    class="bg-purple text-white rounded-borders"
  >
    <q-carousel-slide name="style" class="column no-wrap flex-center">
      <q-icon name="style" size="56px" />
      <div class="q-mt-md text-center">
        {{ lorem }}
      </div>
    </q-carousel-slide>
    <!-- ... -->
  </q-carousel>
</template>

<script setup>
import { ref } from 'vue'

const navPos = ref('bottom')
const navigationPositions = [
  { value: 'top', label: 'top' },
  { value: 'right', label: 'right' },
  { value: 'bottom', label: 'bottom (default)' },
  { value: 'left', label: 'left' }
]

const slide = ref('style')
const lorem =
  'Lorem ipsum dolor, sit amet consectetur adipisicing elit. Itaque voluptatem totam, architecto cupiditate officia rerum, error dignissimos praesentium libero ab nemo.'
</script>
```

### Custom navigation

For a full list of properties of the `navigation-icon` slot, please consult the API card.

```vue
<template>
  <q-carousel
    v-model="slide"
    transition-prev="scale"
    transition-next="scale"
    swipeable
    animated
    control-color="white"
    navigation
    padding
    arrows
    height="300px"
    class="bg-primary text-white shadow-1 rounded-borders"
  >
    <template #navigation-icon="{ active, btnProps, onClick }">
      <q-btn
        v-if="active"
        size="lg"
        icon="home"
        color="yellow"
        flat
        round
        dense
        @click="onClick"
      />
      <q-btn
        v-else
        size="sm"
        :icon="btnProps.icon"
        color="white"
        flat
        round
        dense
        @click="onClick"
      />
    </template>

    <q-carousel-slide name="style" class="column no-wrap flex-center">
      <q-icon name="style" size="56px" />
      <div class="q-mt-md text-center">
        {{ lorem }}
      </div>
    </q-carousel-slide>
    <!-- ... -->
  </q-carousel>
</template>

<script setup>
import { ref } from 'vue'

const slide = ref('style')
const lorem =
  'Lorem ipsum dolor, sit amet consectetur adipisicing elit. Itaque voluptatem totam, architecto cupiditate officia rerum, error dignissimos praesentium libero ab nemo.'
</script>
```

### Accessibility *(v2.25+)*

The navigation buttons (or thumbnails) render as a [`tablist`](https://www.w3.org/TR/wai-aria-1.2/#tablist) with `aria-orientation` matching the carousel direction; each of them is a `tab` with a roving tabindex, `aria-selected` and its slide's `name` as accessible name, while each slide is a `tabpanel`. The previous/next arrows are buttons with localized accessible names from the [Quasar Language Pack](../options/quasar-language-packs.md).

Two limits to design around: a swipe-only carousel — no `arrows` and no `navigation`/`thumbnails` — offers no keyboard way at all to change slides, so always enable at least one of them. And `autoplay` does not pause on hover or focus, so when using it provide a pause control (e.g. a button toggling the `autoplay` prop) — [WCAG 2.2.2](https://www.w3.org/WAI/WCAG22/Understanding/pause-stop-hide.html) requires a way to stop the movement.

#### Keyboard navigation

The navigation buttons (and the thumbnails, when using the `thumbnails` prop) follow the [WAI-ARIA carousel pattern](https://www.w3.org/WAI/ARIA/apg/patterns/carousel/) with a tabbed interface: they form a single Tab stop, while the arrow keys move focus within them and also select the newly focused slide, wrapping around at either end. Horizontal carousels use <kbd>Arrow Left</kbd> and <kbd>Arrow Right</kbd> (reversed in RTL mode); vertical ones use <kbd>Arrow Up</kbd> and <kbd>Arrow Down</kbd>. <kbd>Home</kbd> or <kbd>End</kbd> jumps to the first or last slide.

Each navigation element gets its slide's `name` as the accessible label — pick meaningful slide names, or supply your own labels through the `navigation-icon` slot (spread its `btnProps`, which include the ARIA attributes, then override what you need). The previous/next arrows (`arrows` prop) carry localized accessible names from the [Quasar Language Pack](../options/quasar-language-packs.md) (`carousel.prevSlide` / `carousel.nextSlide`).

### Auto padding

Below is an example with which you can play with different QCarousel settings so you can see the padding (or lack of) in action:

Example "Padding":

```vue
<template>
  <q-toggle
    v-model="padding"
    label="Padding"
    color="purple"
    class="text-weight-bold"
  />

  <q-toggle v-model="vertical" label="Vertical" color="purple" />

  <q-toggle v-model="arrows" label="Arrows" color="purple" />

  <q-toggle v-model="navigation" label="Navigation" color="purple" />

  <div class="row items-center q-mb-md">
    <div>Navigation position:</div>
    <q-option-group
      v-model="navPos"
      :options="navigationPositions"
      color="purple"
      inline
    />
  </div>

  <q-carousel
    v-model="slide"
    swipeable
    animated
    :padding="padding"
    :vertical="vertical"
    :arrows="arrows"
    :navigation="navigation"
    :navigation-position="navPos"
    height="300px"
    class="bg-purple text-white rounded-borders"
  >
    <q-carousel-slide name="style" class="column no-wrap flex-center">
      <q-icon name="style" size="56px" />
      <div class="q-mt-md text-center">
        {{ lorem }}
      </div>
    </q-carousel-slide>
    <!-- ... -->
  </q-carousel>
</template>

<script setup>
import { ref, watch } from 'vue'

const navPos = ref('bottom')
const vertical = ref(false)

watch(vertical, val => {
  navPos.value = val ? 'right' : 'bottom'
})

const padding = ref(true)
const arrows = ref(true)
const navigation = ref(true)

const navigationPositions = [
  { value: 'top', label: 'top' },
  { value: 'right', label: 'right' },
  { value: 'bottom', label: 'bottom (default)' },
  { value: 'left', label: 'left' }
]

const slide = ref('style')
const lorem =
  'Lorem ipsum dolor, sit amet consectetur adipisicing elit. Itaque voluptatem totam, architecto cupiditate officia rerum, error dignissimos praesentium libero ab nemo.'
</script>
```

### Media content

Example "Image slides":

```vue
<template>
  <q-carousel animated v-model="slide" arrows navigation infinite>
    <q-carousel-slide
      :name="1"
      img-src="https://cdn.quasar.dev/img/mountains.jpg"
    />
    <!-- ... -->
  </q-carousel>
</template>

<script setup>
import { ref } from 'vue'

const slide = ref(1)
</script>
```

Example "Multi-image slides":

```vue
<template>
  <q-carousel
    v-model="slide"
    transition-prev="slide-right"
    transition-next="slide-left"
    swipeable
    animated
    control-color="amber"
    navigation
    padding
    arrows
    height="300px"
    class="bg-grey-9 shadow-2 rounded-borders"
  >
    <q-carousel-slide :name="1" class="column no-wrap">
      <div
        class="row fit justify-start items-center q-gutter-xs q-col-gutter no-wrap"
      >
        <q-img
          class="rounded-borders col-6 full-height"
          src="https://cdn.quasar.dev/img/mountains.jpg"
        />
        <q-img
          class="rounded-borders col-6 full-height"
          src="https://cdn.quasar.dev/img/parallax1.jpg"
        />
      </div>
    </q-carousel-slide>
    <!-- ... -->
  </q-carousel>
</template>

<script setup>
import { ref } from 'vue'

const slide = ref(1)
</script>
```

Example "Captions":

```vue
<template>
  <q-carousel arrows animated v-model="slide" height="400px">
    <q-carousel-slide
      name="first"
      img-src="https://cdn.quasar.dev/img/mountains.jpg"
    >
      <div class="absolute-bottom custom-caption">
        <div class="text-h2">First stop</div>
        <div class="text-subtitle1">Mountains</div>
      </div>
    </q-carousel-slide>
    <q-carousel-slide
      name="second"
      img-src="https://cdn.quasar.dev/img/parallax1.jpg"
    >
      <div class="absolute-bottom custom-caption">
        <div class="text-h2">Second stop</div>
        <div class="text-subtitle1">Famous City</div>
      </div>
    </q-carousel-slide>
    <q-carousel-slide
      name="third"
      img-src="https://cdn.quasar.dev/img/parallax2.jpg"
    >
      <div class="absolute-bottom custom-caption">
        <div class="text-h2">Third stop</div>
        <div class="text-subtitle1">Famous Bridge</div>
      </div>
    </q-carousel-slide>
  </q-carousel>
</template>

<script setup>
import { ref } from 'vue'

const slide = ref('first')
</script>

<style lang="sass" scoped>
.custom-caption
  text-align: center
  padding: 12px
  color: white
  background-color: rgba(0, 0, 0, .3)
</style>
```

Example "Video slides":

```vue
<template>
  <div class="q-gutter-sm">
    <q-carousel animated v-model="slide" infinite>
      <q-carousel-slide name="big-buck-bunny">
        <q-video
          class="absolute-full"
          src="https://www.youtube.com/embed/aqz-KE-bpKQ"
        />
      </q-carousel-slide>

      <q-carousel-slide name="sintel">
        <q-video
          class="absolute-full"
          src="https://www.youtube.com/embed/eRsGyueVLvQ"
        />
      </q-carousel-slide>

      <q-carousel-slide name="tears-of-steel">
        <q-video
          class="absolute-full"
          src="https://www.youtube.com/embed/R6MlUcmOul8"
        />
      </q-carousel-slide>
    </q-carousel>

    <div class="row justify-center">
      <q-btn-toggle
        glossy
        v-model="slide"
        :options="[
          { label: 'Big Buck Bunny', value: 'big-buck-bunny' },
          { label: 'Sintel', value: 'sintel' },
          { label: 'Tears of Steel', value: 'tears-of-steel' }
        ]"
      />
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const slide = ref('big-buck-bunny')
</script>
```

In the example below there are thumbnails being generated automatically. Thumbnails only applies to image slides.

Example "Thumbnails":

```vue
<template>
  <q-carousel swipeable animated v-model="slide" thumbnails infinite>
    <q-carousel-slide
      :name="1"
      img-src="https://cdn.quasar.dev/img/mountains.jpg"
    />
    <!-- ... -->
  </q-carousel>
</template>

<script setup>
import { ref } from 'vue'

const slide = ref(1)
</script>
```

> [!IMPORTANT]
> Don't use the property `navigation` along with `thumbnails` as the first supercedes the latter so the thumbnails will not be displayed.

### Infinite and autoplay

You can pause autoplay when the pointer is over the carousel or over a region of interest.

Example "Autoplay":

```vue
<template>
  <q-carousel
    animated
    v-model="slide"
    navigation
    infinite
    :autoplay="autoplay"
    arrows
    transition-prev="slide-right"
    transition-next="slide-left"
    @mouseenter="autoplay = false"
    @mouseleave="autoplay = true"
  >
    <q-carousel-slide
      :name="1"
      img-src="https://cdn.quasar.dev/img/mountains.jpg"
    />
    <!-- ... -->
  </q-carousel>
</template>

<script setup>
import { ref } from 'vue'

const slide = ref(1)
const autoplay = ref(true)
</script>
```

### Controls

```vue
<template>
  <q-carousel
    swipeable
    animated
    v-model="slide"
    :autoplay="autoplay"
    ref="carouselRef"
    infinite
  >
    <q-carousel-slide
      :name="1"
      img-src="https://cdn.quasar.dev/img/mountains.jpg"
    />
    <!-- ... -->

    <template #control>
      <q-carousel-control
        position="top-right"
        :offset="[18, 18]"
        class="text-white rounded-borders"
        style="background: rgba(0, 0, 0, 0.3); padding: 4px 8px"
      >
        <q-toggle
          dense
          dark
          color="orange"
          v-model="autoplay"
          label="Auto Play"
        />
      </q-carousel-control>

      <q-carousel-control
        position="bottom-right"
        :offset="[18, 18]"
        class="q-gutter-xs"
      >
        <q-btn
          push
          round
          dense
          color="orange"
          text-color="black"
          icon="arrow_left"
          @click="$refs.carouselRef.previous()"
        />
        <q-btn
          push
          round
          dense
          color="orange"
          text-color="black"
          icon="arrow_right"
          @click="$refs.carouselRef.next()"
        />
      </q-carousel-control>
    </template>
  </q-carousel>
</template>

<script setup>
import { ref } from 'vue'

const slide = ref(1)
const autoplay = ref(false)
</script>
```

### With QScrollArea

Please note how [QScrollArea](scroll-area.md) is used in the two examples below. Also note the `q-carousel--padding` CSS helper class in the second example.

Example "With QScrollArea and padding":

```vue
<template>
  <q-carousel
    v-model="slide"
    swipeable
    animated
    padding
    arrows
    navigation
    navigation-icon="radio_button_unchecked"
    height="300px"
    class="bg-purple text-white rounded-borders"
  >
    <q-carousel-slide name="style" class="text-center">
      <q-scroll-area class="fit">
        <q-icon name="style" size="56px" />
        <div class="q-mt-md">
          {{ lorem }}
        </div>
        <!-- ... -->
      </q-scroll-area>
    </q-carousel-slide>

    <!-- ... -->
  </q-carousel>
</template>

<script setup>
import { ref } from 'vue'

const slide = ref('style')
const lorem =
  'Lorem ipsum dolor, sit amet consectetur adipisicing elit. Itaque voluptatem totam, architecto cupiditate officia rerum, error dignissimos praesentium libero ab nemo.'
</script>
```

Example "With QScrollArea on whole slide":

```vue
<template>
  <q-carousel
    v-model="slide"
    swipeable
    animated
    arrows
    navigation
    navigation-icon="radio_button_unchecked"
    control-type="regular"
    control-color="orange"
    control-text-color="grey-8"
    height="300px"
    class="bg-purple text-white rounded-borders"
  >
    <q-carousel-slide name="style" class="q-pa-none">
      <q-scroll-area class="fit">
        <div class="column no-wrap flex-center q-carousel--padding">
          <q-icon name="style" size="56px" />
          <div class="q-mt-md">
            {{ lorem }}
          </div>
          <!-- ... -->
        </div>
      </q-scroll-area>
    </q-carousel-slide>

    <!-- ... -->
  </q-carousel>
</template>

<script setup>
import { ref } from 'vue'

const slide = ref('style')
const lorem =
  'Lorem ipsum dolor, sit amet consectetur adipisicing elit. Itaque voluptatem totam, architecto cupiditate officia rerum, error dignissimos praesentium libero ab nemo.'
</script>
```

### Fullscreen

```vue
<template>
  <q-carousel
    swipeable
    animated
    arrows
    v-model="slide"
    v-model:fullscreen="fullscreen"
    infinite
  >
    <q-carousel-slide
      :name="1"
      img-src="https://cdn.quasar.dev/img/mountains.jpg"
    />
    <!-- ... -->

    <template #control>
      <q-carousel-control position="bottom-right" :offset="[18, 18]">
        <q-btn
          push
          round
          dense
          color="white"
          text-color="primary"
          :icon="fullscreen ? 'fullscreen_exit' : 'fullscreen'"
          @click="fullscreen = !fullscreen"
        />
      </q-carousel-control>
    </template>
  </q-carousel>
</template>

<script setup>
import { ref } from 'vue'

const slide = ref(1)
const fullscreen = ref(false)
</script>
```
