Vue 项目 CSS `fit-content` 在生产构建时错误优化导致的异常问题
背景
我的博饼网站在最开始的欢迎界面有一个按钮的高度适配出现了问题,想着改一下。
问题现象
这个按钮的CSS样式出现了如下问题:
- 本地开发 (
pnpm dev):样式正常,height: fit-content生效且未被划线。 - 生产环境 (GitHub Pages + Edge 浏览器):
.welcome_btn的height使用-moz-fit-content,且被划线失效;手动改为fit-content后正常。
排查过程
首先尝试确认了 Edge 版本(152.0.4191.66),排除浏览器兼容性问题; 之后通过查看 Edge 开发者工具下的 Network 面板,寻找到浏览器获取的css样式文件,对比源码与生产环境实际下发的 CSS 文件,发现构建产物中标准语法被删除。判断为生产构建阶段的 CSS 后处理(压缩/去重)Bug,而非浏览器或部署平台问题。
根因定位
由于 Vite 生产构建中 CSS 压缩器(cssnano) 的错误优化,导致出现了按钮样式错误的问题。具体而言,在生产构建时,Vite 的 CSS 压缩器(cssnano) 错误地将 fit-content 与 -moz-fit-content 视为重复声明,在去重优化时只保留了后写的 -moz-fit-content,而删除了前写的标准语法 fit-content。
源码:
.welcome_btn {
width: fit-content;
height: fit-content;
width: -moz-fit-content;
height: -moz-fit-content;
...
}构建产物:
.welcome_btn {
width: -moz-fit-content;
height: -moz-fit-content; /* 仅保留了此行,Edge(Chromium) 无法正常识别,导致相关样式配置失效 */
...
}解决方案:调整属性顺序
将标准语法置于 vendor prefix 之后,确保构建器"去重"后保留的是标准语法:
.welcome_btn {
width: -moz-fit-content;
height: -moz-fit-content;
width: fit-content; /* 标准语法放最后 */
height: fit-content;
...
}但是该解决方案可能会导致项目 无法兼容 2021 年之前的 Firefox。
有试过其他解决方案吗?
有的。我尝试了 更换了 CSS 压缩器,但是未生效。
具体而言:我尝试在 vite.config.ts 中修改配置。
//vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
...
build: {
...
cssMinify: 'lightningcss', // 改用 lightningcss 替代 cssnano
},
})尝试改用 lightningcss 替代 cssnano,但清除 dist 再重新构建后,问题依旧存在。
猜测可能是 Vite 版本对 lightningcss 支持有限,可能仍会使其回退到 esbuild/cssnano进行编译,又或者是由于 esbuild 同样存在类似的重复声明合并逻辑之类的。
结论
问题本质是由于 Vite 生产构建中 CSS 压缩器对需要做 fallback 的属性的错误去重。通过调整 fit-content 与 -moz-fit-content 的顺序,问题解决。
