---
title: Dialog
related:
  - title: Dialog Plugin
    path: ../quasar-plugins/dialog.md
  - title: v-close-popup directive
    path: ../vue-directives/close-popup.md
  - title: Card
    path: card.md
  - title: Popup Proxy
    path: popup-proxy.md
---
The QDialog component is a great way to offer the user the ability to choose a specific action or list of actions. They also can provide the user with important information, or require them to make a decision (or multiple decisions).

From a UI perspective, you can think of Dialogs as a type of floating modal, which covers only a portion of the screen. This means Dialogs should only be used for quick user actions, like verifying a password, getting a short App notification or selecting an option or options quickly.

> [!TIP]
> Dialogs can also be used as a globally available method for more basic use cases, like the native JS alert(), prompt(), etc. For the latter behaviour, go to [Dialog Plugin](../quasar-plugins/dialog.md) page.

> [!TIP]
> **Masterclass TIP**
>
> Rather than cluttering your .vue templates with QDialogs, it's best if you write a component for your dialog and use the [Dialog Plugin](../quasar-plugins/dialog.md#invoking-custom-component) to invoke it from anywhere in your app.

## QDialog API

### Props

- `transition-show` (string, optional), default `'fade'`
  One of Quasar's embedded transitions
  Examples: `'fade'`, `'slide-down'`
- `transition-hide` (string, optional), default `'fade'`
  One of Quasar's embedded transitions
  Examples: `'fade'`, `'slide-down'`
- `transition-duration` (string | number, optional), default `300`
  Transition duration (in milliseconds, without unit)
- `model-value` (boolean, optional), default `null`
  Model of the component defining shown/hidden state; Either use this property (along with a listener for 'update:model-value' event) OR use v-model directive
  Examples: `v-model="state"`
- `persistent` (boolean, optional)
  User cannot dismiss Dialog if clicking outside of it or hitting ESC key; Also, an app route change won't dismiss it
- `no-esc-dismiss` (boolean, optional)
  User cannot dismiss Dialog by hitting ESC key; No need to set it if 'persistent' prop is also set
- `no-backdrop-dismiss` (boolean, optional)
  User cannot dismiss Dialog by clicking outside of it; No need to set it if 'persistent' prop is also set
- `no-route-dismiss` (boolean, optional)
  Changing route app won't dismiss Dialog; No need to set it if 'persistent' prop is also set
- `auto-close` (boolean, optional)
  Any click/tap inside of the dialog will close it
- `seamless` (boolean, optional)
  Put Dialog into seamless mode; Does not use a backdrop so user is able to interact with the rest of the page too
- `backdrop-filter` (string, optional) *(added v2.15)*
  Apply a backdrop filter; The value needs to be the same as in the CSS specs for backdrop-filter; The examples are not an exhaustive list
  Examples:
    - `'blur(4px)'`
    - `'blur(4px) saturate(150%)'`
    - `'brightness(60%)'`
    - `'invert(70%)'`
    - `'grayscale(100%)'`
    - `'contrast(40%)'`
    - `'hue-rotate(120deg)'`
    - `'sepia(90%)'`
    - `'saturate(80%)'`
    - `'none'`
- `maximized` (boolean, optional)
  Put Dialog into maximized mode
- `full-width` (boolean, optional)
  Dialog will try to render with same width as the window
- `full-height` (boolean, optional)
  Dialog will try to render with same height as the window
- `position` (string, optional), default `'standard'`
  Stick dialog to one of the sides (top, right, bottom or left)
  Accepts: `'standard'`, `'top'`, `'right'`, `'bottom'`, `'left'`
- `square` (boolean, optional)
  Forces content to have squared borders
- `no-refocus` (boolean, optional)
  (Accessibility) When Dialog gets hidden, do not refocus on the DOM element that previously had focus
- `no-focus` (boolean, optional)
  (Accessibility) When Dialog gets shown, do not switch focus on it
- `no-shake` (boolean, optional)
  Do not shake up the Dialog to catch user's attention
- `allow-focus-outside` (boolean, optional)
  Allow elements outside of the Dialog to be focusable; By default, for accessibility reasons, QDialog does not allow outer focus

### Computed Props

- `contentEl` (Element, optional)
  The DOM Element of the rendered content

### Methods

- `show(evt?: Event): void`
  Triggers component to show
  Params:
    - `evt` (Event, optional)
      JS event object
- `hide(evt?: Event): void`
  Triggers component to hide
  Params:
    - `evt` (Event, optional)
      JS event object
- `toggle(evt?: Event): void`
  Triggers component to toggle between show/hide
  Params:
    - `evt` (Event, optional)
      JS event object
- `focus(selector?: string): void`
  Focus dialog; if you have content with autofocus attribute, it will directly focus it
  Params:
    - `selector` (string, optional)
      Optional CSS selector to override default focusable element
      Examples: `'[tabindex]:not([tabindex="-1"])'`
- `shake(focusTarget?: Element): void`
  Shakes dialog
  Params:
    - `focusTarget` (Element, optional)
      Optional DOM Element to be focused after shake
      Examples: `document.getElementById('example')`

### Events

- `@update:model-value`
  Emitted when showing/hidden state changes; Is also used by v-model
  Params:
    - `value` (boolean, optional)
      New state (showing/hidden)
- `@show`
  Emitted after component has triggered show()
  Params:
    - `evt` (Event, required)
      JS event object
- `@before-show`
  Emitted when component triggers show() but before it finishes doing it
  Params:
    - `evt` (Event, required)
      JS event object
- `@hide`
  Emitted after component has triggered hide()
  Params:
    - `evt` (Event, required)
      JS event object
- `@before-hide`
  Emitted when component triggers hide() but before it finishes doing it
  Params:
    - `evt` (Event, required)
      JS event object
- `@shake`
  Emitted when the Dialog shakes in order to catch user's attention, unless the 'no-shake' property is set
- `@escape-key`
  Emitted when ESC key is pressed; Does not get emitted if Dialog is 'persistent' or it has 'no-esc-dismiss' set

### Slots

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

## Usage

> [!IMPORTANT]
> It's best that your QDialog main content is a QCard. However, if you are planning on using any other component (like QForm) or tag, make sure that the direct child of QDialog is rendered with a `<div>` tag (or wrap it with one yourself).

### Basic

```vue
<template>
  <div class="q-gutter-sm">
    <q-btn label="Alert" color="primary" @click="alert = true" />
    <q-btn label="Confirm" color="primary" @click="confirm = true" />
    <q-btn label="Prompt" color="primary" @click="prompt = true" />

    <q-dialog v-model="alert">
      <q-card>
        <q-card-section>
          <div class="text-h6">Alert</div>
        </q-card-section>

        <q-card-section class="q-pt-none">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum
          repellendus sit voluptate voluptas eveniet porro. Rerum blanditiis
          perferendis totam, ea at omnis vel numquam exercitationem aut, natus
          minima, porro labore.
        </q-card-section>

        <q-card-actions align="right">
          <q-btn flat label="OK" color="primary" v-close-popup />
        </q-card-actions>
      </q-card>
    </q-dialog>

    <q-dialog v-model="confirm" persistent>
      <q-card>
        <q-card-section class="row items-center">
          <q-avatar icon="signal_wifi_off" color="primary" text-color="white" />
          <span class="q-ml-sm"
            >You are currently not connected to any network.</span
          >
        </q-card-section>

        <q-card-actions align="right">
          <q-btn flat label="Cancel" color="primary" v-close-popup />
          <q-btn flat label="Turn on Wifi" color="primary" v-close-popup />
        </q-card-actions>
      </q-card>
    </q-dialog>

    <q-dialog v-model="prompt" persistent>
      <q-card style="min-width: 350px">
        <q-card-section>
          <div class="text-h6">Your address</div>
        </q-card-section>

        <q-card-section class="q-pt-none">
          <q-input
            dense
            v-model="address"
            autofocus
            @keyup.enter="prompt = false"
          />
        </q-card-section>

        <q-card-actions align="right" class="text-primary">
          <q-btn flat label="Cancel" v-close-popup />
          <q-btn flat label="Add address" v-close-popup />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>

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

const alert = ref(false)
const confirm = ref(false)
const prompt = ref(false)

const address = ref('')
</script>
```

### Styling

```vue
<template>
  <div class="q-gutter-sm">
    <q-btn label="Close Icon" color="primary" @click="icon = true" />
    <q-btn label="With QBar" color="primary" @click="bar = true" />
    <q-btn label="Another QBar" color="primary" @click="bar2 = true" />
    <q-btn label="With QToolbar" color="primary" @click="toolbar = true" />

    <q-dialog v-model="icon">
      <q-card>
        <q-card-section class="row items-center q-pb-none">
          <div class="text-h6">Close icon</div>
          <q-space />
          <q-btn icon="close" flat round dense v-close-popup />
        </q-card-section>

        <q-card-section>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum
          repellendus sit voluptate voluptas eveniet porro. Rerum blanditiis
          perferendis totam, ea at omnis vel numquam exercitationem aut, natus
          minima, porro labore.
        </q-card-section>
      </q-card>
    </q-dialog>

    <q-dialog v-model="bar" persistent>
      <q-card>
        <q-bar>
          <q-icon name="network_wifi" />
          <q-icon name="network_cell" />
          <q-icon name="battery_full" />
          <div>9:34</div>

          <q-space />

          <q-btn dense flat icon="close" v-close-popup>
            <q-tooltip>Close</q-tooltip>
          </q-btn>
        </q-bar>

        <q-card-section>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum
          repellendus sit voluptate voluptas eveniet porro. Rerum blanditiis
          perferendis totam, ea at omnis vel numquam exercitationem aut, natus
          minima, porro labore.
        </q-card-section>

        <q-card-section class="q-pt-none">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum
          repellendus sit voluptate voluptas eveniet porro. Rerum blanditiis
          perferendis totam, ea at omnis vel numquam exercitationem aut, natus
          minima, porro labore.
        </q-card-section>
      </q-card>
    </q-dialog>

    <q-dialog
      v-model="bar2"
      persistent
      transition-show="flip-down"
      transition-hide="flip-up"
    >
      <q-card class="bg-primary text-white">
        <q-bar>
          <q-icon name="network_wifi" />
          <q-icon name="network_cell" />
          <q-icon name="battery_full" />
          <div>9:34</div>

          <q-space />

          <q-btn dense flat icon="close" v-close-popup>
            <q-tooltip class="bg-white text-primary">Close</q-tooltip>
          </q-btn>
        </q-bar>

        <q-card-section>
          <div class="text-h6">Alert</div>
        </q-card-section>

        <q-card-section class="q-pt-none">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum
          repellendus sit voluptate voluptas eveniet porro. Rerum blanditiis
          perferendis totam, ea at omnis vel numquam exercitationem aut, natus
          minima, porro labore.
        </q-card-section>
      </q-card>
    </q-dialog>

    <q-dialog v-model="toolbar">
      <q-card>
        <q-toolbar>
          <q-avatar>
            <img
              alt="Quasar logo"
              src="https://cdn.quasar.dev/logo-v2/svg/logo.svg"
            />
          </q-avatar>

          <q-toolbar-title
            ><span class="text-weight-bold">Quasar</span>
            Framework</q-toolbar-title
          >

          <q-btn flat round dense icon="close" v-close-popup />
        </q-toolbar>

        <q-card-section>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum
          repellendus sit voluptate voluptas eveniet porro. Rerum blanditiis
          perferendis totam, ea at omnis vel numquam exercitationem aut, natus
          minima, porro labore.
        </q-card-section>
      </q-card>
    </q-dialog>
  </div>
</template>

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

const icon = ref(false)
const bar = ref(false)
const bar2 = ref(false)
const toolbar = ref(false)
</script>
```

Example "Backdrop filter (v2.14.8+)":

```vue
<template>
  <div class="q-gutter-sm">
    <q-btn
      v-for="filter in backdropFilterList"
      :key="filter.label"
      color="primary"
      :label="filter.label"
      no-caps
      @click="filter.onClick"
    />

    <q-dialog v-model="dialog" :backdrop-filter="backdropFilter">
      <q-card>
        <q-card-section class="row items-center q-pb-none text-h6">
          Dialog
        </q-card-section>

        <q-card-section>
          This dialog has a backdrop filter of {{ backdropFilter }}.
        </q-card-section>

        <q-card-actions align="right">
          <q-btn flat label="Close" color="primary" v-close-popup />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>

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

/**
 * Values for backdrop-filter are the same as in the CSS specs.
 * The following list is not an exhaustive one.
 */
const list = [
  'blur(4px)',
  'blur(4px) saturate(150%)',
  'brightness(60%)',
  'invert(70%)',
  'grayscale(100%)',
  'contrast(40%)',
  'hue-rotate(120deg)',
  'sepia(90%)',
  'saturate(80%)'
]

const dialog = ref(false)
const backdropFilter = ref(null)

const backdropFilterList = list.map(filter => ({
  label: filter,
  onClick: () => {
    backdropFilter.value = filter
    dialog.value = true
  }
}))
</script>
```

### Positioning

Example "Positions":

```vue
<template>
  <div class="q-gutter-sm">
    <q-btn
      label="Top"
      icon="keyboard_arrow_up"
      color="primary"
      @click="open('top')"
    />
    <q-btn
      label="Right"
      icon="keyboard_arrow_right"
      color="primary"
      @click="open('right')"
    />
    <q-btn
      label="Bottom"
      icon="keyboard_arrow_down"
      color="primary"
      @click="open('bottom')"
    />
    <q-btn
      label="Left"
      icon="keyboard_arrow_left"
      color="primary"
      @click="open('left')"
    />

    <q-dialog v-model="dialog" :position="position">
      <q-card style="width: 350px">
        <q-linear-progress :value="0.6" color="pink" />

        <q-card-section class="row items-center no-wrap">
          <div>
            <div class="text-weight-bold">The Walker</div>
            <div class="text-grey">Fitz & The Tantrums</div>
          </div>

          <q-space />

          <q-btn flat round icon="fast_rewind" />
          <q-btn flat round icon="pause" />
          <q-btn flat round icon="fast_forward" />
        </q-card-section>
      </q-card>
    </q-dialog>
  </div>
</template>

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

const dialog = ref(false)
const position = ref('top')

function open(pos) {
  position.value = pos
  dialog.value = true
}
</script>
```

> [!NOTE]
> Do not mistake "position" prop with the show/hide animation. If you want a custom animation, you should use `transition-show` and `transition-hide` which can be applied regardless of "position" or "maximized".

Example "Maximized":

```vue
<template>
  <div class="q-gutter-sm">
    <q-btn label="Maximized" color="primary" @click="dialog = true" />

    <q-dialog
      v-model="dialog"
      persistent
      :maximized="maximizedToggle"
      transition-show="slide-up"
      transition-hide="slide-down"
    >
      <q-card class="bg-primary text-white">
        <q-bar>
          <q-space />

          <q-btn
            dense
            flat
            icon="minimize"
            @click="maximizedToggle = false"
            :disable="!maximizedToggle"
          >
            <q-tooltip v-if="maximizedToggle" class="bg-white text-primary"
              >Minimize</q-tooltip
            >
          </q-btn>
          <q-btn
            dense
            flat
            icon="crop_square"
            @click="maximizedToggle = true"
            :disable="maximizedToggle"
          >
            <q-tooltip v-if="!maximizedToggle" class="bg-white text-primary"
              >Maximize</q-tooltip
            >
          </q-btn>
          <q-btn dense flat icon="close" v-close-popup>
            <q-tooltip class="bg-white text-primary">Close</q-tooltip>
          </q-btn>
        </q-bar>

        <q-card-section>
          <div class="text-h6">Alert</div>
        </q-card-section>

        <q-card-section class="q-pt-none">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum
          repellendus sit voluptate voluptas eveniet porro. Rerum blanditiis
          perferendis totam, ea at omnis vel numquam exercitationem aut, natus
          minima, porro labore.
        </q-card-section>
      </q-card>
    </q-dialog>
  </div>
</template>

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

const dialog = ref(false)
const maximizedToggle = ref(true)
</script>
```

> [!NOTE]
> **iOS**
>
> On iOS the soft keyboard does not shrink the page, so a dialog (especially a bottom-anchored one) could end up under it when one of its fields gets focused. QDialog keeps itself within the visible part of the screen while the keyboard is open.

### Various content

Dialogs can contain any content. Some examples:

```vue
<template>
  <div class="q-gutter-sm">
    <q-btn label="Carousel" color="primary" @click="carousel = true" />
    <q-btn label="Card" color="primary" @click="card = true" />
    <q-btn label="Sliders" color="primary" @click="sliders = true" />

    <q-dialog v-model="carousel">
      <q-carousel
        transition-prev="slide-right"
        transition-next="slide-left"
        swipeable
        animated
        v-model="slide"
        control-color="primary"
        navigation-icon="radio_button_unchecked"
        navigation
        padding
        height="200px"
        class="bg-white shadow-1 rounded-borders"
      >
        <q-carousel-slide :name="1" 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>
    </q-dialog>

    <q-dialog v-model="card">
      <q-card class="my-card">
        <q-img src="https://cdn.quasar.dev/img/chicken-salad.jpg" />

        <q-card-section>
          <q-btn
            fab
            color="primary"
            icon="place"
            class="absolute"
            style="top: 0; right: 12px; transform: translateY(-50%)"
          />

          <div class="row no-wrap items-center">
            <div class="col text-h6 ellipsis"> Cafe Basilico </div>
            <div
              class="col-auto text-grey text-caption q-pt-md row no-wrap items-center"
            >
              <q-icon name="place" />
              250 ft
            </div>
          </div>

          <q-rating v-model="stars" :max="5" size="32px" />
        </q-card-section>

        <q-card-section class="q-pt-none">
          <div class="text-subtitle1"> $・Italian, Cafe </div>
          <div class="text-caption text-grey">
            Small plates, salads & sandwiches in an intimate setting.
          </div>
        </q-card-section>

        <q-separator />

        <q-card-actions align="right">
          <q-btn v-close-popup flat color="primary" label="Reserve" />
          <q-btn v-close-popup flat color="primary" round icon="event" />
        </q-card-actions>
      </q-card>
    </q-dialog>

    <q-dialog v-model="sliders">
      <q-card style="width: 300px" class="q-px-sm q-pb-md">
        <q-card-section>
          <div class="text-h6">Volumes</div>
        </q-card-section>

        <q-item-label header>Media volume</q-item-label>
        <q-item dense>
          <q-item-section avatar>
            <q-icon name="volume_up" />
          </q-item-section>
          <q-item-section>
            <q-slider color="teal" v-model="slideVol" :step="0" />
          </q-item-section>
        </q-item>

        <q-item-label header>Alarm volume</q-item-label>
        <q-item dense>
          <q-item-section avatar>
            <q-icon name="alarm" />
          </q-item-section>
          <q-item-section>
            <q-slider color="teal" v-model="slideAlarm" :step="0" />
          </q-item-section>
        </q-item>

        <q-item-label header>Ring volume</q-item-label>
        <q-item dense>
          <q-item-section avatar>
            <q-icon name="vibration" />
          </q-item-section>
          <q-item-section>
            <q-slider color="teal" v-model="slideVibration" :step="0" />
          </q-item-section>
        </q-item>
      </q-card>
    </q-dialog>
  </div>
</template>

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

const carousel = ref(false)
const card = ref(false)
const sliders = ref(false)

const slide = ref(1)
const lorem =
  'Lorem ipsum dolor sit amet consectetur, adipisicing elit. Natus, ratione eum minus fuga, quasi dicta facilis corporis magnam, suscipit at quo nostrum!'

const stars = ref(3)

const slideVol = ref(39)
const slideAlarm = ref(56)
const slideVibration = ref(63)
</script>
```

Example "With containerized QLayout":

```vue
<template>
  <div class="q-gutter-sm">
    <q-btn label="Click me" color="primary" @click="layout = true" />

    <q-dialog v-model="layout">
      <q-layout view="Lhh lpR fff" container class="bg-white text-dark">
        <q-header class="bg-primary">
          <q-toolbar>
            <q-btn flat @click="drawer = !drawer" round dense icon="menu" />
            <q-toolbar-title>Header</q-toolbar-title>
            <q-btn flat @click="drawerR = !drawerR" round dense icon="menu" />
            <q-btn flat v-close-popup round dense icon="close" />
          </q-toolbar>
        </q-header>

        <q-footer class="bg-black text-white">
          <q-toolbar>
            <q-toolbar-title>Footer</q-toolbar-title>
          </q-toolbar>
        </q-footer>

        <q-drawer
          aria-label="Left drawer"
          bordered
          v-model="drawer"
          :width="200"
          :breakpoint="600"
          class="bg-grey-3 text-dark q-pa-sm"
        >
          <div v-for="n in 50" :key="n">Drawer {{ n }} / 50</div>
        </q-drawer>

        <q-drawer
          aria-label="Right drawer"
          side="right"
          bordered
          v-model="drawerR"
          :width="200"
          :breakpoint="300"
          class="bg-grey-3 text-dark q-pa-sm"
        >
          <div v-for="n in 50" :key="n">Drawer {{ n }} / 50</div>
        </q-drawer>

        <q-page-container>
          <q-page padding>
            <p v-for="n in contentSize" :key="n">
              {{ lorem }}
            </p>
          </q-page>
        </q-page-container>
      </q-layout>
    </q-dialog>
  </div>
</template>

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

const moreContent = ref(true)
const layout = ref(false)
const contentSize = computed(() => (moreContent.value ? 150 : 5))
const drawer = ref(false)
const drawerR = ref(false)
const lorem =
  'Lorem ipsum dolor sit amet consectetur, adipisicing elit. Natus, ratione eum minus fuga, quasi dicta facilis corporis magnam, suscipit at quo nostrum!'
</script>
```

> [!IMPORTANT]
> If you are going to use the containerized QLayout, you'll need to put a width on your QDialog, if using left/right position, or a height, if using top/bottom position. You can use vw and vh units.

### Handling scroll

Example "Scrollable dialogs":

```vue
<template>
  <div class="q-gutter-sm">
    <q-btn label="Basic scroll" color="primary" @click="basic = true" />
    <q-btn label="Fixed size" color="primary" @click="fixed = true" />

    <q-dialog v-model="basic" transition-show="rotate" transition-hide="rotate">
      <q-card>
        <q-card-section>
          <div class="text-h6">Terms of Agreement</div>
        </q-card-section>

        <q-card-section class="q-pt-none">
          <p v-for="n in 15" :key="n"
            >Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum
            repellendus sit voluptate voluptas eveniet porro. Rerum blanditiis
            perferendis totam, ea at omnis vel numquam exercitationem aut, natus
            minima, porro labore.</p
          >
        </q-card-section>

        <q-card-actions align="right">
          <q-btn flat label="Decline" color="primary" v-close-popup />
          <q-btn flat label="Accept" color="primary" v-close-popup />
        </q-card-actions>
      </q-card>
    </q-dialog>

    <q-dialog v-model="fixed">
      <q-card>
        <q-card-section>
          <div class="text-h6">Terms of Agreement</div>
        </q-card-section>

        <q-separator />

        <q-card-section style="max-height: 50vh" class="scroll">
          <p v-for="n in 15" :key="n"
            >Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum
            repellendus sit voluptate voluptas eveniet porro. Rerum blanditiis
            perferendis totam, ea at omnis vel numquam exercitationem aut, natus
            minima, porro labore.</p
          >
        </q-card-section>

        <q-separator />

        <q-card-actions align="right">
          <q-btn flat label="Decline" color="primary" v-close-popup />
          <q-btn flat label="Accept" color="primary" v-close-popup />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>

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

const basic = ref(false)
const fixed = ref(false)
</script>
```

### Different modes

User cannot dismiss the Dialog by pressing ESCAPE key or by clicking/tapping on its backdrop.

Example "Persistent":

```vue
<template>
  <div class="q-gutter-sm">
    <q-btn label="Click me" color="primary" @click="persistent = true" />

    <q-dialog
      v-model="persistent"
      persistent
      transition-show="scale"
      transition-hide="scale"
    >
      <q-card class="bg-teal text-white" style="width: 300px">
        <q-card-section>
          <div class="text-h6">Persistent</div>
        </q-card-section>

        <q-card-section class="q-pt-none">
          Click/Tap on the backdrop.
        </q-card-section>

        <q-card-actions align="right" class="bg-white text-teal">
          <q-btn flat label="OK" v-close-popup />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>

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

const persistent = ref(false)
</script>
```

Dialogs can also be a part of the page, without requiring immediate focus. It's where "seamless" mode comes into play:

Example "Seamless":

```vue
<template>
  <div class="q-gutter-sm">
    <q-btn label="Click Me" color="primary" @click="seamless = true" />

    <q-dialog v-model="seamless" seamless position="bottom">
      <q-card style="width: 350px">
        <q-linear-progress :value="0.6" color="pink" />

        <q-card-section class="row items-center no-wrap">
          <div>
            <div class="text-weight-bold">The Walker</div>
            <div class="text-grey">Fitz & The Tantrums</div>
          </div>

          <q-space />

          <q-btn flat round icon="play_arrow" />
          <q-btn flat round icon="pause" />
          <q-btn flat round icon="close" v-close-popup />
        </q-card-section>
      </q-card>
    </q-dialog>
  </div>
</template>

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

const seamless = ref(false)
</script>
```

### Dialog in dialog

You are able to open dialogs on top of other dialogs, with infinite number of depth levels.

Example "Inception":

```vue
<template>
  <div class="q-gutter-sm">
    <q-btn label="Click me" color="primary" @click="inception = true" />

    <q-dialog v-model="inception">
      <q-card>
        <q-card-section>
          <div class="text-h6">Inception</div>
        </q-card-section>

        <q-card-section class="q-pt-none">
          Lorem ipsum dolor sit amet, consectetur adipisicing elit. Perferendis
          laudantium minus earum totam modi laborum illo, corporis fuga saepe
          animi aliquam ea enim assumenda ut nulla natus aperiam quis. Iste.
        </q-card-section>

        <q-card-actions align="right" class="text-primary">
          <q-btn
            flat
            label="Open another dialog"
            @click="secondDialog = true"
          />
          <q-btn flat label="Close" v-close-popup />
        </q-card-actions>
      </q-card>
    </q-dialog>

    <q-dialog
      v-model="secondDialog"
      persistent
      transition-show="scale"
      transition-hide="scale"
    >
      <q-card class="bg-teal text-white" style="width: 300px">
        <q-card-section>
          <div class="text-h6">Persistent</div>
        </q-card-section>

        <q-card-section class="q-pt-none">
          Click/Tap on the backdrop.
        </q-card-section>

        <q-card-actions align="right" class="bg-white text-teal">
          <q-btn flat label="OK" v-close-popup />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>

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

const inception = ref(false)
const secondDialog = ref(false)
</script>
```

### Sizing

You are able to customize the size of the Dialogs. Notice we either tamper with the content's style or we use `full-width` or `full-height` props:

Example "Sizing examples":

```vue
<template>
  <div class="q-gutter-sm">
    <q-btn label="Small" color="primary" @click="small = true" />
    <q-btn label="Medium" color="primary" @click="medium = true" />
    <q-btn label="Full Width" color="primary" @click="fullWidth = true" />
    <q-btn label="Full Height" color="primary" @click="fullHeight = true" />

    <q-dialog v-model="small">
      <q-card style="width: 300px">
        <q-card-section>
          <div class="text-h6">Small</div>
        </q-card-section>

        <q-card-section class="q-pt-none">
          Click/Tap on the backdrop.
        </q-card-section>

        <q-card-actions align="right" class="bg-white text-teal">
          <q-btn flat label="OK" v-close-popup />
        </q-card-actions>
      </q-card>
    </q-dialog>

    <q-dialog v-model="medium">
      <q-card style="width: 700px; max-width: 80vw">
        <q-card-section>
          <div class="text-h6">Medium</div>
        </q-card-section>

        <q-card-section class="q-pt-none">
          Click/Tap on the backdrop.
        </q-card-section>

        <q-card-actions align="right" class="bg-white text-teal">
          <q-btn flat label="OK" v-close-popup />
        </q-card-actions>
      </q-card>
    </q-dialog>

    <q-dialog v-model="fullWidth" full-width>
      <q-card>
        <q-card-section>
          <div class="text-h6">Full Width</div>
        </q-card-section>

        <q-card-section class="q-pt-none">
          Click/Tap on the backdrop.
        </q-card-section>

        <q-card-actions align="right" class="bg-white text-teal">
          <q-btn flat label="OK" v-close-popup />
        </q-card-actions>
      </q-card>
    </q-dialog>

    <q-dialog v-model="fullHeight" full-height>
      <q-card class="column full-height" style="width: 300px">
        <q-card-section>
          <div class="text-h6">Full Height</div>
        </q-card-section>

        <q-card-section class="col q-pt-none">
          Click/Tap on the backdrop.
        </q-card-section>

        <q-card-actions align="right" class="bg-white text-teal">
          <q-btn flat label="OK" v-close-popup />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>

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

const small = ref(false)
const medium = ref(false)
const fullWidth = ref(false)
const fullHeight = ref(false)
</script>
```

## Accessibility *(v2.25+)*

QDialog follows the [WAI-ARIA dialog pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/): the popup renders with `role="dialog"` and a managed `aria-modal` attribute — `"true"` while the dialog has a backdrop, while a `seamless` dialog (which does not block the rest of the page) keeps the dialog role but announces `aria-modal="false"`.

Focus is managed for you. On open, it moves into the dialog — to the first element bearing an `autofocus` (or `data-autofocus`) attribute, or to the dialog body itself when there is none. While the dialog is modal, focus that strays outside of it gets recaptured back in, and on close it returns to the element that opened the dialog. The `no-focus`, `no-refocus` and `allow-focus-outside` props opt out of each of these behaviors, should you need to manage focus yourself. <kbd>Escape</kbd> dismisses the dialog — a `persistent` dialog responds with its "shake" animation instead.

> [!WARNING]
> One thing QDialog cannot do for you is provide an accessible name — by default it is announced as an unnamed dialog. Pass an `aria-label`, or better, give your title element an `id` and reference it with `aria-labelledby`; both are attributes that fall through onto the `role="dialog"` element.

## Cordova/Capacitor back button

Quasar handles the back button for you by default so it can hide any opened Dialogs instead of the default behavior which is to return to the previous page (which is not a nice user experience).

However, should you wish to disable this behavior, edit your `/quasar.config` file:

Example "For Capacitor":

```js
// quasar.config file
return {
  framework: {
    config: {
      capacitor: {
        // Quasar handles app exit on mobile phone back button.
        backButtonExit: true/false/'*'/['/login', '/home', '/my-page'],

        // On the other hand, the following completely
        // disables Quasar's back button management.
        backButton: true/false
      }
    }
  }
}
```

Example "For Cordova":

```js
// quasar.config file
return {
  framework: {
    config: {
      cordova: {
        // Quasar handles app exit on mobile phone back button.
        backButtonExit: true/false/'*'/['/login', '/home', '/my-page'],

        // On the other hand, the following completely
        // disables Quasar's back button management.
        backButton: true/false
      }
    }
  }
}
```
