You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何缩小MUI Flex布局中Grid组件的间距?

MUI表单布局优化:左右分栏排列字段并最小化间距

我正在用MUI构建表单,共有6个字段,想把其中3个放在左侧,另外3个放在右侧,且间距最小。

预期效果

预期效果示意图

当前效果

当前效果示意图

我试过用gap属性但没效果,可能是Flex布局用错了,以下是我的代码:

import styled from "@emotion/styled";
import {
  Box,
  Button,
  Container,
  CssBaseline,
  Grid,
  Link,
  TextField,
  Typography,
} from "@mui/material";
import React, { useState } from "react";
const Field = styled(TextField)`
  // Custom TextField to avoid styling repetitions
  width: 650px;
`;
const FieldName = styled(Typography)`
  // Custom Typography to avoid styling repetitions
  font-weight: 700;
`;

const asterisk = <span style={{ color: "red" }}>*</span>;

const MailThread = () => {
  const [formData, setFormData] = useState({
    threadName: "",
    from: "Qmeter or 2354",
    customerName: "",
    subject: "",
    dropdownOption: "QNP-102 Template",
    to: [],
    startSending: new Date(),
  });

  const {
    threadName,
    from,
    customerName,
    subject,
    dropdownOption,
    to,
    starSending,
  } = formData;

  const onChange = (e) => {
    setFormData((prevState) => ({
      ...prevState,
      [e.target.name]: e.target.value,
    }));
  };

  const onSubmit = (e) => {
    e.preventDefault();
  };

  return (
    <Container maxWidth={false} component="main">
      <CssBaseline />
     
        <Box component="form" noValidate onSubmit={onSubmit} sx={{ mt: 3, display:'flex' }}>
          <Grid  container spacing={2}>
            <Grid item xs={12}>
              <FieldName>Thread Name{asterisk}</FieldName>
              <Field
                name="threadName"
                required
                value={threadName}
                onChange={onChange}
              />
            </Grid>

            <Grid item xs={12}>
              <FieldName>From</FieldName>
              <Field
                sx={{
                  backgroundColor: "#f8f4f4",
                }}
                disabled
                value={from}
                name="from"
                onChange={onChange}
              />
            </Grid>
            <Grid item xs={12}>
              <FieldName>If Customer name is empty</FieldName>
              <Field onChange={onChange} />
            </Grid>
            <Grid item xs={12}>
              <FieldName>Subject</FieldName>
              <Field placeholder="Enter subject here" onChange={onChange} />
            </Grid>
            <Grid item xs={12}></Grid>
          </Grid>
          <Grid container spacing={2} sx={{marginLeft:'10px'}}>
            <Grid item xs={12}>
              <FieldName>Template</FieldName>
              <Field placeholder="Enter subject here" onChange={onChange} />
            </Grid>
          </Grid>
        </Box>
      
    </Container>
  );
};

export default MailThread;

解决方案

核心问题是Grid容器使用方式错误:你创建了两个独立Grid容器,导致它们仅横向排列而非真正的分栏布局。以下是修正后的实现方案:

关键调整点

  • 使用单个Grid容器,将其拆分为两个宽度各占一半的列(xs={6}),分别承载左右两组字段
  • 移除TextField固定宽度width: 650px,改用fullWidth属性让字段自适应列宽,避免布局溢出
  • 用Grid容器的spacing控制内部字段间距,gap属性控制左右栏的最小间距
  • 整理字段分组,确保左右各3个字段

修正后的完整代码

import styled from "@emotion/styled";
import {
  Box,
  Container,
  CssBaseline,
  Grid,
  TextField,
  Typography,
} from "@mui/material";
import React, { useState } from "react";

const Field = styled(TextField)`
  margin-bottom: 8px; // 控制字段与标签的间距
`;

const FieldName = styled(Typography)`
  font-weight: 700;
`;

const asterisk = <span style={{ color: "red" }}>*</span>;

const MailThread = () => {
  const [formData, setFormData] = useState({
    threadName: "",
    from: "Qmeter or 2354",
    customerName: "",
    subject: "",
    dropdownOption: "QNP-102 Template",
    to: [],
    startSending: new Date(),
  });

  const { threadName, from, customerName, subject, dropdownOption } = formData;

  const onChange = (e) => {
    setFormData((prevState) => ({
      ...prevState,
      [e.target.name]: e.target.value,
    }));
  };

  const onSubmit = (e) => {
    e.preventDefault();
  };

  return (
    <Container maxWidth={false} component="main">
      <CssBaseline />
      <Box component="form" noValidate onSubmit={onSubmit} sx={{ mt: 3 }}>
        {/* 单个Grid容器,分为两列并设置最小间距 */}
        <Grid container spacing={2} sx={{ gap: 1 }}>
          {/* 左侧列:3个字段 */}
          <Grid item xs={6}>
            <FieldName>Thread Name{asterisk}</FieldName>
            <Field
              name="threadName"
              required
              fullWidth
              value={threadName}
              onChange={onChange}
            />

            <FieldName>From</FieldName>
            <Field
              fullWidth
              sx={{ backgroundColor: "#f8f4f4" }}
              disabled
              value={from}
              name="from"
              onChange={onChange}
            />

            <FieldName>If Customer name is empty</FieldName>
            <Field fullWidth onChange={onChange} />
          </Grid>

          {/* 右侧列:3个字段 */}
          <Grid item xs={6}>
            <FieldName>Subject</FieldName>
            <Field
              fullWidth
              placeholder="Enter subject here"
              onChange={onChange}
            />

            <FieldName>Template</FieldName>
            <Field
              fullWidth
              placeholder="Enter template here"
              value={dropdownOption}
              name="dropdownOption"
              onChange={onChange}
            />

            <FieldName>To</FieldName>
            <Field fullWidth onChange={onChange} />
          </Grid>
        </Grid>
      </Box>
    </Container>
  );
};

export default MailThread;

额外说明

  • Grid container的sx={{ gap: 1 }}可直接控制左右两列的间距,替代手动设置marginLeft
  • fullWidth属性让TextField自动填充所在列宽度,避免固定宽度导致的布局溢出
  • 移除了多余的空Grid项,简化结构

内容的提问来源于stack exchange,提问作者Süleyman Eminbəyli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 10:28:13