Responsive Design with SCSS Mixins in Nuxt.js

Learn how to use breakpoints in your Nuxt.js application to make it as responsive as water.

Responsive Design with SCSS Mixins in Nuxt.js

Responsive web design has become a cornerstone of modern web development, allowing websites to adapt seamlessly to various screen sizes and devices. While frameworks like Bootstrap offer robust solutions, customizing responsive behavior often demands more flexibility and control. In this tutorial, we'll explore how to leverage SCSS mixins within a Nuxt.js application to manage breakpoints effectively.

Understanding SCSS Mixins for Breakpoints

First, we're creating a new directory called "mixins" inside of the "assets/scss" directory and place a breakpoints.scss file in it:

assets/scss/mixins/breakpoints.scss
$breakpoints: (
  'xs': 576px,
  'sm': 768px,
  'md': 992px,
  'lg': 1200px,
  'xl': 1400px,
);

@mixin mq($width, $type: min) {
  @if map_has_key($breakpoints, $width) {
    $width: map_get($breakpoints, $width);
    @if $type == max {
      $width: $width - 0.02px;
    }
    @media only screen and (#{$type}-width: $width) {
      @content;
    }
  }
}

This mixin, named mq (short for Media Query), accepts two parameters: $width and $type. It checks if the provided width exists in the $breakpoints map and generates a media query accordingly. Additionally, it can handle both min-width and max-width scenarios, offering flexibility in responsive design implementation. By subtracting 0.02 pixel from the calculated width at max-width breakpoints, the mixin ensures that styles are applied up to, but not including, the exact specified width. This practice helps maintain clear and distinct boundaries between different breakpoint ranges, ensuring that styles transition smoothly across various viewport sizes without unintended side effects.

Using SCSS Mixins in Nuxt.js

In order to use the mq mixin within a Nuxt.js application, we'll need to add it to the nuxt.config.ts file:

nuxt.config.ts
export default defineNuxtConfig({
  css: ['@/assets/scss/main.scss'],
  devtools: { enabled: false },
  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: '@use "@/assets/scss/mixins/breakpoints.scss" as *;',
        },
      },
    },
  },
});

With the syntax @use "@/assets/scss/mixins/breakpoints.scss" as *; we can now use the mq mixin in our Nuxt.js application. The @use keyword is used to import SCSS files and the as * part means that all the styles and mixins from the imported file will be available in the current file without any namespace prefix. This makes it easier to use the mixin in other parts of the application.

Implementing Responsive Grid Layouts in Nuxt.js

Let's integrate this mixin within a Nuxt.js application to create a responsive grid layout. Consider the following example:

app.vue
<template>
  <div>
    <h1>Breakpoint Demo</h1>

    <div class="grid">
      <div><p>1</p></div>
      <div><p>2</p></div>
      <div><p>3</p></div>
      <div><p>4</p></div>
      <div><p>5</p></div>
    </div>
  </div>
</template>

<style scoped lang="scss">
  .grid {
    display: grid;
    grid-template-columns: auto;
    gap: 0.5rem;

    @include mq('xs') {
      grid-template-columns: 1fr;
    }
    @include mq('sm') {
      grid-template-columns: 1fr 1fr;
    }
    @include mq('md') {
      grid-template-columns: 1fr 1fr 1fr;
    }
    @include mq('lg') {
      grid-template-columns: 1fr 1fr 1fr 1fr;
    }
    @include mq('xl') {
      grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
    }
  }
</style>

In this example, we've defined a simple grid layout with five columns. By applying the mq mixin at various breakpoints, we adjust the number of columns dynamically, ensuring optimal display across different screen sizes.

Example

You can try out the mq mixin in the StackBlitz editor below. Change the size of the preview window to see the effect.

Conclusion

With the help of this mixin it is not necessary to write custom media queries for different breakpoints. The mq mixin takes care of this for you. Especially if you are using Nuxt.js it is easy to integrate the mq mixin into your application. It allows you to create responsive layouts with ease and having a consistent breakpoint approach.