Skip to content
Advertisement

Vuetify Navigation-drawer weird behavior with mini-variant.sync

I’m experiencing an issue with the v-navigation-drawer component in my Vuetify application. When the mini-variant.sync prop is enabled and the viewport is at a certain breakpoint (between lg and md), there is a strange padding appearing on the main part of the application. I have included my code above for reference.

I am using Vuetify version 2(have not encountered any error messages). I am expecting the v-navigation-drawer component to behave as it normally does, without the strange padding appearing on the main part of the application.

Can someone please help me understand why this issue is occurring and how I can fix it? Any insights or suggestions would be greatly appreciated. Thank you 😁

See an example of the problem here(increase your resolution by clicking on the “Full page” link!!)

<!DOCTYPE html>
<html>
<head>
  <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
  <div id="app">
    <v-app>
      <v-expand-x-transition>
    <v-navigation-drawer
    v-if="drawer"
   :style="'background-color:yellow;'+($vuetify.breakpoint.xsOnly ? 'width:100%;': '')"
        :permanent="$vuetify.breakpoint.mdAndUp" 
      
        :mini-variant.sync="$vuetify.breakpoint.lgAndUp"
        :left="$vuetify.breakpoint.mdAndUp" 
      app
        v-model="drawer"  
:expand-on-hover="$vuetify.breakpoint.mdAndUp" 
    >  
    <span style="color:white;" v-if="$vuetify.breakpoint.xsOnly||!($vuetify.breakpoint.mdAndUp)">Please increase your resolution!</span>
[content of navigation-drawer]
    </v-navigation-drawer> 
 



    </v-expand-x-transition>
      <v-main style="background-color:red;">
        <v-container>There is a strange padding when you enter your mouse on the navigation drawer and leave!</v-container>
      </v-main>
    </v-app>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
  
  <script>
    new Vue({
      el: '#app',
      vuetify: new Vuetify(),
    data: {
      drawer:true,
    },
    })
    </script>
</body>
</html>

Advertisement

Answer

EDIT-

After checking so deeply, I finally found the bug which is as follows-

The behaviour of mini-variant prop is like-

Expand the drawer = mini-variant is false = drawer is no more mini

Shrink the drawer = mini-variant is true = drawer is in mini mode

But, in your implementation, the value of mini-variant is always true even when expand the drawer (which should change the value to false). In fact there is a blink of false -> true when expand the drawer but at the end remains true always.

Here is the proof-

<!DOCTYPE html>
<html>
  <head>
    <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
  </head>
  <body>
    <div id="app">
      <v-app>
        <v-expand-x-transition>
          <v-navigation-drawer
            v-if="drawer"
            style="background-color:blue;" :style="$vuetify.breakpoint.xsOnly ? 'width:100%;': ''"
            :permanent="$vuetify.breakpoint.mdAndUp" 
            :mini-variant.sync="$vuetify.breakpoint.lgAndUp"
            :left="$vuetify.breakpoint.mdAndUp" 
            app
            v-model="drawer"  
            :expand-on-hover="$vuetify.breakpoint.mdAndUp" 
            >  
            <span style="color:white;" v-if="$vuetify.breakpoint.xsOnly||!($vuetify.breakpoint.mdAndUp)">Please increase your resolution!</span>
            [content of navigation-drawer]
          </v-navigation-drawer>
        </v-expand-x-transition>
        <v-main style="background-color:red;">
          <v-container>
          mini-variant - {{ $vuetify.breakpoint.lgAndUp }}
          </v-container>
        </v-main>
      </v-app>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
    <script>
      new Vue({
        el: '#app',
        vuetify: new Vuetify(),
        data() {
          return {
            drawer: true,
          }
        }
      })
    </script>
  </body>
</html>

Now, the bug is to use mini-variant like this-

:mini-variant="$vuetify.breakpoint.lgAndUp"

which will always be true because no matter you expand/shrink the drawer, mini-variant is directly depending on the breakpoint which is always true for the large device, and this is what the blink of true -> false indicated.

Expand the drawer -> mini turns false -> realized that breakpoint condition is true -> suddenly change itself to true -> always remains true.

Now, when mini-variant sets false for one second, the container gets padding of 256px from the left but as there no one saved the status of mini-variant (before turing it to true), it never knows if it is expanding/shrinking so the padding never gets chance to reset to default and this is what gave you the weired padding.

Now, the solution is to use a data property which can store the status of the drawer and do not directly depend on the breakpoint and this is what a way of implemenmtation described in the documentation.

Here is the working demo-

<!DOCTYPE html>
<html>
  <head>
    <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
  </head>
  <body>
    <div id="app">
      <v-app>
        <v-expand-x-transition>
          <v-navigation-drawer
            v-if="drawer"
            :style="'background-color:blue;'+($vuetify.breakpoint.xsOnly ? 'width:100%;': '')"
            :permanent="$vuetify.breakpoint.mdAndUp" 
            :mini-variant.sync="mini"
            :left="$vuetify.breakpoint.mdAndUp" 
            app
            v-model="drawer"  
            :expand-on-hover="$vuetify.breakpoint.mdAndUp" 
            >  
            <span style="color:white;" v-if="$vuetify.breakpoint.xsOnly||!($vuetify.breakpoint.mdAndUp)">Please increase your resolution!</span>
            [content of navigation-drawer]
          </v-navigation-drawer>
        </v-expand-x-transition>
        <v-main style="background-color:red;">
          <v-container>
            mini-variant - {{ mini }}
          </v-container>
        </v-main>
      </v-app>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
    <script>
      new Vue({
        el: '#app',
        vuetify: new Vuetify(),
        data() {
          return {
            drawer: true,
            mini: this.$vuetify.breakpoint.lgAndUp
          }
        }
      })
    </script>
  </body>
</html>
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement