facebook / docusaurus

Easy to maintain open source documentation websites.
https://docusaurus.io
MIT License
55.56k stars 8.33k forks source link

Can't use CSS nesting in prod #9303

Open zt-9 opened 1 year ago

zt-9 commented 1 year ago

Have you read the Contributing Guidelines on issues?

Prerequisites

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

Self-service

zt-9 commented 1 year ago

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;

}
slorber commented 1 year ago

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"}

hrumhurum commented 11 months ago

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.

slorber commented 11 months ago

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

sekoyo commented 8 months ago

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.

slorber commented 4 months ago

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:

weareoutman commented 1 month ago

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.