如何自定义MUI Tabs面板样式?解决标签异常展开问题
问题描述
我正在为MUI提供的<Tabs组件>设置自定义样式,遇到以下问题:切换标签时,部分标签会出现异常“变大”的展开现象,该现象似乎与标签内容量相关。我尝试添加minWidth、maxWidth等样式属性调整,也移除过自行设置的部分样式,但均无法解决该问题。网上现有方案多使用已过时的makeStyles,我需要适配当前版本的替代方案。
原实现代码
import * as React from 'react'; import PropTypes from 'prop-types'; import Tabs from '@mui/material/Tabs'; import Tab from '@mui/material/Tab'; import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; import '../CSS/test.css' import '../App.css' import '../CSS/Work.css' function TabPanel(props) { const { children, value, index, ...other } = props; return ( <div role="tabpanel" hidden={value !== index} id={`vertical-tabpanel-${index}`} aria-labelledby={`vertical-tab-${index}`} {...other} > {value === index && ( <Box sx={{ p: 3 }}> <Typography>{children}</Typography> </Box> )} </div> ); } TabPanel.propTypes = { children: PropTypes.node, index: PropTypes.number.isRequired, value: PropTypes.number.isRequired, }; function a11yProps(index) { return { id: `vertical-tab-${index}`, 'aria-controls': `vertical-tabpanel-${index}`, }; } export default function VerticalTabs() { const [value, setValue] = React.useState(0); const handleChange = (event, newValue) => { setValue(newValue); }; return ( <Box sx={{ flexGrow: 1, bgcolor: '#222725', display: 'flex', height: 'fit-content', width: '100vh' }} > <Tabs TabIndicatorProps={{style: {background:'green'}}} // CHANGE INDICATOR COLOR HERE orientation="vertical" variant="scrollable" value={value} onChange={handleChange} aria-label="Vertical tabs example" centered sx={{ borderRight: 1, borderColor: 'divider', '.MuiTabPanel-root': { width: 2000, }, ".Mui-selected": { color: `green`, // CHANGE THE COLOR OF HIGHLIGHTED TAB HERE fontFamily: 'NTR, sans-serif', fontSize: '2vh', width: "50vh", }, '& .inactiveTab': {color: '#fff', fontFamily: 'NTR, sans-serif', fontSize: '2vh', width: 400} }} > <Tab label="CS 128" {...a11yProps(0)} className={value !== 0 ? 'inactiveTab' : ''} /> <Tab label="CS 173" {...a11yProps(1)} className={value !== 1 ? 'inactiveTab' : ''}/> <Tab label="IGL" {...a11yProps(2)} className={value !== 2 ? 'inactiveTab' : ''}/> </Tabs> <TabPanel value={value} index={0}> <div className='slide-tab'> <h1 className='job_title'>Course Assistant for CS 128 at UIUC</h1> <h3 className='job_date'>Fall 2022 - Present</h3> <ul className='tester_list'> <li className='job_desc'>Developed a grade management system with JavaScript that calculated class grades for the entire course</li> <li className='job_desc'>Helped to develop and draft the prompts for course material that explained foundational CS concepts</li> <li className='job_desc'>Hosted and coordinated multiple office hours every week</li> </ul> </div> </TabPanel> <TabPanel value={value} index={1}> <div className='slide-tab'> <h1 className='job_title'>Course Assistant for CS 173 at UIUC</h1> <h3 className='job_date'>Spring 2023 - Present</h3> <ul className='tester_list'> <li className='job_desc'>Created tutoring approach that best fit each students' learning style</li> <li className='job_desc'>Assess and troubleshoot conceptual misunderstandings brought by students</li> <li className='job_desc'>Led large gatherings of the class where new material was learned and practiced</li> <li className='job_desc'>Developed content that was used by the entire class</li> </ul> </div> </TabPanel> <TabPanel value={value} index={2}> <div className='slide-tab'> <h1 className='job_title'>Undergraduate Research Assistant @ IGL</h1> <h3 className='job_date'>Fall 2023</h3> <ul className='tester_list'> <li className='job_desc'>Working closely with Radu's Algorithm and its' application to combinatorics/number theory</li> <li className='job_desc'>Developing several solutions to various questions posed by this algorithm in Mathematica</li> <li className='job_desc'>Processing and computing new and efficient solutions to proofs that have existed on paper for some time</li> </ul> </div> </TabPanel> </Box> ); }
解决方案
问题根源是你给选中/未选中Tab设置了不同的宽度值(选中Tab设为50vh,未选中设为400px),切换时宽度突变导致“变大”现象。以下是基于MUI当前版本(使用sx prop)的修复方案:
修复后代码
import * as React from 'react'; import PropTypes from 'prop-types'; import Tabs from '@mui/material/Tabs'; import Tab from '@mui/material/Tab'; import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; import '../CSS/test.css' import '../App.css' import '../CSS/Work.css' function TabPanel(props) { const { children, value, index, ...other } = props; return ( <div role="tabpanel" hidden={value !== index} id={`vertical-tabpanel-${index}`} aria-labelledby={`vertical-tab-${index}`} {...other} > {value === index && ( <Box sx={{ p: 3 }}> <Typography>{children}</Typography> </Box> )} </div> ); } TabPanel.propTypes = { children: PropTypes.node, index: PropTypes.number.isRequired, value: PropTypes.number.isRequired, }; function a11yProps(index) { return { id: `vertical-tab-${index}`, 'aria-controls': `vertical-tabpanel-${index}`, }; } export default function VerticalTabs() { const [value, setValue] = React.useState(0); const handleChange = (event, newValue) => { setValue(newValue); }; return ( <Box sx={{ flexGrow: 1, bgcolor: '#222725', display: 'flex', height: 'fit-content', width: '100%' }} > <Tabs TabIndicatorProps={{ style: { background: 'green' } }} orientation="vertical" variant="scrollable" value={value} onChange={handleChange} aria-label="Vertical tabs example" centered sx={{ borderRight: 1, borderColor: 'divider', width: '50vh', // 固定Tabs容器宽度 '& .MuiTab-root': { width: '100%', // 所有Tab占满容器宽度 fontFamily: 'NTR, sans-serif', fontSize: '2vh', color: '#fff', // 默认未选中颜色 }, '& .Mui-selected': { color: 'green', // 选中状态颜色 } }} > <Tab label="CS 128" {...a11yProps(0)} /> <Tab label="CS 173" {...a11yProps(1)} /> <Tab label="IGL" {...a11yProps(2)} /> </Tabs> <Box sx={{ flexGrow: 1 }}> {/* 内容区域自动填充剩余空间 */} <TabPanel value={value} index={0}> <div className='slide-tab'> <h1 className='job_title'>Course Assistant for CS 128 at UIUC</h1> <h3 className='job_date'>Fall 2022 - Present</h3> <ul className='tester_list'> <li className='job_desc'>Developed a grade management system with JavaScript that calculated class grades for the entire course</li> <li className='job_desc'>Helped to develop and draft the prompts for course material that explained foundational CS concepts</li> <li className='job_desc'>Hosted and coordinated multiple office hours every week</li> </ul> </div> </TabPanel> <TabPanel value={value} index={1}> <div className='slide-tab'> <h1 className='job_title'>Course Assistant for CS 173 at UIUC</h1> <h3 className='job_date'>Spring 2023 - Present</h3> <ul className='tester_list'> <li className='job_desc'>Created tutoring approach that best fit each students' learning style</li> <li className='job_desc'>Assess and troubleshoot conceptual misunderstandings brought by students</li> <li className='job_desc'>Led large gatherings of the class where new material was learned and practiced</li> <li className='job_desc'>Developed content that was used by the entire class</li> </ul> </div> </TabPanel> <TabPanel value={value} index={2}> <div className='slide-tab'> <h1 className='job_title'>Undergraduate Research Assistant @ IGL</h1> <h3 className='job_date'>Fall 2023</h3> <ul className='tester_list'> <li className='job_desc'>Working closely with Radu's Algorithm and its' application to combinatorics/number theory</li> <li className='job_desc'>Developing several solutions to various questions posed by this algorithm in Mathematica</li> <li className='job_desc'>Processing and computing new and efficient solutions to proofs that have existed on paper for some time</li> </ul> </div> </TabPanel> </Box> </Box> ); }
关键修复点
- 统一Tab宽度:移除自定义
inactiveTab类,通过& .MuiTab-root让所有Tab宽度设为100%,选中/未选中状态仅修改颜色,避免尺寸突变 - 固定Tabs容器宽度:给Tabs设置
width: '50vh',防止被内容撑开导致布局混乱 - 优化内容布局:TabPanel外层用
Box sx={{ flexGrow: 1 }},让内容区域自动填充剩余空间,不挤压Tabs宽度 - 适配屏幕宽度:将外层Box的
width: '100vh'改为width: '100%',提升响应式表现
内容的提问来源于stack exchange,提问作者cushdog
相关产品推荐
相关产品推荐

