Material-UI 布局组件 #
概述 #
MUI 提供了一套强大的布局组件,帮助你快速构建响应式页面布局。
text
布局组件体系
│
├── Box 通用容器(最常用)
├── Container 内容容器(限制宽度)
├── Grid 网格布局(12列系统)
├── Stack 堆叠布局(一维排列)
├── Divider 分隔线
└── Paper 纸张容器(带阴影)
Box 组件 #
Box 是最通用的容器组件,类似 HTML 的 <div>,但具有强大的样式功能。
基础用法 #
jsx
import { Box } from '@mui/material';
<Box>
这是一个 Box
</Box>
sx Prop 样式 #
jsx
<Box
sx={{
width: 100,
height: 100,
bgcolor: 'primary.main',
color: 'white',
p: 2,
m: 1,
borderRadius: 1,
}}
>
sx 样式
</Box>
系统属性 #
Box 支持所有系统属性,可以直接作为 props 使用:
jsx
<Box
width={100}
height={100}
bgcolor="primary.main"
color="white"
p={2}
m={1}
borderRadius={1}
>
系统属性
</Box>
常用系统属性 #
| 类别 | 属性 | 说明 |
|---|---|---|
| 间距 | m, mt, mr, mb, ml, mx, my | margin 系列 |
| 间距 | p, pt, pr, pb, pl, px, py | padding 系列 |
| 尺寸 | width, height, minWidth, maxWidth, minHeight, maxHeight | 尺寸控制 |
| 布局 | display, overflow, position, zIndex | 布局控制 |
| Flex | flex, flexDirection, justifyContent, alignItems, gap | Flex 布局 |
| 背景 | bgcolor, background, backgroundColor | 背景 |
| 边框 | border, borderRadius, borderColor | 边框 |
| 文字 | color, fontSize, fontWeight, textAlign | 文字样式 |
Flex 布局 #
jsx
<Box sx={{ display: 'flex', gap: 2 }}>
<Box sx={{ p: 2, bgcolor: 'primary.light' }}>项目 1</Box>
<Box sx={{ p: 2, bgcolor: 'primary.main' }}>项目 2</Box>
<Box sx={{ p: 2, bgcolor: 'primary.dark' }}>项目 3</Box>
</Box>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Box sx={{ p: 2, bgcolor: 'secondary.light' }}>项目 1</Box>
<Box sx={{ p: 2, bgcolor: 'secondary.main' }}>项目 2</Box>
</Box>
<Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: 200 }}>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>居中内容</Box>
</Box>
响应式属性 #
jsx
<Box
sx={{
width: {
xs: '100%',
sm: '80%',
md: '60%',
lg: '50%',
},
p: {
xs: 1,
sm: 2,
md: 3,
},
}}
>
响应式 Box
</Box>
嵌套选择器 #
jsx
<Box
sx={{
'& .child': {
p: 2,
bgcolor: 'primary.main',
color: 'white',
},
'& .child:hover': {
bgcolor: 'primary.dark',
},
}}
>
<div className="child">子元素 1</div>
<div className="child">子元素 2</div>
</Box>
Container 组件 #
Container 用于限制内容宽度,实现居中布局。
基础用法 #
jsx
import { Container } from '@mui/material';
<Container>
默认容器
</Container>
maxWidth 属性 #
jsx
<Container maxWidth="xs">
xs 容器 (444px)
</Container>
<Container maxWidth="sm">
sm 容器 (600px)
</Container>
<Container maxWidth="md">
md 容器 (900px)
</Container>
<Container maxWidth="lg">
lg 容器 (1200px)
</Container>
<Container maxWidth="xl">
xl 容器 (1536px)
</Container>
<Container maxWidth={false}>
全宽容器
</Container>
fixed 属性 #
jsx
<Container fixed>
固定宽度容器
</Container>
禁用内边距 #
jsx
<Container disableGutters>
无内边距容器
</Container>
完整示例 #
jsx
<Container maxWidth="lg" sx={{ mt: 4, mb: 4 }}>
<Typography variant="h4" gutterBottom>
页面标题
</Typography>
<Box sx={{ p: 2, bgcolor: 'grey.100' }}>
页面内容
</Box>
</Container>
Grid 组件 #
Grid 是一个强大的 12 列网格系统,用于构建复杂的响应式布局。
基础概念 #
text
Grid 系统
│
├── container 网格容器
└── item 网格项目
│
└── 列宽 (1-12)
xs, sm, md, lg, xl
基础用法 #
jsx
import { Grid } from '@mui/material';
<Grid container spacing={2}>
<Grid item xs={12} md={6}>
<Box sx={{ p: 2, bgcolor: 'primary.light' }}>左侧</Box>
</Grid>
<Grid item xs={12} md={6}>
<Box sx={{ p: 2, bgcolor: 'secondary.light' }}>右侧</Box>
</Grid>
</Grid>
列宽分配 #
jsx
<Grid container spacing={2}>
<Grid item xs={12}>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>12列 (100%)</Box>
</Grid>
<Grid item xs={6}>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>6列 (50%)</Box>
</Grid>
<Grid item xs={6}>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>6列 (50%)</Box>
</Grid>
<Grid item xs={4}>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>4列 (33.33%)</Box>
</Grid>
<Grid item xs={4}>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>4列 (33.33%)</Box>
</Grid>
<Grid item xs={4}>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>4列 (33.33%)</Box>
</Grid>
</Grid>
响应式布局 #
jsx
<Grid container spacing={2}>
<Grid item xs={12} sm={6} md={4} lg={3}>
<Box sx={{ p: 2, bgcolor: 'primary.light' }}>项目 1</Box>
</Grid>
<Grid item xs={12} sm={6} md={4} lg={3}>
<Box sx={{ p: 2, bgcolor: 'primary.light' }}>项目 2</Box>
</Grid>
<Grid item xs={12} sm={6} md={4} lg={3}>
<Box sx={{ p: 2, bgcolor: 'primary.light' }}>项目 3</Box>
</Grid>
<Grid item xs={12} sm={6} md={4} lg={3}>
<Box sx={{ p: 2, bgcolor: 'primary.light' }}>项目 4</Box>
</Grid>
</Grid>
spacing 间距 #
jsx
<Grid container spacing={2}>
{/* spacing={2} = 16px 间距 */}
</Grid>
<Grid container spacing={{ xs: 1, sm: 2, md: 3 }}>
{/* 响应式间距 */}
</Grid>
direction 方向 #
jsx
<Grid container direction="row" spacing={2}>
<Grid item xs={6}>横向排列</Grid>
<Grid item xs={6}>横向排列</Grid>
</Grid>
<Grid container direction="column" spacing={2}>
<Grid item xs={12}>纵向排列</Grid>
<Grid item xs={12}>纵向排列</Grid>
</Grid>
<Grid container direction="row-reverse" spacing={2}>
<Grid item xs={6}>反向排列</Grid>
<Grid item xs={6}>反向排列</Grid>
</Grid>
justifyContent 对齐 #
jsx
<Grid container justifyContent="flex-start">
<Grid item><Box sx={{ p: 2, bgcolor: 'grey.300' }}>左对齐</Box></Grid>
</Grid>
<Grid container justifyContent="center">
<Grid item><Box sx={{ p: 2, bgcolor: 'grey.300' }}>居中</Box></Grid>
</Grid>
<Grid container justifyContent="flex-end">
<Grid item><Box sx={{ p: 2, bgcolor: 'grey.300' }}>右对齐</Box></Grid>
</Grid>
<Grid container justifyContent="space-between">
<Grid item><Box sx={{ p: 2, bgcolor: 'grey.300' }}>两端</Box></Grid>
<Grid item><Box sx={{ p: 2, bgcolor: 'grey.300' }}>两端</Box></Grid>
</Grid>
<Grid container justifyContent="space-around">
<Grid item><Box sx={{ p: 2, bgcolor: 'grey.300' }}>环绕</Box></Grid>
<Grid item><Box sx={{ p: 2, bgcolor: 'grey.300' }}>环绕</Box></Grid>
</Grid>
<Grid container justifyContent="space-evenly">
<Grid item><Box sx={{ p: 2, bgcolor: 'grey.300' }}>均匀</Box></Grid>
<Grid item><Box sx={{ p: 2, bgcolor: 'grey.300' }}>均匀</Box></Grid>
</Grid>
alignItems 垂直对齐 #
jsx
<Grid container alignItems="flex-start" sx={{ height: 200 }}>
<Grid item><Box sx={{ p: 2, bgcolor: 'grey.300' }}>顶部</Box></Grid>
</Grid>
<Grid container alignItems="center" sx={{ height: 200 }}>
<Grid item><Box sx={{ p: 2, bgcolor: 'grey.300' }}>居中</Box></Grid>
</Grid>
<Grid container alignItems="flex-end" sx={{ height: 200 }}>
<Grid item><Box sx={{ p: 2, bgcolor: 'grey.300' }}>底部</Box></Grid>
</Grid>
嵌套网格 #
jsx
<Grid container spacing={2}>
<Grid item xs={12} md={8}>
<Box sx={{ p: 2, bgcolor: 'grey.200' }}>
<Typography>主内容区</Typography>
<Grid container spacing={1} sx={{ mt: 1 }}>
<Grid item xs={6}>
<Box sx={{ p: 1, bgcolor: 'grey.300' }}>嵌套 1</Box>
</Grid>
<Grid item xs={6}>
<Box sx={{ p: 1, bgcolor: 'grey.300' }}>嵌套 2</Box>
</Grid>
</Grid>
</Box>
</Grid>
<Grid item xs={12} md={4}>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>侧边栏</Box>
</Grid>
</Grid>
Grid v2(新版) #
MUI v5.6+ 提供了新的 Grid v2:
jsx
import { Grid2 as Grid } from '@mui/material';
<Grid container spacing={2}>
<Grid size={6}>
<Box sx={{ p: 2, bgcolor: 'primary.light' }}>项目 1</Box>
</Grid>
<Grid size={6}>
<Box sx={{ p: 2, bgcolor: 'primary.light' }}>项目 2</Box>
</Grid>
</Grid>
Stack 组件 #
Stack 用于一维布局,简化 flex 布局的编写。
基础用法 #
jsx
import { Stack } from '@mui/material';
<Stack spacing={2}>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>项目 1</Box>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>项目 2</Box>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>项目 3</Box>
</Stack>
direction 方向 #
jsx
<Stack direction="row" spacing={2}>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>横向</Box>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>横向</Box>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>横向</Box>
</Stack>
<Stack direction="column" spacing={2}>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>纵向</Box>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>纵向</Box>
</Stack>
<Stack direction="row-reverse" spacing={2}>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>反向</Box>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>反向</Box>
</Stack>
divider 分隔符 #
jsx
import { Stack, Divider } from '@mui/material';
<Stack
direction="row"
divider={<Divider orientation="vertical" flexItem />}
spacing={2}
>
<Box sx={{ p: 2 }}>项目 1</Box>
<Box sx={{ p: 2 }}>项目 2</Box>
<Box sx={{ p: 2 }}>项目 3</Box>
</Stack>
justifyContent 对齐 #
jsx
<Stack direction="row" justifyContent="space-between">
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>左</Box>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>右</Box>
</Stack>
<Stack direction="row" justifyContent="center">
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>居中</Box>
</Stack>
alignItems 对齐 #
jsx
<Stack direction="row" alignItems="center" spacing={2}>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>项目 1</Box>
<Box sx={{ p: 4, bgcolor: 'grey.300' }}>项目 2</Box>
<Box sx={{ p: 3, bgcolor: 'grey.300' }}>项目 3</Box>
</Stack>
useFlexGap #
jsx
<Stack direction="row" spacing={2} useFlexGap sx={{ flexWrap: 'wrap' }}>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>项目 1</Box>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>项目 2</Box>
<Box sx={{ p: 2, bgcolor: 'grey.300' }}>项目 3</Box>
</Stack>
Divider 组件 #
Divider 用于分隔内容。
基础用法 #
jsx
import { Divider } from '@mui/material';
<Box>
<Typography>上方内容</Typography>
<Divider />
<Typography>下方内容</Typography>
</Box>
带文字的分隔线 #
jsx
<Divider>或</Divider>
垂直分隔线 #
jsx
<Stack direction="row" alignItems="center" spacing={2}>
<Typography>左侧</Typography>
<Divider orientation="vertical" flexItem />
<Typography>右侧</Typography>
</Stack>
变体 #
jsx
<Divider variant="fullWidth" />
<Divider variant="inset" />
<Divider variant="middle" />
Paper 组件 #
Paper 提供带阴影的容器,模拟纸张效果。
基础用法 #
jsx
import { Paper } from '@mui/material';
<Paper sx={{ p: 2 }}>
这是一个 Paper
</Paper>
elevation 阴影级别 #
jsx
<Stack spacing={2} direction="row">
<Paper elevation={0} sx={{ p: 2 }}>elevation 0</Paper>
<Paper elevation={1} sx={{ p: 2 }}>elevation 1</Paper>
<Paper elevation={3} sx={{ p: 2 }}>elevation 3</Paper>
<Paper elevation={6} sx={{ p: 2 }}>elevation 6</Paper>
<Paper elevation={12} sx={{ p: 2 }}>elevation 12</Paper>
<Paper elevation={24} sx={{ p: 2 }}>elevation 24</Paper>
</Stack>
square 圆角 #
jsx
<Paper square sx={{ p: 2 }}>
无圆角 Paper
</Paper>
variant 变体 #
jsx
<Paper variant="elevation" sx={{ p: 2 }}>
带阴影
</Paper>
<Paper variant="outlined" sx={{ p: 2 }}>
带边框
</Paper>
布局实战示例 #
经典页面布局 #
jsx
import { Box, Container, AppBar, Toolbar, Typography, Drawer, Grid } from '@mui/material';
const drawerWidth = 240;
function PageLayout() {
return (
<Box sx={{ display: 'flex' }}>
<AppBar position="fixed" sx={{ zIndex: 1201 }}>
<Toolbar>
<Typography variant="h6">应用标题</Typography>
</Toolbar>
</AppBar>
<Drawer
variant="permanent"
sx={{
width: drawerWidth,
flexShrink: 0,
'& .MuiDrawer-paper': { width: drawerWidth, boxSizing: 'border-box' },
}}
>
<Toolbar />
<Box sx={{ overflow: 'auto', p: 2 }}>
侧边栏内容
</Box>
</Drawer>
<Box component="main" sx={{ flexGrow: 1, p: 3 }}>
<Toolbar />
<Container maxWidth="lg">
<Grid container spacing={3}>
<Grid item xs={12} md={8}>
<Paper sx={{ p: 2 }}>主内容</Paper>
</Grid>
<Grid item xs={12} md={4}>
<Paper sx={{ p: 2 }}>侧边栏</Paper>
</Grid>
</Grid>
</Container>
</Box>
</Box>
);
}
卡片网格布局 #
jsx
function CardGrid() {
const items = Array.from({ length: 6 }, (_, i) => i + 1);
return (
<Container maxWidth="lg" sx={{ py: 4 }}>
<Grid container spacing={4}>
{items.map((item) => (
<Grid item key={item} xs={12} sm={6} md={4}>
<Paper sx={{ p: 2, height: '100%' }}>
<Typography variant="h6">卡片 {item}</Typography>
<Typography variant="body2" color="text.secondary">
这是卡片 {item} 的描述内容
</Typography>
</Paper>
</Grid>
))}
</Grid>
</Container>
);
}
下一步 #
继续学习 输入组件,了解按钮、表单等交互组件!
最后更新:2026-03-28