ierdna
ierdna

Reputation: 6293

Change font size in Vuetify based on viewport?

I have a title:

<v-card-text style="font-size:5em">
    Some Heading Here
</v-card-text>

I would like to set font size to 3em when the view is XS. Right now I duplicated it as follows:

<v-card-text hidden-xs-only style="font-size:5em">
    Some Heading Here
</v-card-text>
<v-card-text visible-xs-only style="font-size:3em">
    Some Heading Here
</v-card-text>

However I would like to avoid this duplication and solve the issue with CSS alone, but without having to write my own @media queries in the local .vue file. Is that possible?

Alternatively, I'm ok with using predefined classes instead of specifying font size directly or even different elements completely, e.g. something like <h3> when it's XS but <h2> on other viewports.

Upvotes: 22

Views: 31624

Answers (5)

Debu Shinobi
Debu Shinobi

Reputation: 2582

In addition to Igor's answer.

You can also add multiple classes like

:class="{'subheading font-weight-black pt-2': $vuetify.breakpoint.xs}"

Upvotes: 0

MAW
MAW

Reputation: 973

Use breakpoint width value to check the viewport width and decide.

$vuetify.breakpoint.width

Upvotes: 0

CICSolutions
CICSolutions

Reputation: 1053

I too have been trying to solve this riddle, as it feels gross to reach into javascript to handle simple style changes for different device sizes.

As it turns out, generating custom css rules for different breakpoints is quite easy because Vuetify is leveraging Stylus and assigning the breakpoints to a Stylus variable. Naturally, this variable is available in your custom vue components and style files (provided you have the proper pre-processor setup to compile stylus).

Here are some resources that helped me understand things better:

  1. Pre-processor setup:

  2. Modifying Stylus Variables - Vuetify:

  3. Stylus @media queries - http://stylus-lang.com/docs/media.html

As you'll see, the $display-breakpoints Stylus Object is your new best friend!

Boil it all down, and here's what you get in a Vue single file component:

<template>
  <v-layout column justify-center align-center>
    <v-flex xs12 sm8 md6>
      <v-card>
        <v-card-title class="custom-selector headline">
          Welcome to the Vuetify + Nuxt.js template
        </v-card-title>
      </v-card>
    </v-flex>
  </v-layout>
</template>

<script>
export default {
  // ...
}
</script>

<style lang="styl">
.custom-selector
  font-size 3em
  @media $display-breakpoints.xs-only
    font-size 2em
  @media $display-breakpoints.lg-and-up
    font-size 5em
</style>

Notice in the code above, we are changing the font-size of the <v-card-title> component by targeting it in our Stylus media queries and using the $display-breakpoints object to identify the desired breakpoint.

I think the benefit of not having a UI framework that generates every option at every breakpoint is a much smaller file to load. It seems like Vuetify+Stylus is a lighter approach that makes writing custom @media queries the simplest and most efficient approach.

Upvotes: 13

raina77ow
raina77ow

Reputation: 106453

You can use Breakpoint object, provided and tracked by Vuetify itself. Quoting the docs:

Vuetify converts the available breakpoints into an accessible object from within your application. This will allow you to assign/apply specific properties and attributes based upon viewport size.

One possible (and rather direct way) is mentioned in the same docpage - using computed property to calculate font-size:

computed: {
  fontSize() {
    switch (this.$vuetify.breakpoint.name) {
      case 'xs': return '3em';
      default: return '5em';
    }
  }
}

... and use it in your template directly. Of course, you can do the same with dynamic class name instead - applied on $vuetify.breakpoint.xsOnly, for example.

Upvotes: 13

Igor Kokotko
Igor Kokotko

Reputation: 509

You can apply class based on viewport

:class="{'subheading': $vuetify.breakpoint.xs}"

Upvotes: 25

Related Questions