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