postcss-best-practices
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePostCSS Best Practices
PostCSS最佳实践
You are an expert in PostCSS, CSS processing pipelines, and modern CSS tooling.
您是PostCSS、CSS处理流程及现代CSS工具领域的专家。
Key Principles
核心原则
- Use PostCSS as a modular CSS processor with purpose-specific plugins
- Write future-proof CSS using modern syntax with appropriate transpilation
- Optimize CSS output for production with minification and autoprefixing
- Keep plugin configurations minimal and purposeful
- 将PostCSS作为模块化CSS处理器使用,搭配特定用途的插件
- 使用现代语法编写具有前瞻性的CSS,并配合适当的转译处理
- 通过压缩和自动添加前缀优化生产环境CSS输出
- 保持插件配置精简且目标明确
What is PostCSS
什么是PostCSS
PostCSS is a tool for transforming CSS with JavaScript plugins. Unlike preprocessors (Sass/Less), PostCSS:
- Is modular - add only the features you need
- Can parse and transform standard CSS
- Enables future CSS syntax today
- Optimizes and minifies output
- Works with any build tool
PostCSS是一个通过JavaScript插件转换CSS的工具。与预处理器(Sass/Less)不同,PostCSS:
- 模块化设计 - 仅添加您需要的功能
- 可以解析和转换标准CSS
- 让您现在就能使用未来的CSS语法
- 优化并压缩输出结果
- 可与任何构建工具配合使用
Project Setup
项目设置
Installation
安装
bash
undefinedbash
undefinedCore PostCSS
核心PostCSS
npm install postcss postcss-cli --save-dev
npm install postcss postcss-cli --save-dev
Common plugins
常用插件
npm install autoprefixer cssnano postcss-preset-env --save-dev
npm install autoprefixer cssnano postcss-preset-env --save-dev
Optional plugins
可选插件
npm install postcss-import postcss-nested postcss-custom-media --save-dev
undefinednpm install postcss-import postcss-nested postcss-custom-media --save-dev
undefinedConfiguration File
配置文件
javascript
// postcss.config.js
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-preset-env')({
stage: 2,
features: {
'nesting-rules': true,
'custom-media-queries': true,
'custom-properties': true,
},
}),
require('autoprefixer'),
require('cssnano')({
preset: ['default', {
discardComments: { removeAll: true },
}],
}),
],
};javascript
// postcss.config.js
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-preset-env')({
stage: 2,
features: {
'nesting-rules': true,
'custom-media-queries': true,
'custom-properties': true,
},
}),
require('autoprefixer'),
require('cssnano')({
preset: ['default', {
discardComments: { removeAll: true },
}],
}),
],
};Build Tool Integration
构建工具集成
Webpack
Webpack
javascript
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
'postcss-loader',
],
},
],
},
};javascript
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
'postcss-loader',
],
},
],
},
};Vite
Vite
javascript
// vite.config.js
import { defineConfig } from 'vite';
export default defineConfig({
css: {
postcss: './postcss.config.js',
},
});javascript
// vite.config.js
import { defineConfig } from 'vite';
export default defineConfig({
css: {
postcss: './postcss.config.js',
},
});Next.js
Next.js
javascript
// postcss.config.js (auto-detected)
module.exports = {
plugins: {
'postcss-import': {},
'tailwindcss/nesting': {},
tailwindcss: {},
autoprefixer: {},
},
};javascript
// postcss.config.js(自动识别)
module.exports = {
plugins: {
'postcss-import': {},
'tailwindcss/nesting': {},
tailwindcss: {},
autoprefixer: {},
},
};Essential Plugins
必备插件
postcss-preset-env
postcss-preset-env
Enables modern CSS features with polyfills:
javascript
// postcss.config.js
module.exports = {
plugins: [
require('postcss-preset-env')({
stage: 2, // Stage 2 features are stable
features: {
'nesting-rules': true,
'custom-media-queries': true,
'custom-selectors': true,
'gap-properties': true,
'logical-properties-and-values': true,
},
autoprefixer: { grid: true },
browsers: 'last 2 versions',
}),
],
};通过polyfill启用现代CSS特性:
javascript
// postcss.config.js
module.exports = {
plugins: [
require('postcss-preset-env')({
stage: 2, // Stage 2特性已稳定
features: {
'nesting-rules': true,
'custom-media-queries': true,
'custom-selectors': true,
'gap-properties': true,
'logical-properties-and-values': true,
},
autoprefixer: { grid: true },
browsers: 'last 2 versions',
}),
],
};autoprefixer
autoprefixer
Adds vendor prefixes automatically:
javascript
// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')({
grid: 'autoplace', // Enable grid prefixes
flexbox: true,
}),
],
};
// Input CSS
.element {
display: flex;
user-select: none;
}
// Output CSS
.element {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}自动添加浏览器厂商前缀:
javascript
// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')({
grid: 'autoplace', // 启用Grid前缀
flexbox: true,
}),
],
};
// 输入CSS
.element {
display: flex;
user-select: none;
}
// 输出CSS
.element {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}cssnano
cssnano
Minifies and optimizes CSS for production:
javascript
// postcss.config.js
const isProduction = process.env.NODE_ENV === 'production';
module.exports = {
plugins: [
require('autoprefixer'),
isProduction && require('cssnano')({
preset: ['default', {
discardComments: { removeAll: true },
normalizeWhitespace: true,
minifyFontValues: true,
minifyGradients: true,
reduceIdents: false, // Preserve animation names
mergeRules: true,
mergeLonghand: true,
}],
}),
].filter(Boolean),
};为生产环境压缩和优化CSS:
javascript
// postcss.config.js
const isProduction = process.env.NODE_ENV === 'production';
module.exports = {
plugins: [
require('autoprefixer'),
isProduction && require('cssnano')({
preset: ['default', {
discardComments: { removeAll: true },
normalizeWhitespace: true,
minifyFontValues: true,
minifyGradients: true,
reduceIdents: false, // 保留动画名称
mergeRules: true,
mergeLonghand: true,
}],
}),
].filter(Boolean),
};postcss-import
postcss-import
Inline @import statements:
javascript
// postcss.config.js
module.exports = {
plugins: [
require('postcss-import')({
path: ['src/styles'],
}),
],
};css
/* main.css */
@import 'variables.css';
@import 'base.css';
@import 'components/buttons.css';
@import 'components/cards.css';内联@import语句:
javascript
// postcss.config.js
module.exports = {
plugins: [
require('postcss-import')({
path: ['src/styles'],
}),
],
};css
/* main.css */
@import 'variables.css';
@import 'base.css';
@import 'components/buttons.css';
@import 'components/cards.css';postcss-nested
postcss-nested
Enables Sass-like nesting:
javascript
// postcss.config.js
module.exports = {
plugins: [
require('postcss-nested'),
],
};css
/* Input */
.card {
background: white;
&__header {
padding: 16px;
}
&__body {
padding: 16px;
}
&:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
@media (min-width: 768px) {
display: flex;
}
}
/* Output */
.card {
background: white;
}
.card__header {
padding: 16px;
}
.card__body {
padding: 16px;
}
.card:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
@media (min-width: 768px) {
.card {
display: flex;
}
}启用类Sass的嵌套语法:
javascript
// postcss.config.js
module.exports = {
plugins: [
require('postcss-nested'),
],
};css
/* 输入 */
.card {
background: white;
&__header {
padding: 16px;
}
&__body {
padding: 16px;
}
&:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
@media (min-width: 768px) {
display: flex;
}
}
/* 输出 */
.card {
background: white;
}
.card__header {
padding: 16px;
}
.card__body {
padding: 16px;
}
.card:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
@media (min-width: 768px) {
.card {
display: flex;
}
}Modern CSS Features
现代CSS特性
CSS Nesting (Native)
CSS嵌套(原生)
css
/* Modern browsers support native nesting */
.card {
background: white;
border-radius: 8px;
& .card-header {
padding: 1rem;
border-bottom: 1px solid #eee;
}
& .card-body {
padding: 1rem;
}
&:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
@media (min-width: 768px) {
display: flex;
}
}css
/* 现代浏览器支持原生嵌套 */
.card {
background: white;
border-radius: 8px;
& .card-header {
padding: 1rem;
border-bottom: 1px solid #eee;
}
& .card-body {
padding: 1rem;
}
&:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
@media (min-width: 768px) {
display: flex;
}
}Custom Properties (CSS Variables)
自定义属性(CSS变量)
css
:root {
/* Colors */
--color-primary: #3498db;
--color-primary-light: color-mix(in srgb, var(--color-primary), white 20%);
--color-primary-dark: color-mix(in srgb, var(--color-primary), black 20%);
--color-text: #333333;
--color-background: #ffffff;
--color-border: #e0e0e0;
/* Typography */
--font-family-base: 'Helvetica Neue', Arial, sans-serif;
--font-size-base: 1rem;
--line-height-base: 1.5;
/* Spacing */
--spacing-unit: 8px;
--spacing-sm: calc(var(--spacing-unit) * 1);
--spacing-md: calc(var(--spacing-unit) * 2);
--spacing-lg: calc(var(--spacing-unit) * 3);
--spacing-xl: calc(var(--spacing-unit) * 4);
/* Transitions */
--transition-base: 0.3s ease;
/* Shadows */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.button {
padding: var(--spacing-sm) var(--spacing-md);
background: var(--color-primary);
color: white;
transition: background var(--transition-base);
}
.button:hover {
background: var(--color-primary-dark);
}css
:root {
/* 颜色 */
--color-primary: #3498db;
--color-primary-light: color-mix(in srgb, var(--color-primary), white 20%);
--color-primary-dark: color-mix(in srgb, var(--color-primary), black 20%);
--color-text: #333333;
--color-background: #ffffff;
--color-border: #e0e0e0;
/* 排版 */
--font-family-base: 'Helvetica Neue', Arial, sans-serif;
--font-size-base: 1rem;
--line-height-base: 1.5;
/* 间距 */
--spacing-unit: 8px;
--spacing-sm: calc(var(--spacing-unit) * 1);
--spacing-md: calc(var(--spacing-unit) * 2);
--spacing-lg: calc(var(--spacing-unit) * 3);
--spacing-xl: calc(var(--spacing-unit) * 4);
/* 过渡 */
--transition-base: 0.3s ease;
/* 阴影 */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.button {
padding: var(--spacing-sm) var(--spacing-md);
background: var(--color-primary);
color: white;
transition: background var(--transition-base);
}
.button:hover {
background: var(--color-primary-dark);
}Custom Media Queries
自定义媒体查询
css
/* Define custom media queries */
@custom-media --viewport-sm (min-width: 576px);
@custom-media --viewport-md (min-width: 768px);
@custom-media --viewport-lg (min-width: 992px);
@custom-media --viewport-xl (min-width: 1200px);
@custom-media --motion-ok (prefers-reduced-motion: no-preference);
@custom-media --dark-mode (prefers-color-scheme: dark);
/* Usage */
.element {
width: 100%;
}
@media (--viewport-md) {
.element {
width: 50%;
}
}
@media (--viewport-lg) {
.element {
width: 33.333%;
}
}
@media (--motion-ok) {
.element {
transition: transform 0.3s ease;
}
}css
/* 定义自定义媒体查询 */
@custom-media --viewport-sm (min-width: 576px);
@custom-media --viewport-md (min-width: 768px);
@custom-media --viewport-lg (min-width: 992px);
@custom-media --viewport-xl (min-width: 1200px);
@custom-media --motion-ok (prefers-reduced-motion: no-preference);
@custom-media --dark-mode (prefers-color-scheme: dark);
/* 使用示例 */
.element {
width: 100%;
}
@media (--viewport-md) {
.element {
width: 50%;
}
}
@media (--viewport-lg) {
.element {
width: 33.333%;
}
}
@media (--motion-ok) {
.element {
transition: transform 0.3s ease;
}
}Custom Selectors
自定义选择器
css
/* Define reusable selectors */
@custom-selector :--heading h1, h2, h3, h4, h5, h6;
@custom-selector :--button button, [type="button"], [type="submit"];
@custom-selector :--enter :hover, :focus;
/* Usage */
:--heading {
font-family: var(--font-family-heading);
line-height: 1.2;
margin-bottom: 1rem;
}
:--button {
cursor: pointer;
font-family: inherit;
}
.link:--enter {
color: var(--color-primary);
text-decoration: underline;
}css
/* 定义可复用选择器 */
@custom-selector :--heading h1, h2, h3, h4, h5, h6;
@custom-selector :--button button, [type="button"], [type="submit"];
@custom-selector :--enter :hover, :focus;
/* 使用示例 */
:--heading {
font-family: var(--font-family-heading);
line-height: 1.2;
margin-bottom: 1rem;
}
:--button {
cursor: pointer;
font-family: inherit;
}
.link:--enter {
color: var(--color-primary);
text-decoration: underline;
}Logical Properties
逻辑属性
css
/* Use logical properties for internationalization */
.element {
/* Instead of margin-left/right */
margin-inline: auto;
/* Instead of padding-top/bottom */
padding-block: var(--spacing-md);
/* Instead of width/height */
inline-size: 100%;
block-size: auto;
/* Instead of border-left */
border-inline-start: 2px solid var(--color-primary);
/* Instead of text-align: left */
text-align: start;
}css
/* 使用逻辑属性适配国际化 */
.element {
/* 替代margin-left/right */
margin-inline: auto;
/* 替代padding-top/bottom */
padding-block: var(--spacing-md);
/* 替代width/height */
inline-size: 100%;
block-size: auto;
/* 替代border-left */
border-inline-start: 2px solid var(--color-primary);
/* 替代text-align: left */
text-align: start;
}Container Queries
容器查询
css
/* Modern container queries */
.card-container {
container-type: inline-size;
container-name: card;
}
.card {
display: block;
}
@container card (min-width: 400px) {
.card {
display: flex;
}
}
@container card (min-width: 600px) {
.card {
gap: 2rem;
}
}css
/* 现代容器查询 */
.card-container {
container-type: inline-size;
container-name: card;
}
.card {
display: block;
}
@container card (min-width: 400px) {
.card {
display: flex;
}
}
@container card (min-width: 600px) {
.card {
gap: 2rem;
}
}File Organization
文件组织
Structure
结构
src/
├── styles/
│ ├── base/
│ │ ├── reset.css
│ │ ├── typography.css
│ │ └── base.css
│ ├── components/
│ │ ├── buttons.css
│ │ ├── cards.css
│ │ ├── forms.css
│ │ └── navigation.css
│ ├── layout/
│ │ ├── header.css
│ │ ├── footer.css
│ │ └── grid.css
│ ├── utilities/
│ │ ├── spacing.css
│ │ ├── colors.css
│ │ └── display.css
│ ├── variables.css
│ └── main.css
├── postcss.config.js
└── package.jsonsrc/
├── styles/
│ ├── base/
│ │ ├── reset.css
│ │ ├── typography.css
│ │ └── base.css
│ ├── components/
│ │ ├── buttons.css
│ │ ├── cards.css
│ │ ├── forms.css
│ │ └── navigation.css
│ ├── layout/
│ │ ├── header.css
│ │ ├── footer.css
│ │ └── grid.css
│ ├── utilities/
│ │ ├── spacing.css
│ │ ├── colors.css
│ │ └── display.css
│ ├── variables.css
│ └── main.css
├── postcss.config.js
└── package.jsonMain Entry Point
主入口文件
css
/* main.css */
/* Variables first */
@import 'variables.css';
/* Reset and base styles */
@import 'base/reset.css';
@import 'base/typography.css';
@import 'base/base.css';
/* Layout */
@import 'layout/grid.css';
@import 'layout/header.css';
@import 'layout/footer.css';
/* Components */
@import 'components/buttons.css';
@import 'components/cards.css';
@import 'components/forms.css';
@import 'components/navigation.css';
/* Utilities (last for specificity) */
@import 'utilities/spacing.css';
@import 'utilities/colors.css';
@import 'utilities/display.css';css
/* main.css */
/* 先引入变量 */
@import 'variables.css';
/* 重置和基础样式 */
@import 'base/reset.css';
@import 'base/typography.css';
@import 'base/base.css';
/* 布局 */
@import 'layout/grid.css';
@import 'layout/header.css';
@import 'layout/footer.css';
/* 组件 */
@import 'components/buttons.css';
@import 'components/cards.css';
@import 'components/forms.css';
@import 'components/navigation.css';
/* 工具类(最后引入以保证优先级) */
@import 'utilities/spacing.css';
@import 'utilities/colors.css';
@import 'utilities/display.css';Production Configuration
生产环境配置
Environment-Based Config
基于环境的配置
javascript
// postcss.config.js
const isProduction = process.env.NODE_ENV === 'production';
module.exports = {
plugins: [
// Always run these
require('postcss-import'),
require('postcss-preset-env')({
stage: 2,
features: {
'nesting-rules': true,
'custom-media-queries': true,
},
}),
require('autoprefixer'),
// Production only
isProduction && require('cssnano')({
preset: ['default', {
discardComments: { removeAll: true },
reduceIdents: false,
zindex: false,
}],
}),
isProduction && require('@fullhuman/postcss-purgecss')({
content: [
'./src/**/*.html',
'./src/**/*.js',
'./src/**/*.jsx',
'./src/**/*.tsx',
],
safelist: {
standard: [/^is-/, /^has-/, /^js-/],
deep: [/modal/, /tooltip/],
},
}),
].filter(Boolean),
};javascript
// postcss.config.js
const isProduction = process.env.NODE_ENV === 'production';
module.exports = {
plugins: [
// 始终启用这些插件
require('postcss-import'),
require('postcss-preset-env')({
stage: 2,
features: {
'nesting-rules': true,
'custom-media-queries': true,
},
}),
require('autoprefixer'),
// 仅生产环境启用
isProduction && require('cssnano')({
preset: ['default', {
discardComments: { removeAll: true },
reduceIdents: false,
zindex: false,
}],
}),
isProduction && require('@fullhuman/postcss-purgecss')({
content: [
'./src/**/*.html',
'./src/**/*.js',
'./src/**/*.jsx',
'./src/**/*.tsx',
],
safelist: {
standard: [/^is-/, /^has-/, /^js-/],
deep: [/modal/, /tooltip/],
},
}),
].filter(Boolean),
};Browser Support
浏览器支持
javascript
// package.json
{
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
]
}
// Or .browserslistrc
> 1%
last 2 versions
not dead
not ie 11javascript
// package.json
{
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
]
}
// 或 .browserslistrc
> 1%
last 2 versions
not dead
not ie 11Useful Plugin Configurations
实用插件配置
postcss-custom-media
postcss-custom-media
javascript
require('postcss-custom-media')({
importFrom: [
{
customMedia: {
'--viewport-sm': '(min-width: 576px)',
'--viewport-md': '(min-width: 768px)',
'--viewport-lg': '(min-width: 992px)',
'--viewport-xl': '(min-width: 1200px)',
},
},
],
});javascript
require('postcss-custom-media')({
importFrom: [
{
customMedia: {
'--viewport-sm': '(min-width: 576px)',
'--viewport-md': '(min-width: 768px)',
'--viewport-lg': '(min-width: 992px)',
'--viewport-xl': '(min-width: 1200px)',
},
},
],
});postcss-mixins
postcss-mixins
javascript
require('postcss-mixins')({
mixins: {
'flex-center': {
display: 'flex',
'align-items': 'center',
'justify-content': 'center',
},
'visually-hidden': {
position: 'absolute',
width: '1px',
height: '1px',
overflow: 'hidden',
clip: 'rect(0, 0, 0, 0)',
},
},
});javascript
require('postcss-mixins')({
mixins: {
'flex-center': {
display: 'flex',
'align-items': 'center',
'justify-content': 'center',
},
'visually-hidden': {
position: 'absolute',
width: '1px',
height: '1px',
overflow: 'hidden',
clip: 'rect(0, 0, 0, 0)',
},
},
});postcss-simple-vars
postcss-simple-vars
javascript
require('postcss-simple-vars')({
variables: {
'color-primary': '#3498db',
'spacing-unit': '8px',
},
});javascript
require('postcss-simple-vars')({
variables: {
'color-primary': '#3498db',
'spacing-unit': '8px',
},
});Performance Tips
性能优化技巧
- Order plugins correctly: import, preset-env/nesting, autoprefixer, cssnano
- Use PurgeCSS to remove unused styles in production
- Enable source maps only in development
- Cache PostCSS results in build tools when possible
- Avoid unnecessary plugins - each adds processing time
- Use browserslist to target only necessary browsers
- 正确排序插件:import、preset-env/嵌套、autoprefixer、cssnano
- 在生产环境使用PurgeCSS移除未使用的样式
- 仅在开发环境启用Source Maps
- 尽可能在构建工具中缓存PostCSS结果
- 避免不必要的插件 - 每个插件都会增加处理时间
- 使用browserslist仅针对必要的浏览器
Common Plugin Combinations
常见插件组合
Minimal Setup
极简配置
javascript
module.exports = {
plugins: [
require('autoprefixer'),
require('cssnano'),
],
};javascript
module.exports = {
plugins: [
require('autoprefixer'),
require('cssnano'),
],
};Modern CSS Features
现代CSS特性配置
javascript
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-preset-env')({ stage: 2 }),
require('autoprefixer'),
require('cssnano'),
],
};javascript
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-preset-env')({ stage: 2 }),
require('autoprefixer'),
require('cssnano'),
],
};Sass-like Features
类Sass特性配置
javascript
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-mixins'),
require('postcss-simple-vars'),
require('postcss-nested'),
require('autoprefixer'),
require('cssnano'),
],
};javascript
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-mixins'),
require('postcss-simple-vars'),
require('postcss-nested'),
require('autoprefixer'),
require('cssnano'),
],
};With Tailwind CSS
搭配Tailwind CSS
javascript
module.exports = {
plugins: {
'postcss-import': {},
'tailwindcss/nesting': {},
tailwindcss: {},
autoprefixer: {},
...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {}),
},
};javascript
module.exports = {
plugins: {
'postcss-import': {},
'tailwindcss/nesting': {},
tailwindcss: {},
autoprefixer: {},
...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {}),
},
};Debugging
调试
Enable Source Maps
启用Source Maps
javascript
// postcss.config.js
module.exports = {
map: process.env.NODE_ENV !== 'production'
? { inline: false }
: false,
plugins: [
// ...plugins
],
};javascript
// postcss.config.js
module.exports = {
map: process.env.NODE_ENV !== 'production'
? { inline: false }
: false,
plugins: [
// ...插件
],
};Verbose Output
详细输出
bash
undefinedbash
undefinedCLI with verbose output
带详细输出的CLI命令
postcss src/main.css -o dist/main.css --verbose
undefinedpostcss src/main.css -o dist/main.css --verbose
undefinedCheck Plugin Order
检查插件顺序
If styles aren't working as expected:
- Check plugin order (import before others)
- Verify preset-env stage settings
- Check browserslist configuration
- Review cssnano options (may be over-optimizing)
如果样式未按预期工作:
- 检查插件顺序(import需在其他插件之前)
- 验证preset-env的stage设置
- 检查browserslist配置
- 查看cssnano选项(可能过度优化)