docusaurus
docusaurus copied to clipboard
Can't use CSS nesting in prod
Have you read the Contributing Guidelines on issues?
- [X] I have read the Contributing Guidelines on issues.
Prerequisites
- [X] I'm using the latest version of Docusaurus.
- [X] I have tried the
npm run clear
oryarn 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.
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;
}
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"}
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:
-
Install
postcss-preset-env
development package to your Docusaurus project:npm i postcss-preset-env --save-dev
-
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.
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
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.
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
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.