nextjs - ✅(Solved) Fix CSS Media Query Compilation Issue [1 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#90133Fetched 2026-04-08 00:20:42
View on GitHub
Comments
2
Participants
2
Timeline
7
Reactions
1
Author
Participants
Timeline (top)
referenced ×3commented ×1cross-referenced ×1issue_type_added ×1

Fix Action

Fix / Workaround

Media Query Ranges

As a temporary hotfix, we enabled the feature media-query-ranges in our repository. It compiles code with the usage of max-width.

PR fix notes

PR #90151: fix(css): normalize media query not-parentheses

Description (problem / solution / changelog)

Summary: This adds a small PostCSS plugin to normalize media queries where and not (...) loses outer parentheses during postprocessing. The plugin ensures expressions like (A) and not (B) become (A) and (not (B)).

Changes:

  • Add a small PostCSS plugin next-fix-media-not in packages/next/src/build/webpack/config/blocks/css/plugins.ts and include it in the default PostCSS plugin list.

Related: Closes #90133

Changed files

  • AGENTS.md (modified, +4/-4)
  • packages/next/src/build/webpack/config/blocks/css/plugins.ts (modified, +66/-0)

Code Example

npx create-next-app@16.1.5 nextjs-media-query-bug
cd nextjs-media-query-bug

---

yarn add @alma-oss/spirit-web@4.1.1

---

// postcss.config.mjs

export default {
  plugins: {
    autoprefixer: {
      flexbox: 'no-2009',
    },
  },
};

---

// app/globals.css

@import '@alma-oss/spirit-web/css/utilities.css';

---

// app/page.tsx

export default function Home() {
  return (
    <div className="d-only-tablet-none">
      This should be hidden on tablet (768px-1279px)
    </div>
  );
}

---

yarn build

---

@media (width >= 768px) and (width < 1280px) {}

---

@media (min-width: 768px) and not (min-width: 1280px) { ... }

---

@media (min-width: 768px) and (not (min-width: 1280px)) { ... }

---

// postcss.config.js

export default {
	plugins: {
		'postcss-preset-env': {
			features: {
				'media-query-ranges': true,
			},
		},
	},
};

---

@media (min-width: 768px) and (max-width: 1279.98px) { ... }

---

// postcss.config.json

{
  "plugins": {
    "postcss-preset-env": {
      "stage": false,
      "features": {
        "nesting-rules": true
      }
    },
  }
}

---

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.2.0: Tue Nov 18 21:09:45 PST 2025; root:xnu-12377.61.12~1/RELEASE_ARM64_T6030
  Available memory (MB): 36864
  Available CPU cores: 11
Binaries:
  Node: 22.16.0
  npm: 10.9.2
  Yarn: 4.12.0
  pnpm: N/A
Relevant Packages:
  next: 16.1.5
  eslint-config-next: 15.2.5
  react: 19.2.3
  react-dom: 19.2.3
  typescript: 5.9.3
Next.js Config:
  output: N/A
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

https://codesandbox.io/p/devbox/fragrant-sky-dkr6k9

To Reproduce

Prerequisites

  • Node.js 18+ and yarn installed
  • Spirit Design System package (@alma-oss/spirit-web) that uses modern CSS media query range syntax

Steps to reproduce

  1. Create a new Next.js 16.1.5 project
npx [email protected] nextjs-media-query-bug
cd nextjs-media-query-bug
  1. Install Spirit Design System
yarn add @alma-oss/[email protected]
  1. Create a minimal PostCSS config:
// postcss.config.mjs

export default {
  plugins: {
    autoprefixer: {
      flexbox: 'no-2009',
    },
  },
};
  1. Import Spirit CSS utilities:
// app/globals.css

@import '@alma-oss/spirit-web/css/utilities.css';
  1. Create a test page at:
// app/page.tsx

export default function Home() {
  return (
    <div className="d-only-tablet-none">
      This should be hidden on tablet (768px-1279px)
    </div>
  );
}
  1. Build the application
yarn build

Current vs. Expected behavior

IMO, Next.js 16.1.5 bundles postcss-preset-env v7.4.3 internally, which uses @csstools/postcss-media-minmax to transpile CSS Media Queries Level 4 range syntax. The bundled version has a bug where it drops the outer parentheses around not expressions when combined with and operators, violating the CSS Media Queries Level 4 specification.

The CSS code before postprocessing:

@media (width >= 768px) and (width < 1280px) { … }

Current behavior after postprocessing.

 @media (min-width: 768px) and not (min-width: 1280px) { ... }

Expected behavior after postprocessing.

 @media (min-width: 768px) and (not (min-width: 1280px)) { ... }

Alternative solutions

Media Query Ranges

As a temporary hotfix, we enabled the feature media-query-ranges in our repository. It compiles code with the usage of max-width.

// postcss.config.js

export default {
	plugins: {
		'postcss-preset-env': {
			features: {
				'media-query-ranges': true,
			},
		},
	},
};
@media (min-width: 768px) and (max-width: 1279.98px) { ... }

Nesting Rules

To achieve expected parentheses, it is possible to enable the feature nesting-rules. But it only works for stage: false, which disables every polyfill, and for these reasons, we consider it a less stable solution.

// postcss.config.json

{
  "plugins": {
    "postcss-preset-env": {
      "stage": false,
      "features": {
        "nesting-rules": true
      }
    },
  }
}

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.2.0: Tue Nov 18 21:09:45 PST 2025; root:xnu-12377.61.12~1/RELEASE_ARM64_T6030
  Available memory (MB): 36864
  Available CPU cores: 11
Binaries:
  Node: 22.16.0
  npm: 10.9.2
  Yarn: 4.12.0
  pnpm: N/A
Relevant Packages:
  next: 16.1.5
  eslint-config-next: 15.2.5
  react: 19.2.3
  react-dom: 19.2.3
  typescript: 5.9.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

CSS

Which stage(s) are affected? (Select all that apply)

next dev (local), next build (local), next start (local)

Additional context

extent analysis

Fix Plan

Update PostCSS Config

To fix the issue, we need to update the PostCSS config to use a version of postcss-preset-env that does not drop the outer parentheses around not expressions.

// postcss.config.mjs

export default {
  plugins: {
    autoprefixer: {
      flexbox: 'no-2009',
    },
    'postcss-preset-env': {
      features: {
        'media-query-ranges': true,
        'nesting-rules': true,
      },
      stage: 2,
    },
  },
};

Update Spirit Design System Package

We also need to update the Spirit Design System package to use a version that is compatible with the updated PostCSS config.

yarn add @alma-oss/spirit-web@latest

Update Next.js Project

Finally, we need to update the Next.js project to use the updated PostCSS config.

yarn build

Verification

To verify that the fix worked, we can check the generated CSS code to ensure that it matches the expected behavior.

@media (min-width: 768px) and (not (min-width: 1280px)) { ... }

Extra Tips

  • Make sure to update the Spirit Design System package to the latest version to ensure compatibility with the updated PostCSS config.
  • If you are using a version of Next.js that is not compatible with the updated PostCSS config, you may need to update to a newer version of Next.js.
  • If you are experiencing issues with the updated PostCSS config, you can try disabling the nesting-rules feature and using the media-query-ranges feature instead.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

nextjs - ✅(Solved) Fix CSS Media Query Compilation Issue [1 pull requests, 2 comments, 2 participants]