Grid 网格布局组件 #

什么是 Grid? #

Grid 是一个基于 CSS Grid 的布局组件,它提供了强大的二维布局能力,适合构建复杂的页面布局。

jsx
import { Grid, GridItem } from '@chakra-ui/react'

function Example() {
  return (
    <Grid templateColumns="repeat(3, 1fr)" gap={6}>
      <GridItem>项目 1</GridItem>
      <GridItem>项目 2</GridItem>
      <GridItem>项目 3</GridItem>
    </Grid>
  )
}

基本用法 #

简单网格 #

jsx
<Grid templateColumns="repeat(3, 1fr)" gap={6}>
  <GridItem bg="blue.500" p={4}>1</GridItem>
  <GridItem bg="green.500" p={4}>2</GridItem>
  <GridItem bg="red.500" p={4}>3</GridItem>
</Grid>

固定宽度列 #

jsx
<Grid templateColumns="200px 1fr 200px" gap={4}>
  <GridItem bg="gray.200" p={4}>侧边栏</GridItem>
  <GridItem bg="gray.100" p={4}>主内容</GridItem>
  <GridItem bg="gray.200" p={4}>右侧栏</GridItem>
</Grid>

Grid 属性 #

templateColumns 列模板 #

jsx
<Grid templateColumns="repeat(2, 1fr)">
  两列等宽
</Grid>

<Grid templateColumns="repeat(4, 1fr)">
  四列等宽
</Grid>

<Grid templateColumns="1fr 2fr 1fr">
  中间列宽度是两侧的两倍
</Grid>

<Grid templateColumns="200px 1fr">
  固定宽度 + 自适应
</Grid>

templateRows 行模板 #

jsx
<Grid templateRows="100px 1fr 50px" h="300px">
  <GridItem>头部 100px</GridItem>
  <GridItem>内容区域</GridItem>
  <GridItem>底部 50px</GridItem>
</Grid>

gap 间距 #

jsx
<Grid gap={2}>间距 8px</Grid>
<Grid gap={4}>间距 16px</Grid>
<Grid gap={6}>间距 24px</Grid>
<Grid gap="20px">自定义间距</Grid>

<Grid rowGap={4} columnGap={8}>
  行间距 16px,列间距 32px
</Grid>

templateAreas 区域模板 #

jsx
<Grid
  h="300px"
  templateRows="auto 1fr auto"
  templateColumns="200px 1fr"
  templateAreas={`
    "header header"
    "nav main"
    "footer footer"
  `}
  gap={4}
>
  <GridItem area="header" bg="blue.500" p={4}>Header</GridItem>
  <GridItem area="nav" bg="green.500" p={4}>Nav</GridItem>
  <GridItem area="main" bg="gray.100" p={4}>Main</GridItem>
  <GridItem area="footer" bg="blue.500" p={4}>Footer</GridItem>
</Grid>

GridItem 属性 #

colSpan 列跨度 #

jsx
<Grid templateColumns="repeat(4, 1fr)" gap={4}>
  <GridItem colSpan={2} bg="blue.500" p={4}>跨 2 列</GridItem>
  <GridItem bg="green.500" p={4}>1</GridItem>
  <GridItem bg="red.500" p={4}>2</GridItem>
  <GridItem colSpan={3} bg="purple.500" p={4}>跨 3 列</GridItem>
  <GridItem bg="orange.500" p={4}>3</GridItem>
</Grid>

rowSpan 行跨度 #

jsx
<Grid templateColumns="repeat(3, 1fr)" templateRows="repeat(3, 100px)" gap={4}>
  <GridItem rowSpan={2} bg="blue.500" p={4}>跨 2 行</GridItem>
  <GridItem bg="green.500" p={4}>1</GridItem>
  <GridItem bg="red.500" p={4}>2</GridItem>
  <GridItem bg="purple.500" p={4}>3</GridItem>
  <GridItem bg="orange.500" p={4}>4</GridItem>
  <GridItem bg="pink.500" p={4}>5</GridItem>
</Grid>

指定位置 #

jsx
<Grid templateColumns="repeat(3, 1fr)" gap={4}>
  <GridItem colStart={2} bg="blue.500" p={4}>从第 2 列开始</GridItem>
  <GridItem colEnd={3} bg="green.500" p={4}>到第 3 列结束</GridItem>
  <GridItem rowStart={2} bg="red.500" p={4}>从第 2 行开始</GridItem>
</Grid>

响应式 Grid #

响应式列数 #

jsx
<Grid
  templateColumns={{
    base: '1fr',
    sm: 'repeat(2, 1fr)',
    md: 'repeat(3, 1fr)',
    lg: 'repeat(4, 1fr)',
  }}
  gap={6}
>
  {items.map((item) => (
    <GridItem key={item.id}>{item.content}</GridItem>
  ))}
</Grid>

使用 SimpleGrid #

Chakra UI 提供了更简单的 SimpleGrid 组件:

jsx
import { SimpleGrid } from '@chakra-ui/react'

<SimpleGrid columns={{ base: 1, md: 2, lg: 3 }} spacing={6}>
  <Box bg="blue.500" p={4}>项目 1</Box>
  <Box bg="green.500" p={4}>项目 2</Box>
  <Box bg="red.500" p={4}>项目 3</Box>
  <Box bg="purple.500" p={4}>项目 4</Box>
</SimpleGrid>

SimpleGrid 属性 #

jsx
<SimpleGrid
  columns={3}
  spacing={4}
  minChildWidth="200px"
>
  自动计算列数,最小宽度 200px
</SimpleGrid>

常用布局示例 #

仪表盘布局 #

jsx
<Grid
  h="100vh"
  templateRows="auto 1fr"
  templateColumns="250px 1fr"
  templateAreas={`
    "sidebar header"
    "sidebar main"
  `}
>
  <GridItem area="header" bg="white" shadow="sm" p={4}>
    Header
  </GridItem>
  <GridItem area="sidebar" bg="gray.800" color="white" p={4}>
    Sidebar
  </GridItem>
  <GridItem area="main" bg="gray.50" p={6}>
    Main Content
  </GridItem>
</Grid>

图片画廊 #

jsx
<Grid templateColumns="repeat(3, 1fr)" gap={4}>
  <GridItem rowSpan={2}>
    <Image src="large.jpg" alt="Large" objectFit="cover" h="100%" />
  </GridItem>
  <GridItem>
    <Image src="small1.jpg" alt="Small 1" objectFit="cover" h="100%" />
  </GridItem>
  <GridItem>
    <Image src="small2.jpg" alt="Small 2" objectFit="cover" h="100%" />
  </GridItem>
  <GridItem colSpan={2}>
    <Image src="wide.jpg" alt="Wide" objectFit="cover" h="100%" />
  </GridItem>
</Grid>

卡片网格 #

jsx
<SimpleGrid columns={{ base: 1, md: 2, lg: 3 }} spacing={6}>
  {products.map((product) => (
    <Card key={product.id}>
      <CardBody>
        <Image src={product.image} alt={product.name} />
        <Heading size="md" mt={4}>{product.name}</Heading>
        <Text color="gray.500">{product.description}</Text>
        <Button colorScheme="blue" mt={4}>购买</Button>
      </CardBody>
    </Card>
  ))}
</SimpleGrid>

表单布局 #

jsx
<Grid templateColumns="repeat(2, 1fr)" gap={4}>
  <FormControl>
    <FormLabel>姓名</FormLabel>
    <Input placeholder="请输入姓名" />
  </FormControl>
  <FormControl>
    <FormLabel>邮箱</FormLabel>
    <Input type="email" placeholder="请输入邮箱" />
  </FormControl>
  <FormControl colSpan={2}>
    <FormLabel>地址</FormLabel>
    <Input placeholder="请输入地址" />
  </FormControl>
  <FormControl colSpan={2}>
    <FormLabel>备注</FormLabel>
    <Textarea placeholder="请输入备注" />
  </FormControl>
</Grid>

统计卡片 #

jsx
<SimpleGrid columns={{ base: 1, md: 2, lg: 4 }} spacing={6}>
  <StatCard title="总收入" value="¥350,000" change="+23.36%" />
  <StatCard title="用户数" value="1,234" change="+12.05%" />
  <StatCard title="订单数" value="567" change="-5.23%" />
  <StatCard title="转化率" value="45.67%" change="+8.92%" />
</SimpleGrid>

自动布局 #

autoFlow #

jsx
<Grid
  autoFlow="row"
  autoColumns="100px"
  autoRows="100px"
  gap={4}
>
  <Box bg="blue.500">1</Box>
  <Box bg="green.500">2</Box>
  <Box bg="red.500">3</Box>
</Grid>

autoFill 和 autoFit #

jsx
<Grid
  templateColumns="repeat(auto-fill, minmax(200px, 1fr))"
  gap={4}
>
  自动填充,最小 200px
</Grid>

<Grid
  templateColumns="repeat(auto-fit, minmax(200px, 1fr))"
  gap={4}
>
  自动适应,最小 200px
</Grid>

对齐属性 #

justifyItems #

jsx
<Grid templateColumns="repeat(3, 100px)" justifyItems="center" gap={4}>
  <Box bg="blue.500" p={4}>1</Box>
  <Box bg="green.500" p={4}>2</Box>
  <Box bg="red.500" p={4}>3</Box>
</Grid>

alignItems #

jsx
<Grid templateColumns="repeat(3, 1fr)" alignItems="center" h="200px" gap={4}>
  <Box bg="blue.500" p={4}>1</Box>
  <Box bg="green.500" p={4}>2</Box>
  <Box bg="red.500" p={4}>3</Box>
</Grid>

justifyContent #

jsx
<Grid
  templateColumns="repeat(3, 100px)"
  justifyContent="space-between"
  gap={4}
>
  <Box bg="blue.500" p={4}>1</Box>
  <Box bg="green.500" p={4}>2</Box>
  <Box bg="red.500" p={4}>3</Box>
</Grid>

Grid 属性速查表 #

属性 CSS 属性 说明
templateColumns grid-template-columns 列模板
templateRows grid-template-rows 行模板
templateAreas grid-template-areas 区域模板
gap gap 间距
rowGap row-gap 行间距
columnGap column-gap 列间距
autoFlow grid-auto-flow 自动流向
autoColumns grid-auto-columns 自动列宽
autoRows grid-auto-rows 自动行高
justifyItems justify-items 水平对齐
alignItems align-items 垂直对齐
justifyContent justify-content 整体水平对齐
alignContent align-content 整体垂直对齐

GridItem 属性速查表 #

属性 CSS 属性 说明
colSpan grid-column 列跨度
rowSpan grid-row 行跨度
colStart grid-column-start 列起始
colEnd grid-column-end 列结束
rowStart grid-row-start 行起始
rowEnd grid-row-end 行结束
area grid-area 区域名称

下一步 #

现在你已经掌握了 Grid 组件,接下来学习 Container 容器,了解如何使用容器组件居中内容!

最后更新:2026-03-28