You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React项目npm run build后MUI Drawer CSS样式不生效问题

问题:MUI Drawer样式本地正常,构建后不生效

我尝试覆盖MuiDrawer-paper的CSS样式,本地运行npm start时样式正常生效,但执行npm run build打包后样式未被应用。

本地应用效果:
本地应用效果

构建后应用效果:
构建后应用效果

想解决CSS在构建包中不生效的问题,让React应用在本地和构建包中的CSS样式保持一致。相关代码如下:


相关代码

Header.js

import * as React from 'react';
import { styled, useTheme } from '@mui/material/styles';
import Box from '@mui/material/Box';
import MuiDrawer from '@mui/material/Drawer';
import MuiAppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemButton from '@mui/material/ListItemButton';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import Tooltip from '@mui/material/Tooltip';
import HomeIcon from '@mui/icons-material/Home';
import LayersIcon from '@mui/icons-material/Layers';
import './Header.css';

const drawerWidth = 240;

const openedMixin = (theme) => ({
  width: drawerWidth,
  transition: theme.transitions.create('width', {
    easing: theme.transitions.easing.sharp,
    duration: theme.transitions.duration.enteringScreen,
  }),
  overflowX: 'hidden',
});

const closedMixin = (theme) => ({
  transition: theme.transitions.create('width', {
    easing: theme.transitions.easing.sharp,
    duration: theme.transitions.duration.leavingScreen,
  }),
  overflowX: 'hidden',
  width: `calc(${theme.spacing(7)} + 1px)`,
  [theme.breakpoints.up('sm')]: {
    width: `calc(${theme.spacing(8)} + 1px)`,
  },
});

const DrawerHeader = styled('div')(({ theme }) => ({
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'flex-end',
  padding: theme.spacing(0, 1),
  ...theme.mixins.toolbar,
}));

const AppBar = styled(MuiAppBar, {
  shouldForwardProp: (prop) => prop !== 'open',
})(({ theme, open }) => ({
  zIndex: theme.zIndex.drawer + 1,
  transition: theme.transitions.create(['width', 'margin'], {
    easing: theme.transitions.easing.sharp,
    duration: theme.transitions.duration.leavingScreen,
  }),
  ...(open && {
    marginLeft: drawerWidth,
    width: `calc(100% - ${drawerWidth}px)`,
    transition: theme.transitions.create(['width', 'margin'], {
      easing: theme.transitions.easing.sharp,
      duration: theme.transitions.duration.enteringScreen,
    }),
  }),
}));

const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open' })(
  ({ theme, open }) => ({
    width: drawerWidth,
    flexShrink: 0,
    whiteSpace: 'nowrap',
    boxSizing: 'border-box',
    ...(open && {
      ...openedMixin(theme),
      '& .MuiDrawer-paper': openedMixin(theme),
    }),
    ...(!open && {
      ...closedMixin(theme),
      '& .MuiDrawer-paper': closedMixin(theme),
    }),
  }),
);

export default function MiniDrawer() {
  const theme = useTheme();
  const [open, setOpen] = React.useState(false);

  const handleDrawerOpen = (index) => {
    console.log("index",index)
    setOpen(true);
  };

  const handleDrawerClose = () => {
    setOpen(false);
  };

  return (
    <Box sx={{ display: 'flex' }}>
      <AppBar position="fixed" color="default" >
        <Toolbar variant="dense"></Toolbar>
      </AppBar>
      <Drawer variant="permanent" open={open} 
       sx={{
        "& MuiPaper-root.css-12i7wg6-MuiPaper-root-MuiDrawer-paper": {
          position: "absolute !important",
          minHeight: "fit-content !important",
          top: "50px !important",
          outline: 0, 
          left: "10px !important", 
          width: "35px", 
          padding:" 35px !important", 
          background: "color-mix(in srgb, #D8D8D8, transparent 18%) !important"
        }
      }}
      >
        <List>
          {["Home", "Layers"].map((text, index) => (
            <ListItem key={text} disablePadding sx={{ display: "block" }}>
              <ListItemButton
                sx={{
                  minHeight: 48,
                  justifyContent: open ? 'initial' : 'center',
                  px: 2.5,
                }}
              >
                <ListItemIcon
                  sx={{
                    minWidth: 0,
                    mr: open ? 3 : 'auto',
                    justifyContent: 'center',
                  }}
                >
                  <Tooltip title="Home">
                    {index === 0 ? <HomeIcon />:null} 
                  </Tooltip>
                  <Tooltip title="Layers">
                    {index === 1 ? <LayersIcon />:null} 
                  </Tooltip>
                </ListItemIcon>
                <ListItemText primary={text} sx={{ opacity: open ? 1 : 0 }} />
              </ListItemButton>
            </ListItem>
          ))}
        </List>
      </Drawer>
    </Box>
  );
}

Header.css

.css-12i7wg6-MuiPaper-root-MuiDrawer-paper{
    position: absolute !important;
    top: 50px !important;
    outline: 0;
    left: 10px !important;
    max-width: 35px;
    padding-right: 35px !important;
    background:color-mix(in srgb, #D8D8D8, transparent 18%) !important;
}

App.js

import logo from './logo.svg';
import './App.css';
import Registration from './components/Registration';
import Header from './components/Header';
import Paper from '@mui/material/Paper';

function App() {
  return (
    <div className="App">
      <Header />
      <Paper className='footer'  sx={{ position: 'fixed', bottom: 0, left: 0, right: 0,backgroundColor:'rgba(217, 217, 217, 0.6)' }} elevation={3}>
      </Paper>
    </div>
  );
}

export default App;

App.css

.App {
  text-align: center;
}

.App-logo {
  height: 40vmin;
  pointer-events: none;
}

原因与解决方案

问题根源

你直接使用了MUI生成的动态哈希类名(比如css-12i7wg6-MuiPaper-root-MuiDrawer-paper)写样式,这类类名在生产构建时会被MUI重新哈希,导致构建后的类名和本地开发时不一致,样式无法匹配生效。

解决方法

不要依赖动态变化的哈希类名,改用以下可靠方式覆盖样式:

方法1:使用MUI的sx属性(推荐)

直接在Drawer组件的sx属性中,通过稳定的类名前缀& .MuiDrawer-paper定位目标元素:

<Drawer variant="permanent" open={open} 
 sx={{
  "& .MuiDrawer-paper": {
    position: "absolute !important",
    minHeight: "fit-content !important",
    top: "50px !important",
    outline: 0,
    left: "10px !important",
    width: "35px",
    padding:" 35px !important",
    background: "color-mix(in srgb, #D8D8D8, transparent 18%) !important"
  }
}}
>

方法2:全局CSS + 自定义类名

给Drawer添加自定义类名,再通过该类名定位内部元素:

  1. 修改Drawer组件:
<Drawer variant="permanent" open={open} className="custom-drawer">
  1. 修改Header.css:
.custom-drawer .MuiDrawer-paper{
    position: absolute !important;
    top: 50px !important;
    outline: 0;
    left: 10px !important;
    max-width: 35px;
    padding-right: 35px !important;
    background:color-mix(in srgb, #D8D8D8, transparent 18%) !important;
}

方法3:使用styled组件扩展

利用MUI的styled API,把自定义样式整合到Drawer的styled定义中:

const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open' })(
  ({ theme, open }) => ({
    width: drawerWidth,
    flexShrink: 0,
    whiteSpace: 'nowrap',
    boxSizing: 'border-box',
    ...(open && {
      ...openedMixin(theme),
      '& .MuiDrawer-paper': {
        ...openedMixin(theme),
        position: "absolute !important",
        minHeight: "fit-content !important",
        top: "50px !important",
        outline: 0,
        left: "10px !important",
        width: "35px",
        padding:" 35px !important",
        background: "color-mix(in srgb, #D8D8D8, transparent 18%) !important"
      },
    }),
    ...(!open && {
      ...closedMixin(theme),
      '& .MuiDrawer-paper': {
        ...closedMixin(theme),
        position: "absolute !important",
        minHeight: "fit-content !important",
        top: "50px !important",
        outline: 0,
        left: "10px !important",
        width: "35px",
        padding:" 35px !important",
        background: "color-mix(in srgb, #D8D8D8, transparent 18%) !important"
      },
    }),
  }),
);

以上方法均不依赖动态哈希类名,能确保本地和构建后的样式一致生效。

内容的提问来源于stack exchange,提问作者Suganya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 00:08:10