13
votes

is it possible to make the v-dialog have dynamic width? Currently the v-dialog by default has dynamic height which makes it shorten and lengthen depending on the length of content.

But can this be done with width?

I have a v-dialog that contains 4 tabs. 3 of those tabs don't require much width but the last tab contains a table so I'd like the dialog to widen as far as it needs to, to cater for the table, and then shorten again when clicking on either of the first 3 tabs.

Vuetify v-dialog: https://vuetifyjs.com/en/components/dialogs

6
could you create a codepen for this? You can try playing around with max and min width, or try stuff with fill but I can't tell without your codeSamantha

6 Answers

20
votes

Setting width to "unset" seems to work, haven't discovered any negative side effects yet.

<v-dialog v-model="dialog" width="unset">
    <YourDialogContent></YourDialogContent>
</v-dialog>

or CSS

.v-dialog {
    width: unset;
}
9
votes

For Desktop

so I'd like the dialog to widen as far as it needs to, to cater for the table, and then shorten again when clicking on either of the first 3 tabs.

For desktop, we can set dynamic width for v-dialog based on contents inside the dialog easily, by manually setting the width="auto " (with extra space).

<template>
  <v-dialog width="auto ">
    ...
  </v-dialog>
</template>

For Mobile

Due to limited space, full-screen dialogs may be more appropriate for mobile devices than dialogs used on devices with larger screens. But need to set dialog to full-screen in mobile devices only. We can easily set dynamic full-screen using Vuetify breakpoints like:

<template>
  <v-dialog :fullscreen="$vuetify.breakpoint.xsOnly">
    ...
  </v-dialog>
</template>

Final Version

We can combine both the logics into one like:

<template>
  <v-dialog width="auto " :fullscreen="$vuetify.breakpoint.xsOnly">
    ...
  </v-dialog>
</template>

Working Demo | Code Pen

On Desktop

  • If we open the dialog using the click me button, we can see the dialog has a small width as the content of tab 1 & 2 is very small. But if we click on tab 3, which has a large data table, you can see the dialog width and height automatically increases. You can toggle between tabs and can see this again.

On Mobile

  • If you open this demo on mobile, you can see the dialog is opening in full-screen by default and the width is constant.
4
votes

Write custom css rules and not set width or max-width props. e.g.:

I use a custom class in order to not apply rules to all v-dialog:

<v-dialog v-model="dialog" content-class="v-dialog--custom">
   <!-- dialog content -->
</v-dialog>

And create your custom rules:

.v-dialog--custom {
  width: 100%;
}

/* Desktop */
@media screen and (min-width: 768px) {
  .v-dialog--custom {
    width: 50%;
  }
}

You can see this on codepen: https://codepen.io/hans-felix/pen/BajByxx

1
votes

Are you talking about this part?:

<v-dialog
    v-model="dialog"
    width="500"
>

If so, why just don't remove the width="500" part and leave without one? I tested and it stretches dynamically. This option is not required and nothing is breaking if you remove it.

In case I misunderstood something, please feel free to add more details.

1
votes

I think, what are you searching is the fullscreen (bool) property or depending on the needs the max-width (Number) property.

By setting one of those you control the width of the v-dialog depending on the surrounding element. The surrounding element width can be adjusted via css, e.g. flexbox.

0
votes

Use what scientists are using.

Make width as a computed variable, and then return your value based on the breakpoints. If you want to set width dynamically based on the contents in the dialog then just modify the width function to return the width based on the contents. Copied from vuetify site: LINK

<v-dialog v-model="dialog" :width="width">
  <v-img src="~~~"></v-img>
</v-dialog>
<script>
  ...
  computed:{
    width() {
      switch (this.$vuetify.breakpoint.name) {
        case 'xs': return 220
        case 'sm': return 400
        case 'md': return 500
        case 'lg': return 600
        case 'xl': return 800
      }
    },
  }
</script>