---
title: "Breakpoint variables with pure CSS"
description: "Define and use responsive breakpoints as variables in pure CSS — no preprocessor or JS — for cleaner, DRY media queries. Works in plain stylesheets and slots straight into a Next.js app."
canonical: "https://asmyshlyaev177.dev/blog/breakpoints-variables-with-pure-css"
published: "May 1, 2025"
tags: ["CSS", "Next.js"]
---

# Breakpoint variables with pure CSS

> Define and use responsive breakpoints as variables in pure CSS — no preprocessor or JS — for cleaner, DRY media queries. Works in plain stylesheets and slots straight into a Next.js app.

---

In CSS can use variables most of the time.

```css
:root {
  --color-main: red;
}
```

But, can't use variables in [@media](https://developer.mozilla.org/en-US/docs/Web/CSS/@media) queries.

```css
@media;
```

Unexpected solution is to use [@container](https://developer.mozilla.org/en-US/docs/Web/CSS/@container) queries:

```css
:root {
  --is-tablet: true;

  @media (min-width: 1200px) {
    --is-tablet: false;
  }
}

... @container style(--is-tablet: false) {
  .content {
    grid-template-areas:
      "header aside"
      "feed   aside";
    grid-template-rows: minmax(7.16rem, 17.6rem) minmax(7.16rem, max-content);
    grid-template-columns: var(--feed-columns);
  }
}
```

Only downside is Firefox lacks support of it, but it doesn't do so well on many things.

## Next.js usage

In Next.js can use [postcss-custom-media](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-custom-media) plugin to achieve same outcome, for all browsers and with css modules.

How it looks like

```css
@custom-media --is-desktop (min-width: 1200px);

... @media (--is-desktop) {
  .content {
    grid-template-areas:
      "header aside"
      "feed   aside";
    grid-template-rows: minmax(7.16rem, 17.6rem) minmax(7.16rem, max-content);
    grid-template-columns: var(--feed-columns);
    gap: 1.75rem;
    width: 100%;
  }
}
```

### Setup

[Official](https://nextjs.org/docs/pages/guides/post-css) docs

1. Install all dependencies:
   `npm install --save-dev postcss autoprefixer postcss-flexbugs-fixes @csstools/postcss-global-data postcss-custom-media postcss-preset-env`

2. Add PostCSS config to `package.json`:

```json
  "postcss": {
    "plugins": [
      "postcss-flexbugs-fixes",
      [
        "@csstools/postcss-global-data",
        {
          "files": [
            // need to use file with global variables here
            "core/styles/vars.css"
          ]
        }
      ],
      "postcss-custom-media",
      [
        "postcss-preset-env",
        {
          "autoprefixer": {
            "flexbox": "no-2009"
          },
          "stage": 3,
          "features": {
            "custom-properties": false
          }
        }
      ]
    ]
  }
```

---

Author: Aleksandr Smyshliaev — <https://asmyshlyaev177.dev>
More posts: <https://asmyshlyaev177.dev/blog> · Site summary for LLMs: <https://asmyshlyaev177.dev/llms.txt>
