Responsive Web Apps with Vuetify

Claus Straube
6 min readMay 11, 2020

--

VuetifyJs is a great Material Design Framework for VueJs. It comes with a ton of ready to use components. A “hidden champion” is the build in responsive system. This is not a component, but a declarative feature in some of its components. I’ll show you in this article how to create responsive text, forms, images and nearly everything — latter by using the breakpoint object. So if you want to create a web application that fits to every viewport sizes, VuetifyJs and of course this article is for you ;)

I assume that you’ve a running VueJs project with VuetifyJs, so I skip that project creation stuff. If you want to try this tutorial in a fresh setup, please read the Vuetify Quick Start tutorial. Another point: I’m using typescript (and I can recommend this). If you’re using Javascript things might be slightly different in your component, but this article we have nearly no coding, so this should no problem.

Breakpoints

Breakpoints in responsive web applications represents different view sizes. Obviously has a smart phone an other size than a tablet, or a notebook, or a normal PC monitor or a ultra wide screen. We as web developers should create applications, that work on every screen size — at least. I think it should work and look great on every screen size. To make this, the Material Design Spec gave breakpoints to us. One for each device type.

Material Design Viewport Breakpoints

The screenshot above shows the Material Design viewport breakpoints. This breakpoint system is heavily used by VuetifyJs. You can checkout the documentation for further information.

Responsive Text

Some of the responsive text features come with Vuetify 2.3.0. So the one or other early bird has to use the beta version.

So what is responsive text? The text size depends on the screen size. If you have a headline on a ultra wide display, a font size of 80px may look better than 20px. On the other side — a 80px headline can smash the whole design on a tiny mobile phone. So responsive text makes definitely sense. Of course you can do this with css and media queries. But in VuetifyJs this is a ready to use declarative feature.

Responsive text sample

The image above shows how a heading and even the text can change on the view size. In Vuetify you can get this behavior simply by declaring different classes on your textelement:

<template>
<v-row class="pa-3">
<h1
class="
text-h4 [1]
text-md-h2 [2]
text-lg-h1 [2]
text-xl-h1 [2]
text-truncate" [3]
>This is my heading</h1>
<p
class="
text--secondary
text-caption
text-sm-body-2
text-md-body-1
text-lg-body-1
text-xl-body-1
text-justify">
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut...
</p>
</v-row>
</template>
/// @/components/ResponsiveText.vue

You’ve always a default text size class [1] which also covers the smallest breakpoint (xs). The default can be overwritten by using breakpoint classes for each breakpoint [2] — if you want a different text size according to the default. The pattern is always text-[breakpoint]-[fontsize]. Especially in headings a great tool is text-truncate, which cuts off the text if it doesn’t fit in the outer element.

Responsive Forms

Another big issue in creating responsive web applications are forms. They should be arranged, depending on the view size. Here can the great grid system play out its strength. Of course the grid system is not only useful using forms, but it’s a common case for responsive web applications. So I used a forms sample — it works always the same, regardless what you want to put onto the screen.

The grid system with a form

The grid system consists of rows and columns. Every “virtual” row has 12 “virtual” columns, which gives a grid of an arbitrary number of rows with 12 columns each. There’re two elements in vuetify — v-row and v-column. It’s important to understand, that you can place v-row and v-column into the grid system, but they doesn’t have to be equal to the static n to 12 grid.

The fields in the image above are all named with R(ow)[number]C(olumn)[number]. So you can see, how the fields move, in the grid system, on changing the view size. We can have a look on the first form row (R1C1, R1C2, R1C3) to make things more clear. On big screens, the first row (which is equal to the v-row element) holds three fields in three v-col elements. The first v-col spreads over 6 virtual columns, the other two over 3 each. So they spread over 12 virtual columns in total.

Let’s have a look on the left bottom screenshot. Same form, lower view size. The first v-col element spreads over 12 virtual columns, the other two over 6 each. So the v-row element needs two rows à 12 virtual columns. The right bottom screenshot shows the same form in a very small view. The v-row needs here three virtual rows and each v-col spreads over 12 columns.

The question is — how can I get this behavior from VuetifyJs? Luckily this is the easy part. Simply as writing the number of virtual columns into the breakpoint attribute:

...
<v-row>
<v-col cols="12" md="6" lg="6" xl="6">
<v-text-field
label="Field R1C1"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3" lg="3" xl="3">
<v-text-field
label="Field R1C2"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3" lg="3" xl="3">
<v-text-field
label="Field R1C3"
></v-text-field>
</v-col>
</v-row>
...
/// @/components/ResponsiveForm.vue

There’s a breakpoint attribute for every Material Design breakpoint, except for xs. This one is covered by the default attribute cols. With the VuetifyJs grid system, you can create very powerful responsive layouts without any line of JavaScript code.

Responsive image size

The responsiveness of images comes from there ability to load the best image in size and quality for the device. For this the img element offers the scrset and sizes attributes. There’re tons of great articles out in the web, so I’m not going to write an other one. The message for the VuetifyJs users is: These two attributes are there in the v-img component as well. So you can use the standard responsive stuff with great features like lazy preload images or the contain attribute.

...
<v-img
src="http://catify.de/.../village_1264.jpg"
lazy-src="http://catify.de/.../village_blur.jpg"
srcset="http://catify.de/.../village_600.jpg 600w,
http://catify.de/.../village_960.jpg 960w,
http://catify.de/.../village_1264.jpg 1264w,
http://catify.de/.../village_1904.jpg 1904w,
http://catify.de/.../village_2400.jpg 2400w"
width="100%"
></v-img>
...
/// @/components/ResponsiveImage.vue

Responsive Type- or JavaScript

For every wish in responsiveness, that VuetifyJs not fulfills in a declarative way, they give a responsive breakpoint object to you. This can be used in computed properties, methods or nearly anywhere inside the VueJs context:

this.$vuetify.breakpoint 

It supports you with information about the current breakpoint, conditionals, dimensions etc. You can check out the documentation for more. In the sample I’ve used this object, to switch from many icons in the app bar to a burger icon, for opening a hidden menu. This is simply done in one line of code [1]:

<script lang="ts">
import Vue from 'vue'
import { Component } from "vue-property-decorator"
@Component
export default class ResponsiveActionIcons extends Vue {
get shrink() {
return this.$vuetify.breakpoint.smAndDown [1]
}
show() {
console.log("show menu...")
}
}
</script>
/// @/components/ResponsiveActionIcons.vue

The End

You can find the sources of my responsive VuetifyJs sample on a github repository. I hope you have enjoyed this article. Please leave a comment if you have any question or would like to give feedback.

--

--