Tari Ibaba

Tari Ibaba is a software developer with years of experience building websites and apps. He has written extensively on a wide range of programming topics and has created dozens of apps and open-source libraries.

Vuetify Flex: How to Create Flexbox Layouts

A flexbox layout simplifies the process of designing a flexible and responsive page layout structure without using float or manual positioning. It allows responsive elements within a container to be automatically arranged depending on the size of the viewport. In this article, we’re going to learn about the various helper classes Vuetify provides to control the layout of flex containers with alignment, justification, wrapping, and more.

Vuetify Flexbox Container

Applying the d-flex helper class to an element sets its display to flex, which turns it into a flexbox container transforming its direct children into flex items. As we’ll see later on, we can customize the interaction of these child elements with additional flex property utilities.

<template>
  <v-app>
    <div class="ma-4">
      <v-card
        class="d-flex pa-2"
        outlined
        tile
      >
        <div>A flexbox container</div>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Creating a flexbox container with Vuetify.

Inline Flex

The d-inline-flex class turns an element into an inline flexbox container.

<template>
  <v-app>
    <div class="ma-4">
      <v-card
        class="d-inline-flex pa-2"
        outlined
        tile
      >
        <div>Inline flexbox container</div>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Creating an inline flexbox container with Vuetify.

We can also customize the flex utilities to apply only for specific breakpoints with the following classes:

  • d-sm-flex
  • d-sm-inline-flex
  • d-md-flex
  • d-md-inline-flex
  • d-lg-flex
  • d-lg-inline-flex
  • d-xl-flex
  • d-xl-inline-flex

Vuetify Flex Direction

Vuetify provides flex helper classes for specifying the direction of the flex items within the container. These classes modify the flex-direction CSS property of the element. They are:

  • flex-row
  • flex-row-reverse
  • flex-column
  • flex-column-reverse

flex-row and flex-row-reverse

The flex-row utility class displays the flexible items horizontally, as a row. flex-row-reverse does the same, but in reverse order:

<template>
  <v-app>
    <div class="ma-4">
      <v-card
        class="d-flex flex-row mb-6"
        color="grey lighten-4"
        flat
        tile
      >
        <v-card
          v-for="n in 3"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          Flex item {{ n }}
        </v-card>
      </v-card>
      <v-card
        class="d-flex flex-row-reverse"
        color="grey lighten-4"
        flat
        tile
      >
        <v-card
          v-for="n in 3"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          Flex item {{ n }}
        </v-card>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Vuetify flex row and flex row reverse.

flex-column and flex-column-reverse

The flex-column utility class displays the flex items vertically, in a column. flex-column-reverse does the same, but in reverse order:

<template>
  <v-app>
    <div class="ma-4">
      <div class="d-flex flex-column mb-6">
        <v-card
          v-for="n in 3"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          Flex item {{ n }}
        </v-card>
      </div>
      <div class="d-flex flex-column-reverse">
        <v-card
          v-for="n in 3"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          Flex item {{ n }}
        </v-card>
      </div>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Vuetify flex column and flex column reverse.

There are also responsive variations of these classes that set the flex-direction property for certain breakpoints.

  • flex-sm-row
  • flex-sm-row-reverse
  • flex-sm-column
  • flex-sm-column-reverse
  • flex-md-row
  • flex-md-row-reverse
  • flex-md-column
  • flex-md-column-reverse
  • flex-lg-row
  • flex-lg-row-reverse
  • flex-lg-column
  • flex-lg-column-reverse
  • flex-xl-row
  • flex-xl-row-reverse
  • flex-xl-column
  • flex-xl-column-reverse

Flex Justify Classes

We can modify the justify-content flex property of the flexible container with the flex justify classes from Vuetify. justify-content modifies the flexbox items on the x-axis or y-axis for a flex-direction of row or column respectively. The helper classes can set justify-content to start (browser default), end, center, space-between, or space-around. They are:

  • justify-start
  • justify-end
  • justify-center
  • justify-space-between
  • justify-space-around
<template>
  <v-app>
    <div class="ma-4">
      <v-card
        class="d-flex justify-start mb-6"
        color="grey lighten-4"
        flat
        tile
      >
        <v-card
          v-for="n in 3"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          justify-start
        </v-card>
      </v-card>

      <v-card
        class="d-flex justify-end mb-6"
        color="grey lighten-4"
        flat
        tile
      >
        <v-card
          v-for="n in 3"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          justify-end
        </v-card>
      </v-card>

      <v-card
        class="d-flex justify-center mb-6"
        color="grey lighten-4"
        flat
        tile
      >
        <v-card
          v-for="n in 3"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          justify-center
        </v-card>
      </v-card>

      <v-card
        class="d-flex justify-space-between mb-6"
        color="grey lighten-4"
        flat
        tile
      >
        <v-card
          v-for="n in 3"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          justify-space-between
        </v-card>
      </v-card>

      <v-card
        class="d-flex justify-space-around mb-6"
        color="grey lighten-4"
        flat
        tile
      >
        <v-card
          v-for="n in 3"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          justify-space-around
        </v-card>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the flex justify helper classes from Vuetify.

There are also responsive variations of these classes that set the justify-content property for certain breakpoints:

  • justify-sm-start
  • justify-sm-end
  • justify-sm-center
  • justify-sm-space-between
  • justify-sm-space-around
  • justify-md-start
  • justify-md-end
  • justify-md-center
  • justify-md-space-between
  • justify-md-space-around
  • justify-lg-start
  • justify-lg-end
  • justify-lg-center
  • justify-lg-space-between
  • justify-lg-space-around
  • justify-xl-start
  • justify-xl-end
  • justify-xl-center
  • justify-xl-space-between
  • justify-xl-space-around

Vuetify Flex Align Classes

We also have flex utility classes from Vuetify that modify the align-items CSS property of the flex container. align-items modifies the flexbox items on the y-axis or x-axis for a flex-direction of row or column respectively. The helper classes can set align-items to start, end, center, baseline or stretch (browser default). They are:

  • align-start
  • align-end
  • align-center
  • align-baseline
  • align-stretch
<template>
  <v-app>
    <div class="ma-4">
      <v-card
        class="d-flex align-start mb-6"
        color="grey lighten-2"
        flat
        height="100"
        tile
      >
        <v-card
          v-for="n in 3"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          align-start
        </v-card>
      </v-card>

      <v-card
        class="d-flex align-end mb-6"
        color="grey lighten-2"
        flat
        height="100"
        tile
      >
        <v-card
          v-for="n in 3"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          align-end
        </v-card>
      </v-card>

      <v-card
        class="d-flex align-center mb-6"
        color="grey lighten-2"
        flat
        height="100"
        tile
      >
        <v-card
          v-for="n in 3"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          align-center
        </v-card>
      </v-card>

      <v-card
        class="d-flex align-baseline mb-6"
        color="grey lighten-2"
        flat
        height="100"
        tile
      >
        <v-card
          v-for="n in 3"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          align-baseline
        </v-card>
      </v-card>

      <v-card
        class="d-flex align-stretch mb-6"
        color="grey lighten-2"
        flat
        height="100"
        tile
      >
        <v-card
          v-for="n in 3"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          align-stretch
        </v-card>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the Vuetify flex align utility classes on a flexbox.

They are also responsive variations of these classes that set the align-items property for certain breakpoints:

  • align-sm-start
  • align-sm-end
  • align-sm-center
  • align-sm-baseline
  • align-sm-stretch
  • align-md-start
  • align-md-end
  • align-md-center
  • align-md-baseline
  • align-md-stretch
  • align-lg-start
  • align-lg-end
  • align-lg-center
  • align-lg-baseline
  • align-lg-stretch
  • align-xl-start
  • align-xl-end
  • align-xl-center
  • align-xl-baseline
  • align-xl-stretch

Flex Align Self Classes

We use the flex align self helper classes to modify the align-self flex property of the element. align-self modifies the flexbox items on the x-axis or y-axis for a flex-direction of row or column respectively. The helper classes can set align-self to start, end, center, baseline or stretch (browser default). They are:

  • align-self-start
  • align-self-end
  • align-self-center
  • align-self-baseline
  • align-self-stretch
<template>
  <v-app>
    <div class="ma-4">
      <v-card
        v-for="j in justify"
        :key="j"
        class="d-flex mb-6"
        color="grey lighten-2"
        flat
        height="100"
        tile
      >
        <v-card
          v-for="n in 3"
          :key="n"
          class="pa-2"
          :class="[n === 2 && `align-self-${j}`]"
          outlined
          tile
        >
          {{ n === 2 ? 'Aligned flex item' : 'Flex item' }}
        </v-card>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    justify: [
      'start',
      'end',
      'center',
      'baseline',
      'auto',
      'stretch',
    ],
  }),
};
</script>
Using the Vuetify flex align self helper classes.

Vuetify also provides responsive variations of these classes that set the align-self property for certain breakpoints:

  • align-self-sm-start
  • align-self-sm-end
  • align-self-sm-center
  • align-self-sm-baseline
  • align-self-sm-auto
  • align-self-sm-stretch
  • align-self-md-start
  • align-self-md-end
  • align-self-md-center
  • align-self-md-baseline
  • align-self-md-auto
  • align-self-md-stretch
  • align-self-lg-start
  • align-self-lg-end
  • align-self-lg-center
  • align-self-lg-baseline
  • align-self-lg-auto
  • align-self-lg-stretch
  • align-self-xl-start
  • align-self-xl-end
  • align-self-xl-center
  • align-self-xl-baseline
  • align-self-xl-auto
  • align-self-xl-stretch

Auto Margins

We can apply one of the margin helper classes from Vuetify to a flex container to control the positioning of flex items on the x-axis or y-axis for a flex direction of row or column respectively.

<template>
  <v-app>
    <div class="ma-4">
      <v-card
        class="d-flex mb-6"
        color="grey lighten-2"
        flat
        tile
      >
        <v-card
          v-for="n in 3"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          Flex item
        </v-card>
      </v-card>

      <v-card
        class="d-flex mb-6"
        color="grey lighten-2"
        flat
        tile
      >
        <v-card
          v-for="n in 3"
          :key="n"
          :class="n === 1 && 'mr-auto'"
          class="pa-2"
          outlined
          tile
        >
          Flex item
        </v-card>
      </v-card>

      <v-card
        class="d-flex mb-6"
        color="grey lighten-2"
        flat
        tile
      >
        <v-card
          v-for="n in 3"
          :key="n"
          :class="n === 3 && 'ml-auto'"
          class="pa-2"
          outlined
          tile
        >
          Flex item
        </v-card>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Create auto margins with the Vuetify margin helper classes.

Using align-items

If we set flex-direction to column and specify a value for align-items, we can use either the mb-auto or mt-auto helper class to adjust flex item positioning:

<template>
  <v-app>
    <div class="ma-4">
      <v-card
        class="d-flex align-start flex-column mb-6"
        color="grey lighten-2"
        flat
        tile
        height="200"
      >
        <v-card
          v-for="n in 3"
          :key="n"
          :class="n === 1 && 'mb-auto'"
          class="pa-2"
          outlined
          tile
        >
          Flex item
        </v-card>
      </v-card>
      <v-card
        class="d-flex align-end flex-column"
        color="grey lighten-2"
        flat
        tile
        height="200"
      >
        <v-card
          v-for="n in 3"
          :key="n"
          :class="n === 3 && 'mt-auto'"
          class="pa-2"
          outlined
          tile
        >
          Flex item
        </v-card>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Flex item positioning with align-items and mb-auto/mt-auto classes from Vuetify.

Vuetify Flex Wrap Classes

By default, the d-flex class does not provide wrapping (it behaves similar to setting flex-wrap to nowrap). We can change this by applying one of the flex-wrap helper classes to the container. The classes are:

  • flex-nowrap
  • flex-wrap
  • flex-wrap-reverse

flex-nowrap

flex-nowrap specifies that the items should not wrap.

<template>
  <v-app>
    <div class="ma-4">
      <v-card
        class="d-flex flex-nowrap py-3"
        color="grey lighten-2"
        flat
        tile
        width="125"
      >
        <v-card
          v-for="n in 5"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          Flex item
        </v-card>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the flex-nowrap Vuetify helper class.

flex-wrap

flex-wrap makes the items wrap if necessary.

<template>
  <v-app>
    <div class="ma-4">
      <v-card
        class="d-flex flex-wrap"
        color="grey lighten-2"
        flat
        tile
      >
        <v-card
          v-for="n in 20"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          Flex item {{ n }}
        </v-card>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

Using the Vuetify flex-wrap helper class.

flex-wrap-reverse

flex-wrap-reverse specifies that the flex items will wrap if necessary, in reverse order.

<template>
  <v-app>
    <div class="ma-4">
      <v-card
        class="d-flex flex-wrap-reverse"
        color="grey lighten-2"
        flat
        tile
      >
        <v-card
          v-for="n in 20"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          Flex item {{ n }}
        </v-card>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

Using the flex-wrap-reverse Vuetify helper class.

Vuetify also provides responsive variations of these classes to set the flex-wrap property for certain breakpoints:

  • flex-sm-nowrap
  • flex-sm-wrap
  • flex-sm-wrap-reverse
  • flex-md-nowrap
  • flex-md-wrap
  • flex-md-wrap-reverse
  • flex-lg-nowrap
  • flex-lg-wrap
  • flex-lg-wrap-reverse
  • flex-xl-nowrap
  • flex-xl-wrap
  • flex-xl-wrap-reverse

Vuetify Flex Order Classes

We can use one of the flex order utility classes to customize the visual order of the flexbox items within their container.

<template>
  <v-app>
    <div class="ma-4">
      <v-card
        class="d-flex flex-wrap"
        color="grey lighten-2"
        flat
        tile
      >
        <v-card
          class="order-2 pa-2"
          outlined
          tile
        >
          First flex item
        </v-card>
        <v-card
          class="order-3 pa-2"
          outlined
          tile
        >
          Second flex item
        </v-card>
        <v-card
          class="order-1 pa-2"
          outlined
          tile
        >
          Third flex item
        </v-card>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the Vuetify flex order utility classes.

These classes set the order flex property of the container. They are:

  • order-first
  • order-0
  • order-1
  • order-2
  • order-3
  • order-4
  • order-5
  • order-6
  • order-7
  • order-8
  • order-9
  • order-10
  • order-11
  • order-12
  • order-last

Vuetify also provides responsive variants of these classes that set the order property for certain breakpoints:

  • order-sm-first
  • order-sm-0
  • order-sm-1
  • order-sm-2
  • order-sm-3
  • order-sm-4
  • order-sm-5
  • order-sm-6
  • order-sm-7
  • order-sm-8
  • order-sm-9
  • order-sm-10
  • order-sm-11
  • order-sm-12
  • order-sm-last
  • order-md-first
  • order-md-0
  • order-md-1
  • order-md-2
  • order-md-3
  • order-md-4
  • order-md-5
  • order-md-6
  • order-md-7
  • order-md-8
  • order-md-9
  • order-md-10
  • order-md-11
  • order-md-12
  • order-md-last
  • order-lg-first
  • order-lg-0
  • order-lg-1
  • order-lg-2
  • order-lg-3
  • order-lg-4
  • order-lg-5
  • order-lg-6
  • order-lg-7
  • order-lg-8
  • order-lg-9
  • order-lg-10
  • order-lg-11
  • order-lg-12
  • order-lg-last
  • order-xl-first
  • order-xl-0
  • order-xl-1
  • order-xl-2
  • order-xl-3
  • order-xl-4
  • order-xl-5
  • order-xl-6
  • order-xl-7
  • order-xl-8
  • order-xl-9
  • order-xl-10
  • order-xl-11
  • order-xl-12
  • order-xl-last

Vuetify Flex Align Content

Vuetify provides flex align content classes that we can use to set the align-content CSS property of the flex container. The align-content modifies the flexbox items on the x-axis or y-axis for a flex-direction of row or column respectively. The helper classes can set align-content to start (browser default), end, center, between, around or stretch. They are:

  • align-content-start
  • align-content-end
  • align-content-center
  • align-content-between
  • align-content-around
  • align-content-stretch

align-content-start

<template>
  <v-app>
    <div class="ma-4">
      <v-card
        class="d-flex align-content-start flex-wrap"
        color="grey lighten-2"
        flat
        tile
        min-height="200"
      >
        <v-card
          v-for="n in 20"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          Flex item
        </v-card>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

align-content-end

<template>
  <v-app>
    <div class="ma-4">
      <v-card
        class="d-flex align-content-end flex-wrap"
        color="grey lighten-2"
        flat
        tile
        min-height="200"
      >
        <v-card
          v-for="n in 20"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          Flex item
        </v-card>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

align-content-center

<template>
  <v-app>
    <div class="ma-4">
      <v-card
        class="d-flex align-content-center flex-wrap"
        color="grey lighten-2"
        flat
        tile
        min-height="200"
      >
        <v-card
          v-for="n in 20"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          Flex item
        </v-card>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

align-content-space-between

<template>
  <v-app>
    <div class="ma-4">
      <v-card
        class="d-flex align-content-space-between flex-wrap"
        color="grey lighten-2"
        flat
        tile
        min-height="200"
      >
        <v-card
          v-for="n in 20"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          Flex item
        </v-card>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

align-content-space-around

<template>
  <v-app>
    <div class="ma-4">
      <v-card
        class="d-flex align-content-space-around flex-wrap"
        color="grey lighten-2"
        flat
        tile
        min-height="200"
      >
        <v-card
          v-for="n in 20"
          :key="n"
          class="pa-2"
          outlined
          tile
        >
          Flex item
        </v-card>
      </v-card>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

There are also responsive variations of theses classes that set the align-content property for certain breakpoints:

  • align-sm-content-start
  • align-sm-content-end
  • align-sm-content-center
  • align-sm-content-space-between
  • align-sm-content-space-around
  • align-sm-content-stretch
  • align-md-content-start
  • align-md-content-end
  • align-md-content-center
  • align-md-content-space-between
  • align-md-content-space-around
  • align-md-content-stretch
  • align-lg-content-start
  • align-lg-content-end
  • align-lg-content-center
  • align-lg-content-space-between
  • align-lg-content-space-around
  • align-xl-content-start
  • align-xl-content-end
  • align-xl-content-center
  • align-xl-content-space-between
  • align-xl-content-space-around
  • align-xl-content-stretch

Vuetify Flex Grow and Shrink Classes

Vuetify also comes with helper classes that set the flex-grow and flex-shrink of a flexbox container. These utility classes are in the form flex-{condition}-{value}, where condition can be either grow or shrink and value can be either 0 or 1. The grow condition will allow an element to grow to fill available space, while shrink will allow an element to shrink down only to the space needed for its contents if there is not enough space in its container. The value 0 will prevent the condition from happening, while 1 will allow it. The classes are:

  • flex-grow-0
  • flex-grow-1
  • flex-shrink-0
  • flex-shrink-1
<template>
  <v-app>
    <div class="ma-4">
      <v-container class="grey lighten-5">
        <v-row
          no-gutters
          style="flex-wrap: nowrap"
        >
          <v-col
            cols="2"
            class="flex-grow-0 flex-shrink-0"
          >
            <v-card
              class="pa-2"
              outlined
              tile
            >
              I'm 2 column wide
            </v-card>
          </v-col>
          <v-col
            cols="1"
            style="min-width: 100px; max-width: 100%"
            class="flex-grow-1 flex-shrink-0"
          >
            <v-card
              class="pa-2"
              outlined
              tile
            >
              I'm 1 column wide and I grow to take all the
              space
            </v-card>
          </v-col>
          <v-col
            cols="5"
            style="min-width: 100px"
            class="flex-grow-0 flex-shrink-1"
          >
            <v-card
              class="pa-2"
              outlined
              tile
            >
              I'm 5 column wide and I shrink if there's not
              enough space
            </v-card>
          </v-col>
        </v-row>
      </v-container>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the flex grow and flex shrink Vuetify helper classes.

There are also responsive variations of these classes that set the flex-grow and flex-shrink properties for certain breakpoints:

  • flex-sm-grow-0
  • flex-sm-grow-1
  • flex-sm-shrink-0
  • flex-sm-shrink-1
  • flex-md-grow-0
  • flex-md-grow-1
  • flex-md-shrink-0
  • flex-md-shrink-1
  • flex-lg-grow-0
  • flex-lg-grow-1
  • flex-lg-shrink-0
  • flex-lg-shrink-1
  • flex-xl-grow-0
  • flex-xl-grow-1
  • flex-xl-shrink-0
  • flex-xl-shrink-1

Conclusion

Flexbox layouts allow responsive items inside a container to be automatically arranged depending on the screen size. Vuetify comes with various flexbox utility classes for controlling the layout of flex containers with alignment, justification, wrapping, and more.

Vuetify Breadcrumbs: How to Create Breadcrumbs with Vuetify

Breadcrumbs are navigation helpers that allow users to keep track and maintain awareness of their location within a website. They serve as a navigational aid that enables the user to understand the relation between the current page and higher-level pages. In this article, we’re going to learn how to create breadcrumbs with the Vuetify breadcrumbs component.

The Vuetify Breadcrumbs Component (v-breadcrumbs)

Vuetify provides the v-breadcrumbs component for creating and displaying breadcrumbs. The breadcrumbs component comes with an items prop that takes an array containing information about each item of the breadcrumbs. Each array element is an object that represents one item. Here are some of the properties of this object that we can set:

  • text: sets the text that will be displayed for that item.
  • href: sets the location that the user can navigate to by clicking on the breadcrumbs item.
  • disabled: determines whether the user can click on the breadcrumb to navigate to the location specified with href.
<template>
  <v-app>
    <v-breadcrumbs :items="items"></v-breadcrumbs>
  </v-app>
</template>
<script>
export default {
  name: 'App',
  data: () => ({
    items: [
      {
        text: 'Home',
        disabled: false,
        href: 'breadcrumbs_home',
      },
      {
        text: 'Link 1',
        disabled: false,
        href: 'breadcrumbs_link_1',
      },
      {
        text: 'Link 2',
        disabled: true,
        href: 'breadcrumbs_link_2',
      },
    ],
  }),
};
</script>
Creating breadcrumbs with the Vuetify breadcrumbs component.

Vuetify Breadcrumbs Divider

We can customize the separator displayed between the breadcrumbs with the divider prop. The default separator is a forward slash (/).

<template>
  <v-app>
    <div>
      <v-breadcrumbs :items="items" divider="-"></v-breadcrumbs>

      <v-breadcrumbs :items="items" divider="."></v-breadcrumbs>
    </div>
  </v-app>
</template>
<script>
export default {
  name: 'App',
  data: () => ({
    items: [
      {
        text: 'Home',
        disabled: false,
        href: 'breadcrumbs_home',
      },
      {
        text: 'Link 1',
        disabled: false,
        href: 'breadcrumbs_link_1',
      },
      {
        text: 'Link 2',
        disabled: true,
        href: 'breadcrumbs_link_2',
      },
    ],
  }),
};
</script>
Using the divider prop of the Vuetify breadcrumbs component.

Large Breadcrumbs

We can increase the font size of the breadcrumbs by setting the large prop to true. large increases the font-size of each item from the default 14px to 16px.

<template>
  <v-app>
    <div>
      <v-breadcrumbs :items="items"></v-breadcrumbs>

      <v-breadcrumbs :items="items" large></v-breadcrumbs>
    </div>
  </v-app>
</template>
<script>
export default {
  name: 'App',
  data: () => ({
    items: [
      {
        text: 'Home',
        disabled: false,
        href: 'breadcrumbs_home',
      },
      {
        text: 'Link 1',
        disabled: false,
        href: 'breadcrumbs_link_1',
      },
      {
        text: 'Link 2',
        disabled: true,
        href: 'breadcrumbs_link_2',
      },
    ],
  }),
};
</script>
Using the large prop of the v-breadcrumbs component.

Vuetify Breadcrumbs Icon Dividers

We can use the divider slot of v-breadcrumbs to display custom HTML between each item of the breadcrumbs. For example, we can display any of the icons from Material Design Icons with the Vuetify icon component (v-icon):

<template>
  <v-app>
    <div>
      <v-breadcrumbs :items="items">
        <template v-slot:divider>
          <v-icon>mdi-forward</v-icon>
        </template>
      </v-breadcrumbs>

      <v-breadcrumbs :items="items">
        <template v-slot:divider>
          <v-icon>mdi-chevron-right</v-icon>
        </template>
      </v-breadcrumbs>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: [
      {
        text: 'Home',
        disabled: false,
        href: 'breadcrumbs_home',
      },
      {
        text: 'Link 1',
        disabled: false,
        href: 'breadcrumbs_link_1',
      },
      {
        text: 'Link 2',
        disabled: true,
        href: 'breadcrumbs_link_2',
      },
    ],
  }),
};
</script>
Using the divider slot of v-breadcrumbs.

Vuetify Breadcrumbs item Slot

We can use the item slot of v-breadcrumbs to customize each breadcrumb. For example, here we display an uppercased text for each item:

<template>
  <v-app>
    <div>
      <v-breadcrumbs :items="items">
        <template v-slot:item="{ item }">
          <v-breadcrumbs-item :href="item.href" :disabled="item.disabled">
            {{ item.text.toUpperCase() }}
          </v-breadcrumbs-item>
        </template>
      </v-breadcrumbs>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: [
      {
        text: 'Home',
        disabled: false,
        href: 'breadcrumbs_home',
      },
      {
        text: 'Link 1',
        disabled: false,
        href: 'breadcrumbs_link_1',
      },
      {
        text: 'Link 2',
        disabled: true,
        href: 'breadcrumbs_link_2',
      },
    ],
  }),
};
</script>
Using the item slot of the Vuetify breadcrumbs component.

Conclusion

Breadcrumbs serve as a navigation aid that helps users to maintain awareness of their location within a website. We can the Vuetify breadcrumbs component (v-breadcrumbs) to create breadcrumbs.

Vuetify Lazy: How to Implement Lazy Loading with Vuetify

In web development, lazy loading is a practice of deferring the loading or initialization of the resources of a web page until they’re actually needed. It is a useful technique for reducing page load times, saving system resources, and improving performance. In this article, we’re going to learn how to implement lazy loading and speed up our web pages with the Vuetify lazy component.

The Vuetify Lazy Component (v-lazy)

Vuetify provides the v-lazy component for dynamically loading a UI element based on its visibility. In this example, we’ll be lazy loading a card:

<template>
  <v-app>
    <v-responsive class="overflow-y-auto" max-height="400">
      <div class="pa-6 text-center">Scroll down</div>

      <v-responsive height="200vh" class="text-center pa-2">
        <v-responsive min-height="50vh"></v-responsive>
        <div class="text-center text-body-2 mb-12">
          The card will appear below:
        </div>

        <v-lazy min-height="200" :options="{ threshold: 0.5 }">
          <v-card class="mx-auto" max-width="336" color="indigo" dark>
            <v-card-title>Card Title</v-card-title>

            <v-card-text>
              Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus
              totam aperiam, necessitatibus facilis vitae, ratione officiis
              animi earum veritatis repellat enim, dolore sed atque vero?
              Aliquid, pariatur. Cumque, ad voluptate! Lorem ipsum dolor sit
              amet consectetur adipisicing elit. Error vitae, illo tempore
              quisquam velit distinctio ullam illum sint atque impedit suscipit?
              Modi magni quae accusantium iusto ut explicabo sit facere?
            </v-card-text>
          </v-card>
        </v-lazy>
      </v-responsive>
    </v-responsive>
  </v-app>
</template>
<script>
export default {
  name: 'App',
};
</script>
Lazy loading with the Vuetify lazy component.

v-model

We can use v-model to set up a binding between the render visibility of the root element of v-lazy and a variable. In this code example below, the variable (cardVisible) will be set to true when the card comes into view.

<template>
  <v-app>
    <v-banner class="text-center">Card visible: {{ cardVisible }} </v-banner>
    <v-responsive class="overflow-y-auto" max-height="400">
      <div class="pa-6 text-center">Scroll down</div>

      <v-responsive height="200vh" class="text-center pa-2">
        <v-responsive min-height="50vh"></v-responsive>
        <div class="text-center text-body-2 mb-12">
          The card will appear below:
        </div>

        <v-lazy
          min-height="200"
          v-model="cardVisible"
          :options="{ threshold: 0.5 }"
        >
          <v-card class="mx-auto" max-width="336" color="green" dark>
            <v-card-title>Card Title</v-card-title>

            <v-card-text>
              Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus
              totam aperiam, necessitatibus facilis vitae, ratione officiis
              animi earum veritatis repellat enim, dolore sed atque vero?
              Aliquid, pariatur. Cumque, ad voluptate! Lorem ipsum dolor sit
              amet consectetur adipisicing elit. Error vitae, illo tempore
              quisquam velit distinctio ullam illum sint atque impedit suscipit?
              Modi magni quae accusantium iusto ut explicabo sit facere?
            </v-card-text>
          </v-card>
        </v-lazy>
      </v-responsive>
    </v-responsive>
  </v-app>
</template>
<script>
export default {
  name: 'App',
  data: () => ({
    cardVisible: false,
  }),
};
</script>
Using v-model on the v-lazy component.

Vuetify Lazy Threshold

The Vuetify lazy component comes with the options prop for customizing its behaviours. These options are passed to the constructor of the Intersection Observer class that v-lazy uses internally. One of such options is threshold. We can set threshold to a number to indicate how much of the root element of v-lazy should come into the viewport before it is displayed. The default threshold is 0, which means that the element will be rendered as soon as even a single pixel enters the viewport.

<template>
  <v-app>
    <v-banner class="text-center">
      <v-row>
        <v-col> 0% </v-col>
        <v-col> 50% </v-col>
        <v-col> 100% </v-col>
      </v-row>
    </v-banner>
    <v-responsive class="overflow-y-auto" max-height="400">
      <div class="pa-6 text-center">Scroll down</div>
      <v-responsive height="200vh" class="text-center pa-2">
        <v-responsive min-height="50vh"></v-responsive>
        <div class="text-center text-body-2 mb-12">
          The cards will appear below:
        </div>
        <v-row>
          <v-col>

            <v-lazy min-height="200" :options="{ threshold: 0 }">
              <v-card class="mx-auto" color="red" dark>
                <v-card-title>Card Title</v-card-title>

                <v-card-text>
                  Lorem ipsum dolor sit amet, consectetur adipisicing elit.
                  Ducimus totam aperiam, necessitatibus facilis vitae, ratione
                  officiis animi earum veritatis repellat enim, dolore sed atque
                  vero? Aliquid, pariatur. Cumque, ad voluptate!
                </v-card-text>
              </v-card>
            </v-lazy>
            
          </v-col>
          <v-col>

            <v-lazy min-height="200" :options="{ threshold: 0.5 }">
              <v-card class="mx-auto" color="yellow darken-3" dark>
                <v-card-title>Card Title</v-card-title>

                <v-card-text>
                  Lorem ipsum dolor sit amet, consectetur adipisicing elit.
                  Ducimus totam aperiam, necessitatibus facilis vitae, ratione
                  officiis animi earum veritatis repellat enim, dolore sed atque
                  vero? Aliquid, pariatur. Cumque, ad voluptate!
                </v-card-text>
              </v-card>
            </v-lazy>

          </v-col>
          <v-col>

            <v-lazy min-height="200" :options="{ threshold: 1 }">
              <v-card class="mx-auto" color="blue" dark>
                <v-card-title>Card Title</v-card-title>

                <v-card-text>
                  Lorem ipsum dolor sit amet, consectetur adipisicing elit.
                  Ducimus totam aperiam, necessitatibus facilis vitae, ratione
                  officiis animi earum veritatis repellat enim, dolore sed atque
                  vero? Aliquid, pariatur. Cumque, ad voluptate!
                </v-card-text>
              </v-card>
            </v-lazy>

          </v-col>
        </v-row>
      </v-responsive>
    </v-responsive>
  </v-app>
</template>
<script>
export default {
  name: 'App',
};
</script>
Customizing the threshold with the Vuetify lazy component.

Custom Transition

v-lazy also comes with the transition prop that we can use to customize the transition the root element uses to come into view (the default is a fade-transition). For example, we can set a scale-transition to make it grow into view:

<template>
  <v-app>
    <v-responsive class="overflow-y-auto" max-height="400">
      <div class="pa-6 text-center">Scroll down</div>
      <v-responsive height="200vh" class="text-center pa-2">
        <v-responsive min-height="50vh"></v-responsive>
        <div class="text-center text-body-2 mb-12">
          The card will appear below:
        </div>
        <v-lazy
          min-height="200"
          :options="{ threshold: 1 }"
          transition="scale-transition"
        >
          <v-card class="mx-auto" color="purple accent-4" dark max-width="300">
            <v-card-title>Card Title</v-card-title>

            <v-card-text>
              Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus
              totam aperiam, necessitatibus facilis vitae, ratione officiis
              animi earum veritatis repellat enim, dolore sed atque vero?
              Aliquid, pariatur. Cumque, ad voluptate!
            </v-card-text>
          </v-card>
        </v-lazy>
      </v-responsive>
    </v-responsive>
  </v-app>
</template>
<script>
export default {
  name: 'App',
};
</script>
Customizing the transition of the v-lazy component.

Conclusion

Lazy loading is a useful technique for reducing page loading times and optimizing performance. We can use the Vuetify lazy component (v-lazy) to implement lazy loading.

How to Use the Vuetify Tooltip Component

Tooltips are useful for passing on information when a user hovers over an element in an interface. When a tooltip is activated, it displays a text label that identifies its associated element, for example, describing its function. Read on to find out more about the Vuetify tooltip component and the different customization options provided.

The v-tooltip Component

Vuetify provides the v-tooltip component for creating a tooltip. v-tooltip can wrap any element.

<template>
  <v-app>
    <div class="text-center d-flex ma-4 justify-center">
      <v-tooltip bottom>
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on"> Button </v-btn>
        </template>
        <span>Tooltip</span>
      </v-tooltip>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Creating a tooltip with the Vuetify tooltip component.

Vuetify Tooltip Alignment

We can use one of the position props (top, bottom, left, or right) of the v-tooltip component to set the tooltip alignment. Note that it is required to set one of these props.

<template>
  <v-app>
    <div class="d-flex ma-4 justify-space-around">
      <v-tooltip left>
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on"> Left </v-btn>
        </template>
        <span>Left tooltip</span>
      </v-tooltip>

      <v-tooltip top>
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on"> Top </v-btn>
        </template>
        <span>Top tooltip</span>
      </v-tooltip>

      <v-tooltip bottom>
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on"> Bottom </v-btn>
        </template>
        <span>Bottom tooltip</span>
      </v-tooltip>

      <v-tooltip right>
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on"> Right </v-btn>
        </template>
        <span>Right tooltip</span>
      </v-tooltip>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Set tooltip alignment with the position props of the v-tooltip component.

Vuetify Tooltip Colors

Like many other components in Vuetify, the v-tooltip component comes with the color prop for customizing the color of the tooltip.

<template>
  <v-app>
    <div class="d-flex ma-4 justify-space-around">
      <v-tooltip bottom color="primary">
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on"> primary </v-btn>
        </template>
        <span>Primary tooltip</span>
      </v-tooltip>

      <v-tooltip bottom color="success">
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="success" dark v-bind="attrs" v-on="on"> success </v-btn>
        </template>
        <span>Success tooltip</span>
      </v-tooltip>

      <v-tooltip bottom color="warning">
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="warning" dark v-bind="attrs" v-on="on"> warning </v-btn>
        </template>
        <span>Warning tooltip</span>
      </v-tooltip>

      <v-tooltip bottom color="error">
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="error" dark v-bind="attrs" v-on="on"> error </v-btn>
        </template>
        <span>Error tooltip</span>
      </v-tooltip>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting tooltip color with the color prop of the v-tooltip component.

Vuetify Tooltip Visibility

Using v-model on a v-tooltip allows us to set up a two-way binding between the visibility of the tooltip and a variable. For example, in the code below, we’ve created a button and a tooltip below it. Clicking the button will negate the show variable and toggle the visibility of the tooltip.

<template>
  <v-app>
    <v-container fluid class="text-center ma-4">
      <v-row class="flex" justify="space-between">
        <v-col cols="12">
          <v-btn @click="show = !show" color="purple accent-4" dark>
            toggle
          </v-btn>
        </v-col>

        <v-col cols="12" class="mt-12">
          <v-tooltip v-model="show" top>
            <template v-slot:activator="{ on, attrs }">
              <v-btn icon v-bind="attrs" v-on="on">
                <v-icon color="grey lighten-1"> mdi-alarm </v-icon>
              </v-btn>
            </template>
            <span>Programmatic tooltip</span>
          </v-tooltip>
        </v-col>
      </v-row>
    </v-container>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    show: false,
  }),
};
</script>
Using v-model on a v-tooltip.

Conclusion

A tooltip is useful for conveying information when the user hovers over an element. Use the Vuetify tooltip component (v-tooltip) and its various props to create and customize tooltips.

How to Use the Vuetify Image Component

Images are an indispensable part of every user interface. They improve the user experience and increase engagement. An image can be used along with text to explain a concept or convey information quickly, as people tend to process visual information faster. In this article, we’re going to learn how to display an image in Vuetify with the v-img component.

The Vuetify Image Component

Vuetify provides the v-img component for presenting an image. This component comes with various props to customize the appearance of the image.

<template>
  <v-app>
    <div class="d-flex justify-center ma-4">
      <v-img
        contain
        max-height="300"
        min-height="300"
        src="https://picsum.photos/1920/1080?random"
      ></v-img>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Creating an image with the Vuetify image component.

Image Aspect Ratios in Vuetify

Use the aspect-ratio prop of the v-img component to set a fixed aspect ratio. The ratio between the height and width stays the same when the image is resized.

<template>
  <v-app>
    <div class="d-flex flex-column justify-space-between align-center ma-4">
      <v-slider
        v-model="width"
        class="align-self-stretch"
        min="200"
        max="500"
      ></v-slider>

      <v-img
        :aspect-ratio="16 / 9"
        :width="width"
        src="https://picsum.photos/1920/1080?random"
      ></v-img>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    width: 300,
  }),
};
</script>
Setting image aspect ratios in Vuetify.

Vuetify Image Contain

When the provided aspect ratio doesn’t match that of the actual image, the v-img component will fill as much space and clip the sides of the image. Setting the contain prop to true will stop this from happening, but will result in empty space at the sides.

<template>
  <v-app>
    <v-container fluid>
      <v-row justify="space-around">
        <v-col cols="5">
          <div class="text-h6 mb-1">Default (cover)</div>
          <div class="subheading">Matching</div>
          <v-img
            src="https://picsum.photos/510/300?random"
            aspect-ratio="1.7"
          ></v-img>
          <div class="subheading pt-4">Too high</div>
          <v-img
            src="https://picsum.photos/510/300?random"
            aspect-ratio="2"
          ></v-img>
          <div class="subheading pt-4">Too low</div>
          <v-img
            src="https://picsum.photos/510/300?random"
            aspect-ratio="1.4"
          ></v-img>
        </v-col>

        <v-col cols="5">
          <div class="text-h6 mb-1">Contain</div>
          <div class="subheading">Matching</div>
          <v-img
            src="https://picsum.photos/510/300?random"
            aspect-ratio="1.7"
            contain
          ></v-img>
          <div class="subheading pt-4">Too high</div>
          <v-img
            src="https://picsum.photos/510/300?random"
            aspect-ratio="2"
            contain
          ></v-img>
          <div class="subheading pt-4">Too low</div>
          <v-img
            src="https://picsum.photos/510/300?random"
            aspect-ratio="1.4"
            contain
          ></v-img>
        </v-col>
      </v-row>
    </v-container>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the contain prop of the Vuetify image component.

Vuetify Image Gradient

Use the gradient prop to apply a simple gradient overlay to the image. For more complex gradients, we can use a CSS class instead.

<template>
  <v-app>
    <v-row class="ma-4">
      <v-col cols="6" sm="4">
        <v-img
          src="https://picsum.photos/1920/1080?random"
          gradient="to top right, rgba(100,115,201,.33), rgba(25,32,72,.7)"
        ></v-img>
      </v-col>

      <v-col cols="6" sm="4">
        <v-img src="https://picsum.photos/1920/1080?random">
          <div class="fill-height bottom-gradient"></div>
        </v-img>
      </v-col>

      <v-col cols="6" sm="4">
        <v-img src="https://picsum.photos/1920/1080?random">
          <div class="fill-height repeating-gradient"></div>
        </v-img>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',

};
</script>

<style scoped>
.bottom-gradient {
  background-image: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.4) 0%,
    transparent 72px
  );
}

.repeating-gradient {
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(255, 0, 0, 0.25),
    rgba(255, 0, 0, 0.25) 5px,
    rgba(0, 0, 255, 0.25) 5px,
    rgba(0, 0, 255, 0.25) 10px
  );
}
</style>
Customizing image gradients in Vuetify.

Vuetify Image Height

The Vuetify image component automatically grows to the size of its src and preserves the correct aspect ratio. We can use the height and max-height props to limit this:

<template>
  <v-app>
    <v-container class="fill-height" fluid>
      <v-fade-transition mode="out-in">
        <v-row>
          <v-col cols="6">
            <v-card>
              <v-img
                src="https://picsum.photos/350/165?random"
                height="125"
                class="grey darken-4"
              ></v-img>
              <v-card-title class="text-h6"> height </v-card-title>
            </v-card>
          </v-col>

          <v-col cols="6">
            <v-card>
              <v-img
                src="https://picsum.photos/350/165?random"
                height="125"
                contain
                class="grey darken-4"
              ></v-img>
              <v-card-title class="text-h6"> height with contain </v-card-title>
            </v-card>
          </v-col>

          <v-col cols="6">
            <v-card>
              <v-img
                src="https://picsum.photos/350/165?random"
                max-height="125"
                class="grey darken-4"
              ></v-img>
              <v-card-title class="text-h6"> max-height </v-card-title>
            </v-card>
          </v-col>

          <v-col cols="6">
            <v-card>
              <v-img
                src="https://picsum.photos/350/165?random"
                max-height="125"
                contain
                class="grey darken-4"
              ></v-img>
              <v-card-title class="text-h6">
                max-height with contain
              </v-card-title>
            </v-card>
          </v-col>
        </v-row>
      </v-fade-transition>
    </v-container>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting image height with the Vuetify image component.

Vuetify Image Placeholder

We can use the v-img placeholder slot to display custom content while the image is loading. The image in the example below has a bad src and it won’t load so we can see the placeholder.

<template>
  <v-app>
    <v-row justify="center" class="ma-4">
      <v-img
        src="https://bad.src/not/valid"
        lazy-src="https://picsum.photos/id/12/100/60"
        max-width="500"
        max-height="300"
      >
        <template v-slot:placeholder>
          <v-row class="fill-height ma-0" align="center" justify="center">
            <v-progress-circular
              indeterminate
              color="grey lighten-5"
            ></v-progress-circular>
          </v-row>
        </template>
      </v-img>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the placeholder prop of the v-img component.s

We can use the v-img component to make an image gallery.

<template>
  <v-app>
    <v-row class="ma-4">
      <v-col v-for="n in 6" :key="n" class="d-flex child-flex" cols="4">
        <v-img
          :src="`https://picsum.photos/500/300?image=${n * 12 + 5}`"
          :lazy-src="`https://picsum.photos/10/6?image=${n * 12 + 10}`"
          aspect-ratio="1"
          class="grey lighten-2"
        >
          <template v-slot:placeholder>
            <v-row class="fill-height ma-0" align="center" justify="center">
              <v-progress-circular
                indeterminate
                color="grey lighten-5"
              ></v-progress-circular>
            </v-row>
          </template>
        </v-img>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

Conclusion

Images are an important part of every interface that can help to increase engagement, decorate the UI and enable users to process information faster. We can use the Vuetify image component (v-img) to show images and customize the way they are displayed.

Vuetify Progress Circular: How to Create Circular Progress Bars

A circular progress bar is used to pass on information to the user about some ongoing operation. Just like horizontal progress bars, they visually signify how far the operation has advanced. Read on to learn about the Vuetify progress circular component and the various ways in which we can customize it.

The Vuetify Progress Circular Component

Vuetify provides the v-progress-circular component for creating circular progress bars. We use the value prop to set the progress bar value to a number between 0 and 100 inclusive.

<template>
  <v-app>
    <div class="d-flex justify-center ma-4">
      <div class="d-flex justify-space-between" style="width: 60%">
        <v-progress-circular></v-progress-circular>

        <v-progress-circular :value="20"></v-progress-circular>

        <v-progress-circular :value="40"></v-progress-circular>

        <v-progress-circular :value="60"></v-progress-circular>

        <v-progress-circular :value="80"></v-progress-circular>

        <v-progress-circular :value="100"></v-progress-circular>
      </div>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Vuetify progress circular components.

Circular Progress Bar Colors in Vuetify

The Vuetify progress circular component provides the color prop for customizing the color of the circular progress bar.

<template>
  <v-app>
    <div class="d-flex justify-center ma-4">
      <div class="d-flex justify-space-between" style="width: 60%">
        <v-progress-circular :value="20" color="green"></v-progress-circular>

        <v-progress-circular :value="40" color="primary"></v-progress-circular>

        <v-progress-circular :value="60" color="red"></v-progress-circular>

        <v-progress-circular
          :value="80"
          color="purple accent-4"
        ></v-progress-circular>

        <v-progress-circular
          :value="100"
          color="yellow darken-3"
        ></v-progress-circular>
      </div>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Customizing circular progress bar colors in Vuetify.

Indeterminate Circular Progress Bars in Vuetify

Similar to the Vuetify progress linear component, v-progress-circular can be set to an indeterminate mode. It animates continuously when indeterminate:

<template>
  <v-app>
    <div class="d-flex justify-center ma-4">
      <div class="d-flex justify-space-between" style="width: 60%">
        <v-progress-circular indeterminate color="lime"></v-progress-circular>

        <v-progress-circular indeterminate color="red"></v-progress-circular>

        <v-progress-circular
          indeterminate
          color="primary"
        ></v-progress-circular>

        <v-progress-circular
          indeterminate
          color="yellow darken-3"
        ></v-progress-circular>

        <v-progress-circular
          indeterminate
          color="purple accent-4"
        ></v-progress-circular>
      </div>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Indeterminate progress circular components.

Vuetify Progress Circular Rotate

The rotate prop allows us to customize the origin of the circular progress bar.

<template>
  <v-app>
    <div class="d-flex justify-center ma-4">
      <div class="d-flex justify-space-between" style="width: 60%">
        <v-progress-circular
          :rotate="360"
          :size="100"
          :width="15"
          :value="value"
          color="purple accent-4"
        >
          {{ value }}
        </v-progress-circular>

        <v-progress-circular
          :rotate="-90"
          :size="100"
          :width="15"
          :value="value"
          color="primary"
        >
          {{ value }}
        </v-progress-circular>

        <v-progress-circular
          :rotate="90"
          :size="100"
          :width="15"
          :value="value"
          color="green"
        >
          {{ value }}
        </v-progress-circular>

        <v-progress-circular
          :rotate="180"
          :size="100"
          :width="15"
          :value="value"
          color="red accent-2"
        >
          {{ value }}
        </v-progress-circular>
      </div>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      interval: {},
      value: 0,
    };
  },
  beforeDestroy() {
    clearInterval(this.interval);
  },
  mounted() {
    this.interval = setInterval(() => {
      this.value = this.value === 100 ? 0 : this.value + 10;
    }, 1000);
  },
};
</script>
Using the rotate prop on the Vuetify progress circular component.

Vuetify Progress Circular Size and Thickness

The size prop of v-progress-circular allows us to modify the height of the circular progress bar, while the width prop enables customization of the thickness of the progress bar.

<template>
  <v-app>
    <div class="d-flex justify-center ma-4">
      <div class="d-flex justify-space-between align-center" style="width: 60%">
        <v-progress-circular
          :size="50"
          color="red accent-2"
          indeterminate
        ></v-progress-circular>

        <v-progress-circular
          :width="3"
          color="primary"
          indeterminate
        ></v-progress-circular>

        <v-progress-circular
          :size="70"
          :width="9"
          color="orange"
          indeterminate
        ></v-progress-circular>

        <v-progress-circular
          :width="3"
          color="green"
          indeterminate
        ></v-progress-circular>

        <v-progress-circular
          :size="50"
          color="purple accent-4"
          indeterminate
        ></v-progress-circular>
      </div>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      interval: {},
      value: 0,
    };
  },
  beforeDestroy() {
    clearInterval(this.interval);
  },
  mounted() {
    this.interval = setInterval(() => {
      this.value = this.value === 100 ? 0 : this.value + 10;
    }, 1000);
  },
};
</script>
Customizing the size and thickness of circular progress bars.

Conclusion

A circular progress bar conveys information to the user about the current progress on an ongoing process in an application. Use the Vuetify progress circular component (v-progress-circular) to create and customize circular progress bars.

Vuetify Progress Linear: How to Create Horizontal Progress Bars

Progress bars are used in an interface to pass on information to users related to the known progression of a certain operation. They visually signify how far the operation has advanced and can be circular or horizontal. They can also be indefinite to indicate the loading or processing of data. In this article, we’re going to learn how to create a horizontal progress bar with the Vuetify progress linear component.

The v-progress-linear Component

Vuetify provides the v-progress-linear component for creating a horizontal progress bar.

<template>
  <v-app>
    <v-progress-linear></v-progress-linear>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Creating a horizontal progress bar with the Vuetify progress linear component.

Progress Bar Value

The progress linear component comes with the value prop that we can use to set the progress bar to a determinate value between 0 and 100 inclusive:

<template>
  <v-app>
    <v-row justify="center" class="ma-4">
      <v-col sm="6">
        <v-progress-linear value="40"></v-progress-linear>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting a progress bar value.

Progress Linear v-model

We can set up a two-way binding between the value of the progress bar and a variable using v-model:

<template>
  <v-app>
    <v-row justify="center" class="ma-4">
      <v-col sm="6">
        <v-progress-linear v-model="value"></v-progress-linear>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 30,
  }),
};
</script>
Using v-model with the progress linear component.

To see this two-way binding in action, let’s create two buttons to change the progress bar value and some text to display this value. We spaced the buttons apart with one of the Vuetify spacing helper classes (ma-2).

<template>
  <v-app>
    <v-row justify="center" class="ma-4">
      <v-col sm="6">
        <v-row>
          <v-progress-linear v-model="value"></v-progress-linear>
        </v-row>
        <v-row justify="center">{{ value }}%</v-row>
        <v-row justify="center">
          <v-btn class="ma-2" @click="value -= 10" color="red" dark>
            -10
          </v-btn>
          <v-btn class="ma-2" @click="value += 10" color="green" dark>
            +10
          </v-btn>
        </v-row>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 30,
  }),
};
</script>
Using v-model to show and change the value of the progress bar.

Progress Linear Buffer Value

A buffer state simultaneously represents two values. The primary value is controlled by v-model, while the buffer value is controlled by the buffer-value prop:

<template>
  <v-app>
    <v-row justify="center" class="ma-4">
      <v-col sm="8">
        <v-progress-linear
          v-model="value"
          :buffer-value="bufferValue"
        ></v-progress-linear>
        <br />
        <v-progress-linear
          v-model="value"
          :buffer-value="bufferValue"
          color="green"
        ></v-progress-linear>
        <br />
        <v-progress-linear
          v-model="value"
          :buffer-value="bufferValue"
          color="orange"
        ></v-progress-linear>
        <br />
        <v-progress-linear
          v-model="value"
          :buffer-value="bufferValue"
          color="purple accent-4"
        ></v-progress-linear>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      value: 10,
      bufferValue: 20,
      interval: 0,
    };
  },

  watch: {
    value(val) {
      if (val < 100) return;

      this.value = 0;
      this.bufferValue = 10;
      this.startBuffer();
    },
  },

  mounted() {
    this.startBuffer();
  },

  beforeDestroy() {
    clearInterval(this.interval);
  },

  methods: {
    startBuffer() {
      clearInterval(this.interval);

      this.interval = setInterval(() => {
        this.value += Math.random() * (15 - 5) + 5;
        this.bufferValue += Math.random() * (15 - 5) + 6;
      }, 1000);
    },
  },
};
</script>
Setting a buffer value on the progress linear component.

Progress Bar Custom Colors

The Vuetify progress linear component comes with a color prop that allows us to customize the color of the horizontal progress bar:

<template>
  <v-app>
    <v-row justify="center" class="ma-4">
      <v-col sm="8">
        <v-progress-linear
          background-color="blue"
          color="red accent-2"
          value="20"
        ></v-progress-linear>
        <br />
        <v-progress-linear
          background-color="grey"
          color="yellow"
          value="40"
        ></v-progress-linear>
        <br />
        <v-progress-linear
          background-color="green lighten-3"
          color="green"
          value="60"
        ></v-progress-linear>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Customizing the colors of progress bars.

Progress Linear Indeterminate

We can display an indeterminate progress bar with the indeterminate prop.

<template>
  <v-app>
    <v-row justify="center" class="ma-4">
      <v-col sm="8">
        <v-progress-linear indeterminate color="red"></v-progress-linear>
        <br />
        <v-progress-linear indeterminate color="primary"></v-progress-linear>
        <br />
        <v-progress-linear indeterminate color="green"></v-progress-linear>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

The progress bar will animate continuously when indeterminate:

Indeterminate progress linear components.

Reversed Progress Bar

Setting the reverse prop to true will display a reversed progress bar (right to left in LTR mode and left to right in RTL).

<template>
  <v-app>
    <v-row justify="center" class="ma-4">
      <v-col sm="8">
        <v-progress-linear
          color="indigo"
          value="15"
          reverse
        ></v-progress-linear>

        <br />

        <v-progress-linear
          color="teal"
          indeterminate
          reverse
        ></v-progress-linear>

        <br />

        <v-progress-linear
          buffer-value="55"
          color="red accent-2"
          reverse
          stream
          value="30"
        ></v-progress-linear>

        <br />

        <v-subheader
          >In specific cases you may want progress to display in left-to-right
          mode regardless of the application direction (LTR or
          RTL):</v-subheader
        >

        <v-progress-linear
          :reverse="$vuetify.rtl"
          value="15"
          color="yellow darken-3"
        ></v-progress-linear>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Reversed progress bar.

Progress Linear Rounded

We can add a border radius to the Vuetify progress linear component by setting the rounded prop to true:

<template>
  <v-app>
    <v-row justify="center" class="ma-4">
      <v-col sm="8">
        <v-progress-linear
          color="blue accent-2"
          rounded
          value="100"
        ></v-progress-linear>

        <br />

        <v-progress-linear color="pink" rounded value="100"></v-progress-linear>

        <br />

        <v-progress-linear
          color="orange"
          rounded
          value="100"
        ></v-progress-linear>

        <br />

        <v-progress-linear
          color="purple accent-4"
          rounded
          value="100"
        ></v-progress-linear>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Rounded progress linear components.

Progress Bar Stream

The stream prop works with buffer-value to inform the user that some action is taking place.

<template>
  <v-app>
    <v-row justify="center" class="ma-4">
      <v-col sm="8">
        <v-progress-linear
          color="yellow darken-3"
          buffer-value="0"
          stream
        ></v-progress-linear>
        <br />
        <v-progress-linear
          color="primary"
          buffer-value="0"
          value="20"
          stream
        ></v-progress-linear>
        <br />
        <v-progress-linear
          buffer-value="50"
          stream
          color="red"
        ></v-progress-linear>
        <br />
        <v-progress-linear
          buffer-value="60"
          value="40"
          stream
          color="green"
        ></v-progress-linear>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the stream prop on horizontal progress bars.

Striped Progress Bar

The striped prop applies a striped background over the value portion of the horizontal progress bar.

<template>
  <v-app>
    <v-row justify="center" class="ma-4">
      <v-col sm="8">
        <v-progress-linear
          color="indigo"
          height="10"
          value="10"
          striped
        ></v-progress-linear>
        <br />
        <v-progress-linear
          color="cyan"
          height="10"
          value="20"
          striped
        ></v-progress-linear>
        <br />
        <v-progress-linear
          height="10"
          value="45"
          striped
          color="green"
        ></v-progress-linear>
        <br />
        <v-progress-linear
          value="60"
          height="10"
          striped
          color="orange"
        ></v-progress-linear>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Striped horizontal progress bars.

Default Slot

With the default slot of the progress linear component, we can display custom components inside the progress bar.

<template>
  <v-app>
    <v-row justify="center" class="ma-4">
      <v-col sm="8">
        <v-progress-linear
          :indeterminate="query"
          :query="true"
          height="25"
          value="30"
        >
          <template v-slot:default="{ value }">
            <strong>{{ value }}%</strong>
          </template>
        </v-progress-linear>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    query: false,
  }),
};
</script>

Here, we simply display the progress bar value as a percentage:

Using the progress linear component default slot

Using a Progress Bar as a Loading Indicator

One instance where the progress linear component is useful is in communicating to the user that a response is pending. Like when fetching the user’s photos from a server in a sample photo app.

<template>
  <v-app>
    <v-app-bar app color="primary" dark>
      <v-app-bar-nav-icon></v-app-bar-nav-icon>
      <v-toolbar-title>Photos</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-share-variant</v-icon>
      </v-btn>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
      <v-btn icon>
        <v-icon>mdi-dots-vertical</v-icon>
      </v-btn>
    </v-app-bar>
    <v-container style="flex: 1">
      <v-row class="fill-height" align-content="center" justify="center">
        <v-col class="text-subtitle-1 text-center" cols="12">
          Getting your photos
        </v-col>
        <v-col cols="6">
          <v-progress-linear
            color="primary"
            indeterminate
            rounded
            height="6"
          ></v-progress-linear>
        </v-col>
      </v-row>
    </v-container>
  </v-app>
</template>

<script>
export default {
  name: 'App',

};
</script>
Using a progress bar as a loading indicator.

Using a Progress Bar as an App Bar Loader

A progress bar can also function as an app bar loader. With the absolute and bottom props, we can position it at the bottom of the app bar and control its visibility with the active prop:

<template>
  <v-app>
    <v-system-bar>
      <v-spacer></v-spacer>
      <v-icon>mdi-square</v-icon>
      <v-icon>mdi-circle</v-icon>
      <v-icon>mdi-triangle</v-icon>
    </v-system-bar>

    <v-app-bar app color>
      <v-btn icon>
        <v-icon>mdi-arrow-left</v-icon>
      </v-btn>

      <v-toolbar-title>Books</v-toolbar-title>

      <v-progress-linear
        :active="loading"
        :indeterminate="loading"
        absolute
        bottom
        color="indigo"
      ></v-progress-linear>

      <v-spacer></v-spacer>

      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>

      <v-btn icon>
        <v-icon>mdi-dots-vertical</v-icon>
      </v-btn>
    </v-app-bar>

    <v-container style="flex: 1">
      <v-row class="fill-height" align="center" justify="center">
        <v-scale-transition>
          <div v-if="!loading" class="text-center">
            <v-btn color="indigo" dark @click="loading = true">
              Start loading
            </v-btn>
          </div>
        </v-scale-transition>
      </v-row>
    </v-container>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    loading: false,
  }),
  watch: {
    loading(val) {
      if (!val) return;

      setTimeout(() => (this.loading = false), 3000);
    },
  },
};
</script>
Using a progress bar as an app bar loader.

Conclusion

A progress bar conveys information to the user about the current progress of an ongoing event in an application. Use the Vuetify progress linear component (v-progress-linear) and its various props to create and customize horizontal linear progress bars.

How to Easily Create Versatile Menus in Vuetify

A menu is a versatile component in a user interface. It shows a popover that can serve various functions, such as displaying a list of options. They can be used with other components like a toolbar, app bar, or a button. In this article, we’re to learn how to create and customize a menu in Vuetify.

The v-menu Component

Vuetify provides the v-menu component for creating a menu. We use the activator slot to set the component that will activate the menu when clicked. We set it to a button in this example:

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu offset-y>
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on">
            Dropdown
          </v-btn>
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

Clicking the button will display the popover menu:

Creating a menu in Vuetify.

Creating an Absolute Menu in Vuetify

We can place a menu on the top of the element in the activator slot with the absolute prop.

<template>
  <v-app>
    <div class="d-flex justify-center ma-4">
      <v-menu offset-y absolute>
        <template v-slot:activator="{ on, attrs }">
          <v-card
            class="portrait"
            img="https://picsum.photos/1920/1080?random"
            height="300"
            width="600"
            v-bind="attrs"
            v-on="on"
          ></v-card>
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Creating an an absolute menu in Vuetify.

Absolute Menu without Activator

We can also use a menu without an activator by using absolute together with the position-x and position-y props. This is useful for creating a context menu:

<template>
  <v-app>
    <div>
      <div class="d-flex justify-center ma-4">
        <v-card
          :ripple="false"
          class="portrait"
          img="https://picsum.photos/1920/1080?random"
          height="300"
          width="600"
          @contextmenu="show"
        ></v-card>
      </div>
      <v-menu
        v-model="showMenu"
        :position-x="x"
        :position-y="y"
        absolute
        offset-y
      >
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Option {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    showMenu: false,
    x: 0,
    y: 0,
  }),

  methods: {
    show(e) {
      e.preventDefault();
      this.showMenu = false;
      this.x = e.clientX;
      this.y = e.clientY;
      this.$nextTick(() => {
        this.showMenu = true;
      });
    },
  },
};
</script>
Displaying a menu without an activator.

Closing the Menu on Click

The close-on-click prop determines whether the menu closes when it loses focus or not.

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu offset-y :close-on-click="true">
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on">
            Dropdown
          </v-btn>
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

Here close-on-click is set to true, so clicking on another element will close the menu:

Setting the close-on-click prop to true

If we set it to false:

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu offset-y :close-on-click="false">
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on">
            Dropdown
          </v-btn>
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

It will remain open even when we click on another element or remove its focus:

Setting the close-on-click prop to false.

Close Menu on Content Click

We can use the close-on-content-click prop to determine whether the menu should be closed when its content is clicked.

Setting close-on-content-click to true:

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu offset-y :close-on-content-click="true">
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="purple accent-4" dark v-bind="attrs" v-on="on">
            Dropdown
          </v-btn>
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting close-on-content-click to true on a menu.

Setting close-on-content-click to false:

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu offset-y :close-on-content-click="false">
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="purple accent-4" dark v-bind="attrs" v-on="on">
            Dropdown
          </v-btn>
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting close-on-content-click to false on a menu.

Disabled Menu

We can prevent a menu from being opened with the disabled prop:

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu offset-y disabled>
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="green" dark v-bind="attrs" v-on="on"> Dropdown </v-btn>
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
A disabled menu.

Offset X

We can use the offset-x prop to offset the menu by the X-axis to make the activator visible.

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu offset-x>
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on">
            Dropdown
          </v-btn>
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the offset-x prop on a menu.

Offset Y

We can also offset the menu by the Y-axis to make the activator visible.

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu offset-y>
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on">
            Dropdown
          </v-btn>
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting offset-y on a menu.

Offset X and Offset Y

We can also combine these two props:

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu offset-x offset-y>
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on">
            Dropdown
          </v-btn>
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Combining the v-menu offset-x and offset-y props.

Open Menu on Hover

Setting the open-on-hover prop to true will make the menu open when its activator is hovered over.

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu open-on-hover offset-y>
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="teal" dark v-bind="attrs" v-on="on"> Dropdown </v-btn>
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Making a menu open on hover in Vuetify.

Creating a Rounded Menu in Vuetify

The rounded prop allows us to customize the border-radius of a menu.

Setting it to 0 will remove the border-radius:

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu offset-y rounded="0">
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="blue" dark v-bind="attrs" v-on="on">
            Removed Radius
          </v-btn>
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Removing the menu radius with Vuetify.

We can give the menu a large border-radius by setting rounded to true:

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu offset-y rounded="lg">
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="indigo" dark v-bind="attrs" v-on="on">
            Large Radius</v-btn
          >
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting a large menu border radius with Vuetify.

We can also specify a custom border-radius, for example:

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu offset-y rounded="b-xl">
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="red" dark v-bind="attrs" v-on="on">
            Custom Radius</v-btn
          >
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting a custom menu border radius with Vuetify.

Using a Menu with a Tooltip

We can also display a tooltip for a menu. We do this by nesting activator slots with the v-slot syntax and attaching the props of the slots to the same activator component (a button in this case).

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu>
        <template v-slot:activator="{ on: menu, attrs }">
          <v-tooltip bottom>
            <template v-slot:activator="{ on: tooltip }">
              <v-btn
                color="primary"
                dark
                v-bind="attrs"
                v-on="{ ...tooltip, ...menu }"
              >
                Dropdown w/ Tooltip</v-btn
              >
            </template>
            <span>This is a tooltip</span>
          </v-tooltip>
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using a dropdown with a tooltip.

Custom Menu Transitions in Vuetify

We can also customize the transition that the menu will use to open and close. Vuetify comes with three standard transitions: scale, slide-x and slide-y.

Scale Transition

The scale-transition makes the menu grow in size when opening, and shrink back when closing:

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu transition="scale-transition" origin="center center" bottom>
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on">
            Scale Transition</v-btn
          >
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting the menu transition to scale-transition.

Slide X Transition

The slide-x-transition makes the menu slide in from the left when opening, and slide back out when closing:

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu transition="slide-x-transition" bottom right>
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on">
            Slide X Transition</v-btn
          >
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting the menu transition to slide-x-transition.

Slide Y Transition

The slide-y-transition makes the menu slide in from the top when opening, and slide back out when closing:

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-menu transition="slide-y-transition" bottom>
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on">
            Slide X Transition</v-btn
          >
        </template>
        <v-list>
          <v-list-item v-for="index in 4" :key="index">
            <v-list-item-title>Item {{ index }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting the menu transition to slide-y-transition.

Using a Menu with an App Bar

We can use a menu with a toolbar or app bar:

<template>
  <v-app>
    <v-app-bar app color="deep-purple accent-4" dark>
      <v-app-bar-nav-icon> </v-app-bar-nav-icon>
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon> <v-icon> mdi-heart </v-icon> </v-btn>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
      <v-menu left bottom>
        <template v-slot:activator="{ on, attrs }">
          <v-btn icon v-bind="attrs" v-on="on">
            <v-icon>mdi-dots-vertical</v-icon>
          </v-btn>
        </template>

        <v-list>
          <v-list-item v-for="n in 4" :key="n" @click="() => {}">
            Option {{ n }}
          </v-list-item>
        </v-list>
      </v-menu>
    </v-app-bar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using a menu with an app bar.

Conclusion

A menu is a versatile user interface component in a user interface that shows a popover that we can use for a variety of purposes. It can work with a button, a toolbar or an app bar. Vuetify provides the v-menu component for creating and customizing menus.

How to Easily Create Beautiful App Bars in Vuetify

An app bar is an important part of every user interface and is typically the primary source of site navigation. Like a toolbar, it is displayed at the top of the screen and can be combined with a navigation drawer or tabs. In this article, we’re going to learn how to create and customize app bars with Vuetify.

The v-app-bar Component

Vuetify provides the v-app-bar component for creating app bars. We use the app prop on the component to make Vuetify consider the app bar when dynamically sizing other components, such as v-main.

<template>
  <v-app>
    <v-app-bar app></v-app-bar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
An app bar.

App Bar Title

We can use the v-toolbar-title component to set the app bar title.

<template>
  <v-app>
    <v-app-bar app>
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
    </v-app-bar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
An app bar with a title.

Note: While we could use the v-app-bar-title component to set the app bar title, the Vuetify team does not recommend using it without the shrink-on-scroll prop (discussed later in this article), as it would add an unnecessary resize watcher and additional calculations.

App Bar Nav Icon

v-app-bar-nav-icon is a styled icon button component created specifically for use with a toolbar or app bar. An app bar nav icon is typically placed on the left side of the toolbar or app bar as a hamburger menu, and is often used to control the state of a navigation drawer. We can customize the icon and function of this component with the default slot.

<template>
  <v-app>
    <v-app-bar app>
      <v-app-bar-nav-icon> </v-app-bar-nav-icon>
      <v-toolbar-title>Coding Beauty</v-app-bar-title>
    </v-app-bar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
An app bar with a nav icon.

App Bar Colors

The app bar component comes with the color prop for customizing the color of the app bar. The dark prop makes the color of the text white

<template>
  <v-app>
    <v-app-bar app color="green" dark>
      <v-app-bar-nav-icon> </v-app-bar-nav-icon>
      <v-app-bar-title>Coding Beauty</v-app-bar-title>
    </v-app-bar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Customizing the app bar color.

Collapsed App Bar

Setting the collapse prop to true on the v-app-bar will collapse the app bar at all times:

<template>
  <v-app>
    <v-app-bar app color="primary" dark collapse>
      <v-app-bar-nav-icon> </v-app-bar-nav-icon>
      <v-app-bar-title>Collapsing Bar</v-app-bar-title>
    </v-app-bar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
A collapsed app bar.

Collapse on Scroll

We can decide to use the collapse-on-scroll prop to collapse the app bar only when the user scrolls.

<template>
  <v-app>
    <v-app-bar app color="primary" dark collapse-on-scroll>
      <v-app-bar-nav-icon> </v-app-bar-nav-icon>
      <v-toolbar-title>Collapsing Bar</v-toolbar-title>
    </v-app-bar>
    <v-sheet>
      <v-container style="height: 1000px"> </v-container>
    </v-sheet>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

An app bar that collapses on scroll.

App Bar Actions

We can add functionality to the app bar that we want to be easily accessible to the user with icon buttons.

<template>
  <v-app>
    <v-app-bar app color="yellow accent-3">
      <v-app-bar-nav-icon> </v-app-bar-nav-icon>
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon> <v-icon> mdi-heart </v-icon> </v-btn>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
    </v-app-bar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Adding functionality to the app bar with icon buttons.

App Bar Menu

We can also extend the functionality of the app bar with a menu component (v-menu).

<template>
  <v-app>
    <v-app-bar app color="deep-purple accent-4" dark>
      <v-app-bar-nav-icon> </v-app-bar-nav-icon>
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon> <v-icon> mdi-heart </v-icon> </v-btn>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
      <v-menu left bottom>
        <template v-slot:activator="{ on, attrs }">
          <v-btn icon v-bind="attrs" v-on="on">
            <v-icon>mdi-dots-vertical</v-icon>
          </v-btn>
        </template>

        <v-list>
          <v-list-item v-for="n in 4" :key="n" @click="() => {}">
            Option {{ n }}
          </v-list-item>
        </v-list>
      </v-menu>
    </v-app-bar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
An app bar with a menu.

Clicking the menu icon button will display the popup containing the options we added:

Clicking the menu displays popup containing the options.

Dense App Bar

We can use the dense prop to make an app bar dense. A dense app bar has a lower height than a regular one.

<template>
  <v-app>
    <v-app-bar app color="deep-purple accent-4" dark dense>
      <v-app-bar-nav-icon> </v-app-bar-nav-icon>
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon> <v-icon> mdi-heart </v-icon> </v-btn>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
      <v-menu left bottom>
        <template v-slot:activator="{ on, attrs }">
          <v-btn icon v-bind="attrs" v-on="on">
            <v-icon>mdi-dots-vertical</v-icon>
          </v-btn>
        </template>

        <v-list>
          <v-list-item v-for="n in 4" :key="n" @click="() => {}">
            Option {{ n }}
          </v-list-item>
        </v-list>
      </v-menu>
    </v-app-bar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
A dense app bar.

Elevate on Scroll

When we set the elevate-on-scroll prop to true, the app bar will rest at an elevation of 0dp until the user begins to scroll down. The elevation raises to 4dp once scrolling begins.

<template>
  <v-app>
    <v-app-bar app color="white" elevate-on-scroll>
      <v-app-bar-nav-icon> </v-app-bar-nav-icon>
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon> <v-icon> mdi-heart </v-icon> </v-btn>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
      <v-menu left bottom>
        <template v-slot:activator="{ on, attrs }">
          <v-btn icon v-bind="attrs" v-on="on">
            <v-icon>mdi-dots-vertical</v-icon>
          </v-btn>
        </template>

        <v-list>
          <v-list-item v-for="n in 4" :key="n" @click="() => {}">
            Option {{ n }}
          </v-list-item>
        </v-list>
      </v-menu>
    </v-app-bar>
    <v-sheet>
      <v-container style="height: 1000px"> </v-container>
    </v-sheet>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Making an app bar elevate on scroll.

Extending the App Bar with Tabs

We can extend the app bar with tabs by including the tabs in the extension slot of v-app-bar:

<template>
  <v-app>
    <v-app-bar app color="primary" dark>
      <v-app-bar-nav-icon> </v-app-bar-nav-icon>
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
      <v-menu left bottom>
        <template v-slot:activator="{ on, attrs }">
          <v-btn icon v-bind="attrs" v-on="on">
            <v-icon>mdi-dots-vertical</v-icon>
          </v-btn>
        </template>
      </v-menu>

      <template v-slot:extension>
        <v-tabs align-with-title>
          <v-tab>Tab 1</v-tab>
          <v-tab>Tab 2</v-tab>
          <v-tab>Tab 3</v-tab>
        </v-tabs>
      </template>
    </v-app-bar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Extending the app bar with tabs.

Prominent App Bar

Setting the prominent prop to true will increase its height.

<template>
  <v-app>
    <v-app-bar app color="primary" dark prominent>
      <v-app-bar-nav-icon> </v-app-bar-nav-icon>
      <v-toolbar-title>Title</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
      <v-menu left bottom>
        <template v-slot:activator="{ on, attrs }">
          <v-btn icon v-bind="attrs" v-on="on">
            <v-icon>mdi-dots-vertical</v-icon>
          </v-btn>
        </template>
      </v-menu>

      <template v-slot:extension>
        <v-tabs align-with-title>
          <v-tab>Tab 1</v-tab>
          <v-tab>Tab 2</v-tab>
          <v-tab>Tab 3</v-tab>
        </v-tabs>
      </template>
    </v-app-bar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
A prominent app bar.

Shrink on Scroll

With the shrink-on-scroll prop, we can a prominent app bar reduce in height as the user scrolls down. This allows for a smooth transition to taking up less visual space when the user is scrolling through content.

<template>
  <v-app>
    <v-app-bar app color="primary" dark prominent shrink-on-scroll>
      <v-app-bar-nav-icon> </v-app-bar-nav-icon>
      <v-toolbar-title>Title</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
      <v-menu left bottom>
        <template v-slot:activator="{ on, attrs }">
          <v-btn icon v-bind="attrs" v-on="on">
            <v-icon>mdi-dots-vertical</v-icon>
          </v-btn>
        </template>
      </v-menu>

      <template v-slot:extension>
        <v-tabs align-with-title>
          <v-tab>Tab 1</v-tab>
          <v-tab>Tab 2</v-tab>
          <v-tab>Tab 3</v-tab>
        </v-tabs>
      </template>
    </v-app-bar>
    <v-sheet>
      <v-container style="height: 1000px"></v-container>
    </v-sheet>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Making an app bar shrink on scroll.

App Bar Images

We can display background images on the app bar with the src prop. When we set an image, the color prop acts as a fallback color that the app bar will display when the image has not yet loaded or fails to load.

<template>
  <v-app>
    <v-app-bar
      app
      color="primary"
      dark
      prominent
      src="https://picsum.photos/1920/1080?random"
    >
      <v-app-bar-nav-icon> </v-app-bar-nav-icon>
      <v-toolbar-title>Title</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
      <v-menu left bottom>
        <template v-slot:activator="{ on, attrs }">
          <v-btn icon v-bind="attrs" v-on="on">
            <v-icon>mdi-dots-vertical</v-icon>
          </v-btn>
        </template>
      </v-menu>

      <template v-slot:extension>
        <v-tabs align-with-title>
          <v-tab>Tab 1</v-tab>
          <v-tab>Tab 2</v-tab>
          <v-tab>Tab 3</v-tab>
        </v-tabs>
      </template>
    </v-app-bar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Displaying an image on the app bar.

Fade Image on Scroll

We might want to make the background image on the app bar fade as the user scrolls down. We can do this with the fade-img-on-scroll prop. As we scroll, the image reduces in opacity until it totally fades away and we can only see the background color.

<template>
  <v-app>
    <v-app-bar
      app
      color="grey"
      dark
      prominent
      src="https://picsum.photos/1920/1080?random"
      fade-img-on-scroll
    >
      <v-app-bar-nav-icon> </v-app-bar-nav-icon>
      <v-app-bar-title>Title</v-app-bar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
      <v-menu left bottom>
        <template v-slot:activator="{ on, attrs }">
          <v-btn icon v-bind="attrs" v-on="on">
            <v-icon>mdi-dots-vertical</v-icon>
          </v-btn>
        </template>
      </v-menu>

      <template v-slot:extension>
        <v-tabs align-with-title>
          <v-tab>Tab 1</v-tab>
          <v-tab>Tab 2</v-tab>
          <v-tab>Tab 3</v-tab>
        </v-tabs>
      </template>
    </v-app-bar>
    <v-sheet>
      <v-container style="height: 1000px"> </v-container>
    </v-sheet>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Making the background image of the app bar fade on scroll.

Hide on Scroll

We can hide the app bar when the user starts to scroll with the hide-on-scroll prop.

<template>
  <v-app>
    <v-app-bar app color="teal" dark hide-on-scroll>
      <v-app-bar-nav-icon> </v-app-bar-nav-icon>
      <v-app-bar-title>Title</v-app-bar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
      <v-menu left bottom>
        <template v-slot:activator="{ on, attrs }">
          <v-btn icon v-bind="attrs" v-on="on">
            <v-icon>mdi-dots-vertical</v-icon>
          </v-btn>
        </template>
      </v-menu>
    </v-app-bar>
    <v-sheet>
      <v-container style="height: 1000px"> </v-container>
    </v-sheet>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Making the app bar hide on scroll.

Inverted Scroll

When the inverted-scroll prop is set to true, the app bar will hide until the user scrolls past the designated threshold. Once past the threshold, the app bar will continue to display until the user scrolls up past the threshold. If the scroll-treshold prop is not set, a default value of 0 will be used.

<template>
  <v-app>
    <v-app-bar app color="primary" dark inverted-scroll>
      <v-app-bar-nav-icon> </v-app-bar-nav-icon>
      <v-app-bar-title>Coding Beauty</v-app-bar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
      <v-menu left bottom>
        <template v-slot:activator="{ on, attrs }">
          <v-btn icon v-bind="attrs" v-on="on">
            <v-icon>mdi-dots-vertical</v-icon>
          </v-btn>
        </template>
      </v-menu>
    </v-app-bar>
    <v-sheet>
      <v-container style="height: 1000px"> </v-container>
    </v-sheet>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting inverted scroll on an app bar.

Using an App Bar with a Navigation Drawer

We can add a navigation drawer to our user interface and use the functional v-nav-bar-icon component on the app bar to toggle its visibility.

<template>
  <v-app>
    <v-app-bar app color="green" dark>
      <v-app-bar-nav-icon @click="drawer = true"> </v-app-bar-nav-icon>
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
    </v-app-bar>
    <v-navigation-drawer v-model="drawer" absolute temporary>
      <v-list nav dense>
        <v-list-item-group
          v-model="group"
          active-class="deep-purple--text text--accent-4"
        >
          <v-list-item>
            <v-list-item-icon>
              <v-icon>mdi-home</v-icon>
            </v-list-item-icon>
            <v-list-item-title>Home</v-list-item-title>
          </v-list-item>

          <v-list-item>
            <v-list-item-icon>
              <v-icon>mdi-account</v-icon>
            </v-list-item-icon>
            <v-list-item-title>Account</v-list-item-title>
          </v-list-item>
        </v-list-item-group>
      </v-list>
    </v-navigation-drawer>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    drawer: false,
    group: null,
  }),
};
</script>
Using an app bar with a navigation drawer.

Conclusion

We can add an app bar to a user interface for quick and easy navigation. Vuetify provides the v-app-bar component for creating and customizing the behaviour and appearance of an app bar.

Vuetify Typography: How to Style Text with Vuetify

Every user interface contains some text. Different texts have different styles according to their purpose in the UI. Vuetify provides various classes that we can use to control various text properties such as size, alignment, wrapper, overflow and transforms. We’re going to learn about these typography helper classes in this article.

Font Size

Vuetify comes with classes for modifying the font size and style of a text. They are of the following formats:

  • .text-{value} for the xs breakpoint.
  • .text-{breakpoint}-{value} for the sm, md, lg and xl breakpoints.

The value can be any of the following:

  • h1
  • h2
  • h3
  • h4
  • h5
  • h6
  • subtitle-1
  • subtitle-2
  • body-1
  • body-2
  • button
  • caption
  • overline
<template>
  <v-app>
    <div class="ma-4">
      <div class="text-h1">Heading 1</div>
      <div class="text-h2">Heading 2</div>
      <div class="text-h3">Heading 3</div>
      <div class="text-h4">Heading 4</div>
      <div class="text-h5">Heading 5</div>
      <div class="text-subtitle-1">Subtitle 1</div>
      <div class="text-subtitle-2">Subtitle 2</div>
      <div class="text-body-1">Body 1</div>
      <div class="text-body-2">Body 2</div>
      <div class="text-button">Button</div>
      <div class="text-caption">Caption</div>
      <div class="text-overline">Overline</div>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Vuetify typography classes.

Font Emphasis

Vuetify also provides typography classes that control the font emphasis of the text. Material Design supports italicized text and font weights of 100, 300, 400, 500, 700 and 900.

<template>
  <v-app>
    <div class="ma-4">
      <div class="font-weight-black">Black text</div>
      <div class="font-weight-bold">Bold text</div>
      <div class="font-weight-medium">Medium weight text</div>
      <div class="font-weight-regular">Normal weight text</div>
      <div class="font-weight-light">Light weight text</div>
      <div class="font-weight-thin">Thin weight text</div>
      <div class="font-italic">Italic text</div>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Font emphasis.

Text Alignment

text-left, text-center, and text-right are typography classes used to set the alignment of text:

<template>
  <v-app>
    <div class="ma-4">
      <p class="text-left">Left aligned text on all viewport sizes.</p>
      <p class="text-center">Center aligned text on all viewport sizes.</p>
      <p class="text-right">Right aligned text on all viewport sizes.</p>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting text alignment.

Just like with font weights, Vuetify also comes with typography classes for targeting certain viewport width ranges. They include:

  • text-sm-{value}
  • text-md-{value}
  • text-lg-{value}
  • text-xl-{value}

value can be left, center or right.

Text Decoration

In addition, Vuetify has typography classes for adding text decorations. There are of the form text-decoration-{value}, where value can be none, overline, underline or line-through.

<template>
  <v-app>
    <div class="ma-4">
      <p class="text-decoration-overline">Overline text</p>
      <p class="text-decoration-underline">Underline text</p>
      <p class="text-decoration-line-through">Line-through text</p>
      <a href="#" class="text-decoration-none">Non-underlined link</a>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting text decoration.

Text Opacity

Opacity typography helper classes are another handy way of adjusting text emphasis with Vuetify. text--primary has the same opacity as default text, text--secondary is used for hints and helper text. De-emphasize text with text--disabled.

<template>
  <v-app>
    <div class="ma-4">
      <p class="text--primary">
        High-emphasis has an opacity of 87% in light theme and 100% in dark.
      </p>
      <p class="text--secondary">
        Medium-emphasis text and hint text have opacities of 60% in light theme
        and 70% in dark.
      </p>
      <p class="text--disabled">
        Disabled text has an opacity of 38% in light theme and 50% in dark.
      </p>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting text opacity.

Text Transform

We can transform text with Vuetify using the text capitalization typography classes. They are text-lowercase, text-uppercase, and text-capitalize.

<template>
  <v-app>
    <div class="ma-4">
      <p class="text-lowercase">Lowercased text</p>
      <p class="text-uppercase">Uppercased text</p>
      <p class="text-capitalize">CapiTaliZed text</p>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting text transform.

Wrapping and Overflow

The text-no-wrap typography class allows us to prevent text wrapping:

<template>
  <v-app>
    <div class="text-no-wrap blue ma-4" style="width: 8rem">
      This text should overflow the parent.
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Preventing text wrapping.

Summary

Typography is an important aspect of every user interface. Vuetify provides various helper classes to allow us easily modify text properties.