如何在Material-UI AppBar中居中放置搜索组件并保持响应式
Material-UI AppBar搜索栏居中实现方案
你当前代码的问题在于标题组件设置了flexGrow: 1,会自动占据剩余空间,把搜索组件挤到AppBar最右侧。只需要调整Toolbar的flex布局结构,拆分为左、中、右三等分布局即可实现搜索栏居中,同时保留原有的响应式特性。
修改后的完整代码如下:
import { alpha, styled } from '@mui/material/styles'; import Box from '@mui/material/Box'; import AppBar from '@mui/material/AppBar'; import Toolbar from '@mui/material/Toolbar'; import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import InputBase from '@mui/material/InputBase'; import MenuIcon from '@mui/icons-material/Menu'; import SearchIcon from '@mui/icons-material/Search'; const Search = styled('div')(({ theme }) => ({ position: 'relative', borderRadius: theme.shape.borderRadius, backgroundColor: alpha(theme.palette.common.white, 0.15), '&:hover': { backgroundColor: alpha(theme.palette.common.white, 0.25), }, width: '100%', [theme.breakpoints.up('sm')]: { width: 'auto', }, })); const SearchIconWrapper = styled('div')(({ theme }) => ({ padding: theme.spacing(0, 2), height: '100%', position: 'absolute', pointerEvents: 'none', display: 'flex', alignItems: 'center', justifyContent: 'center', })); const StyledInputBase = styled(InputBase)(({ theme }) => ({ color: 'inherit', '& .MuiInputBase-input': { padding: theme.spacing(1, 1, 1, 0), paddingLeft: `calc(1em + ${theme.spacing(4)})`, transition: theme.transitions.create('width'), width: '100%', [theme.breakpoints.up('sm')]: { width: '12ch', '&:focus': { width: '20ch', }, }, }, })); export default function SearchAppBar() { return ( <Box sx={{ flexGrow: 1 }}> <AppBar position="static"> <Toolbar> {/* 左侧区域:占1份flex宽度,内容左对齐 */} <Box sx={{ flex: 1, display: 'flex', alignItems: 'center' }}> <IconButton size="large" edge="start" color="inherit" aria-label="open drawer" sx={{ mr: 2 }} > <MenuIcon /> </IconButton> <Typography variant="h6" noWrap component="div" sx={{ display: { xs: 'none', sm: 'block' } }} > MUI </Typography> </Box> {/* 中间区域:搜索栏,自然居中 */} <Search> <SearchIconWrapper> <SearchIcon /> </SearchIconWrapper> <StyledInputBase placeholder="Search…" inputProps={{ 'aria-label': 'search' }} /> </Search> {/* 右侧区域:占1份flex宽度,内容右对齐,无内容时仅做占位 */} <Box sx={{ flex: 1, display: 'flex', justifyContent: 'flex-end' }}> {/* 这里可以放右侧操作按钮,比如登录、购物车等,没有内容可以留空 */} </Box> </Toolbar> </AppBar> </Box> ); }
核心调整说明
- 把Toolbar内的元素拆分为左、中、右三个容器,左右容器都设置
flex: 1,保证两侧宽度均等,自动把中间的搜索栏挤到正中间位置 - 移除了原Typography上的
flexGrow: 1属性,避免标题占满剩余空间挤压搜索栏 - 保留了原搜索组件的所有响应式逻辑:小屏宽度100%,大屏默认12ch宽度、聚焦时扩展为20ch
- 右侧容器预留了扩展位置,如果后续需要添加右侧操作按钮,直接放在右侧Box内即可,不会影响搜索栏的居中效果
内容的提问来源于stack exchange,提问作者Forged
相关产品推荐
相关产品推荐

