docusaurus icon indicating copy to clipboard operation
docusaurus copied to clipboard

Can't use CSS nesting in prod

Open zt-9 opened this issue 1 year ago • 7 comments

Have you read the Contributing Guidelines on issues?

Prerequisites

  • [X] I'm using the latest version of Docusaurus.
  • [X] I have tried the npm run clear or yarn clear command.
  • [X] I have tried rm -rf node_modules yarn.lock package-lock.json and re-installing packages.
  • [ ] I have tried creating a repro with https://new.docusaurus.io.
  • [x] I have read the console error message carefully (if applicable).

Description

My custom css for navbar

.navbar{
  position: sticky;
  width: fit-content;
  margin-left: 25px;
  margin-top: 25px;
  height: 48px;
  border-radius: 2px;
  @media screen and (max-width: 780px) {
		width: 100%;
    margin-left: 0px;
    margin-top: 0px;
	}
}

The media override for smaller screen works well on yarn start. but this information got lost after build. I checked the css file in build folder, it does not contain any @media related to max-width:780px either. My guess is those information got lost during build

Reproducible demo

No response

Steps to reproduce

put this in custom.css to override navbar style

.navbar{
  position: sticky;
  width: fit-content;
  margin-left: 25px;
  margin-top: 25px;
  height: 48px;
  border-radius: 2px;
  @media screen and (max-width: 780px) {
		width: 100%;
    margin-left: 0px;
    margin-top: 0px;
	}
}

Expected behavior

the margin for navbar should be 0 for screen smaller than 780px. however, it's still 25px. And I tried to uss 996px for the width, still doesn't work.

it works as expected under yarn start but not on yarn serve after build

Actual behavior

navbar margin is still 25px

Your environment

  • Public source code:
  • Public site URL:
  • Docusaurus version used: 2.4.1
  • Environment name and version : Node.js v20.2.0
  • Operating system and version (e.g. Ubuntu 20.04.2 LTS): Macos 13.5.1 (22G90)

Self-service

  • [ ] I'd be willing to fix this bug myself.

zt-9 avatar Sep 14 '23 07:09 zt-9

issue solved by changing css to this

@media (max-width: 768px) {
  .navbar {
    width: 100%;
    margin-left: 0px;
    margin-top: 0px;
  }

}

.navbar {
  position: sticky;
  width: fit-content;
  margin-left: 25px;
  margin-top: 25px;
  height: 48px;
  border-radius: 2px;

}

zt-9 avatar Sep 14 '23 18:09 zt-9

Will keep it open because it's a bug to me.

The new CSS nesting feature allows it, so our PostCSS processing CSS stack should allow it too: https://developer.chrome.com/articles/css-nesting/

CSS nesting is implemented in Chrome so that's probably why it works in dev.

It looks like the problem is related to the CSS minimizer, cf the prod warning emitted:

[WARNING] {"file":"assets/css/styles.e13d20fa.css","message":"assets/css/styles.e13d20fa.css from Css Minimizer plugin\nInvalid character(s) 'border:thick solid blue;margin-left:0;margin-top:0;width:100%' at assets/css/styles.e13d20fa.css:25:85915. Ignoring.","compilerPath":"client"}

slorber avatar Sep 15 '23 09:09 slorber

You can use postcss-preset-env PostCSS plugin to automatically transpile newer CSS syntax to an older syntax of the browsers targeted by your app.

To integrate it with Docusaurus 2.x, you can use the instructions below:

  1. Install postcss-preset-env development package to your Docusaurus project:

    npm i postcss-preset-env --save-dev

  2. In docusaurus.config.js file, add the following plugin function for PostCSS:

    // @ts-check
    
    /** @type {import('@docusaurus/types').Config} */
    const config = {
      // ...
      plugins: [
        customPostCssPlugin // PostCSS plugin function registration
      ]
    };
    
    /** @return {import('@docusaurus/types').Plugin} */
    function customPostCssPlugin() {
      return {
        name: "custom-postcss",
        configurePostCss(options) {
          // Append new PostCSS plugins here.
          options.plugins.push(require("postcss-preset-env")); // allow newest CSS syntax
          return options;
        }
      };
    }
    
    module.exports = config;
    
    

When postcss-preset-env PostCSS plugin is in place, your CSS gets automatically transpiled to an older syntax during the build, allowing you to use the newest CSS features without fears of possible incompatibilities.

In my humble opinion, Docusaurus should use the postcss-preset-env plugin for CSS by default to make a parity with JavaScript side of things which relies on the Babel transpiler. The latest JavaScript syntax + the latest syntax of CSS is kind of an expected combo for development, out of the box.

hrumhurum avatar Sep 25 '23 12:09 hrumhurum

Thanks, will think about it.

We used that preset before, but removed it in https://github.com/facebook/docusaurus/pull/4355 Perhaps we shouldn't have removed it 🤷‍♂️

CSS nesting support is not so great atm so it's not a big deal if we don't re-introduce it immediately, notably because you can use the configurePostCss lifecycle as a workaround: https://docusaurus.io/docs/api/plugin-methods/lifecycle-apis#configurePostCss

We'll also probably want to explore LightningCSS in the future

slorber avatar Sep 25 '23 13:09 slorber

Same issue, pretty confusing as the same code works during development and then breaks in prod even though I have the same browserlist for both.

I'd have expected it to either flatten it, or keep it. But not just remove it.

dominictobias avatar Jan 02 '24 22:01 dominictobias

Also reported here: https://github.com/facebook/docusaurus/issues/10113

Sandbox repro: https://stackblitz.com/edit/github-wa8upy?file=src%2Fpages%2Findex.js,src%2Fpages%2Findex.module.css

Note:

  • It doesn't work with: yarn build && yarn serve
  • It works with USE_SIMPLE_CSS_MINIFIER=true yarn build && yarn serve

slorber avatar May 09 '24 10:05 slorber

I encountered with an issue maybe related to this, lots of warnings are reported during build.

Parts of the log from https://github.com/easyops-cn/brick-docs/actions/runs/10244840918/job/28338673377:

Warning:  {"file":"assets/css/styles.74c286a5.css","message":"assets/css/styles.74c286a5.css from Css Minimizer plugin\nUnexpected '}' at assets/css/styles.74c286a5.css:37:85695.","compilerPath":"client"}
Warning:  {"file":"assets/css/styles.74c286a5.css","message":"assets/css/styles.74c286a5.css from Css Minimizer plugin\nInvalid property name '&>div{position' at assets/css/styles.74c286a5.css:37:13911. Ignoring.","compilerPath":"client"}
Warning:  {"file":"assets/css/styles.74c286a5.css","message":"assets/css/styles.74c286a5.css from Css Minimizer plugin\nInvalid property name '&.showAlways{opacity' at assets/css/styles.74c286a5.css:37:13980. Ignoring.","compilerPath":"client"}

But the build succeeded anyway, the output works on browsers which support css nesting.

By the way, the source code of these nesting rules seems to be from a third-party lib monaco-editor.

weareoutman avatar Aug 05 '24 08:08 weareoutman