Skip to content

CSS Integration ​

The breakpoints you describe once for JavaScript can be written out for stylesheets as well, so the two never drift apart. The functions are plain and framework-agnostic, and the Nuxt module can generate the files for you.

ts
import { toMediaQueries, toScssModule, toCustomMedia, toTailwindScreens } from 'responsive-media'

const config = {
  mobile: [{ type: 'max-width', value: 600 }],
  tablet: [{ type: 'max-width', value: 960 }],
  desktop: [{ type: 'min-width', value: 961 }],
}

Media query strings ​

toMediaQueries(config)

Record<string, string>

Maps every key to its media query, the same string getMediaQueries() returns for an instance.

ts
toMediaQueries(config)
// { mobile: '(max-width: 600px)', tablet: '(max-width: 960px)', desktop: '(min-width: 961px)' }

SCSS ​

toScssModule(config, options?)

string

A ready SCSS module: a map of the queries and a mixin to use them.

scss
@use 'sass:map';

$queries: (
  'mobile': '(max-width: 600px)',
  'tablet': '(max-width: 960px)',
  'desktop': '(min-width: 961px)',
);

@mixin media($key) {
  @if not map.has-key($queries, $key) {
    @error 'Unknown breakpoint #{$key}';
  }
  @media #{map.get($queries, $key)} {
    @content;
  }
}
  • name — string · default: 'queries'. The name of the map.
  • mixin — string · default: 'media'. The name of the mixin.

Keys are always quoted, so a key such as 2xl is valid. An unknown key stops the compilation with an error instead of producing an empty @media.

toScssMap(config, options?) returns only the map, when you want to write your own mixin.

Write the module to a file once, then use it:

ts
import { writeFileSync } from 'node:fs'
writeFileSync('src/styles/_breakpoints.scss', toScssModule(config))
scss
@use 'breakpoints' as bp;

.sidebar {
  width: 280px;

  @include bp.media(mobile) {
    width: 100%;
  }
}

@custom-media ​

toCustomMedia(config, options?)

string

One @custom-media rule per key, for use with a PostCSS plugin such as postcss-custom-media. Browsers do not understand the rule on their own.

ts
toCustomMedia(config)
// @custom-media --mobile (max-width: 600px);
// @custom-media --tablet (max-width: 960px);
// @custom-media --desktop (min-width: 961px);
  • prefix — string · default: '--'. Put before every key.

Tailwind ​

toTailwindScreens(config)

Record<string, { raw: string }>

The screens of a Tailwind 3 configuration, with every breakpoint as a raw media query:

ts
// tailwind.config.ts
import { toTailwindScreens } from 'responsive-media'
import { breakpoints } from './breakpoints'

export default {
  theme: { screens: toTailwindScreens(breakpoints) },
}

In Nuxt ​

The module writes the SCSS module and the @custom-media file for you, from the same breakpoints it uses for the composables:

ts
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['responsive-media/nuxt'],
  responsive: {
    breakpoints: {
      mobile: [{ type: 'max-width', value: 600 }],
      desktop: [{ type: 'min-width', value: 601 }],
    },
    css: { scss: true, customMedia: true },
  },
})
  • css.scss writes .nuxt/responsive-media/queries.scss.
  • css.customMedia writes .nuxt/responsive-media/custom-media.css.
vue
<style lang="scss">
@use '#build/responsive-media/queries' as r;

.page {
  color: black;

  @include r.media(mobile) {
    color: red;
  }
}
</style>