How to create reactive CSS breakpoints with Composition API

Learn how to add reactivity to you own CSS breakpoints, so you can be notified (and react to it) when they mutate.


Have you ever had to check and react to viewport changes programmatically? It's more common than you might imagine.

Over the years, I've tried different solutions, like using window.matchMedia and observing the resize event. As you can imagine, even throttling the callback, this method isn't the elegant nor sustainable.

If you're using Vue.js, there's a much simpler way: using the wonderful VueUse composable library. If you're not familiar with what a composable is, you can learn it here.

One of the many VueUse composables is useBreakpoints.

Dynamic Viewport with useBreakpoints

How to set up useBreakpoints to reactively react to viewport changes? Very simple.

First, you need to establish the breakpoints you're working with. Then, invoke the composable, passing them:

TS
const breakpoints = useBreakpoints({
  mobile: 0,
  tablet: 640,
  laptop: 1024,
  desktop: 1280,
});

    

If you use a CSS framework or utility collection with pre-established breakpoints, like TailwindCSS, useBreakpoints comes with a helper to set them up:

TS
import { breakpointsTailwind, useBreakpoints } from '@vueuse/core'

const breakpoints = useBreakpoints(breakpointsTailwind)
const smAndLarger = breakpoints.greaterOrEqual('sm') // sm and larger
...

    

From here, breakpoints is an object that contains helper methods. Let's look at the ones I think will be most useful to you, although the API is quite self-explanatory.

How to Know Which Breakpoint is Active

To find out — among all the breakpoints you've defined through useBreakpoints — which one is active at any given moment, you can use the active method, through breakpoints.active(). This returns a computed property (ComputedRef) that you can observe and act upon accordingly.

Moreover, if you create CSS classes with the same identifiers as your breakpoints, you can set those classes dynamically. Handy.

Vue
<script>
    ...
  const activeBreakpoint = breakpoints.active(); // Returns a "normal" computed prop
</script>

<template>
  <blockquote :class="activeBreakpoint"> <!-- Dynamic style binding -->
    Current breakpoint: <strong>{{ activeBreakpoint }}</strong>
  </blockquote>
</template>

    

Knowing if a Specific Breakpoint is Active

The breakpoints object (generated with useBreakpoints) has more useful methods. For instance greaterOrEqual, greater, smallerOrEqual, and smaller. Armed with these, you can create comparison expressions to check, considering the viewport size, whether a specific breakpoint is active or not.

TS
const isDesktop = breakpoints.greater('laptop');
const isNotMobile = breakpoints.between('tablet', 'desktop');
const isMobile = breakpoints.smaller('tablet');

    

These methods return a reactive reference (Ref), so you can react to their changes and set any logic you need.

Demo

As always, here's a demo of everything we've discussed.

Juan Andrés Núñez
Juan Andrés Núñez
Senior Frontend Engineer. Vue.js specialist. Speaker. Professional teacher. Stoic.