Cómo crear breakpoints CSS reactivos con Composition API

Aprende cómo hacer reactivos tus puntos de ruptura CSS para que puedas reaccionar cuando muten


¿Alguna vez has tenido que observar las dimensiones del viewport de forma programática? Es más común de lo que te puedas imaginar.

Con los años he probado distintas soluciones, usando window.matchMedia y observando el evento resize. Como puedes imaginarte y aunque puedes hacer throttling **del callback, este método no es el más elegante que digamos.

Si usas Vue.js existe una forma mucho más sencilla: usar la maravillosa librería de composables VueUse. Si no sabes qué es un composable, te invito a que lo descubras.

Uno de los muchos composables de VueUse es useBreakpoints. Imagino que ya sabes por dónde voy.

Viewport dinámico con useBreakpoints

¿Cómo configurar useBreakpoints para poder reaccionar de forma reactiva a los cambios del viewport?. Muy sencillo.

Primero debes establecer cuáles son los puntos de ruptura con los que trabajas. Luego, invocar el composable, pasándoselos:

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

    

Si usas un framework o colección de utilidades CSS que puntos de ruptura ya establecidos, como TailwindCSS, useBreakpoints viene con un helper para establecerlos:

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

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

    

A partir de aquí, breakpoints es un objeto que contiene métodos de ayuda. Vamos a ver los que creo te podrán ser más útiles, aunque la API es bastante autoexplicativa.

Cómo saber qué breakpoint está activo

Para saber —de entre todos los breakpoints que has definido a través de useBreakpoints— cuál es el breakpoint activo en un momento dado, puedes usar el método active, a través de breakpoints.active(). Esto devuelve una propiedad computada (ComputedRef) que puedes observar y actuar en consecuencia.

Es más, si creas clases CSS con los mismos identificadores que tus breakpoints, podrás establecer esas clases de forma dinámica.

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>

    

Saber si hay un breakpoint específico activo

El objeto breakpoints (generado con useBreakpoints) tiene más métodos útiles. Por ejemplo greaterOrEqual, greater, smallerOrEqual y smaller. Con ellos puedes crear expresiones de comparación para saber, teniendo en cuenta las medidas del viewport, si un breakpoint específico está activo, o no.

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

    

Estos métodos retornan una referencia reactiva (Ref), por lo que puedes reaccionar a sus mutaciones y establecer cualquier lógica que necesites.

Demo

Como siempre, aquí tienes una demo de todo lo que hemos hablado.

Juan Andrés Núñez
Juan Andrés Núñez
Ingeniero Frontend Senior. Especialista en Vue.js. Speaker. Docente profesional. Estoico.