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添加自定义类名,再通过该类名定位内部元素:
- 修改Drawer组件:
<Drawer variant="permanent" open={open} className="custom-drawer">
- 修改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
相关产品推荐
相关产品推荐

