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

React组件中动态修改grid-template-rows的最优方案咨询

动态显示区块的布局适配方案

需求说明

React组件包含三个区块:

  • tools 和 searchPanel:固定高度,根据条件动态显示
  • mainContent:始终显示,需要占据容器剩余空间

初始组件结构:

<div className={`reference-container`}> 
    {isToolsVisible && <div className={`tools`}></div>}
    {isSearchPanelVisible && <div className={`searchPanel`}></div>}
    <div className={`mainContent`}></div>
</div>

初始SCSS尝试(存在问题:区块隐藏时Grid模板未动态调整):

.reference-container {
    $toolHeight: 100px;
    $serachPanelHeight: 50px;
    
    height: 100%;
    display: grid;
    grid-template-areas: 
      "tools"
      "serachPanel"
      "mainContent";
    grid-template-rows: $toolHeight $serachPanelHeight 1fr;
    
    .tools {
        grid-area: tools;
    }
    .searchPanel {
        grid-area: searchPanel;
    }
    .mainContent {
        grid-area: mainContent;
    }
} 

现有尝试(通过条件类修改Grid模板)

给父容器添加条件类,动态定义Grid规则:

<div className={`reference-container ${isToolsVisible ? 'with-tools' : ''} ${isSearchPanelVisible ? 'with-search-panel' : ''}`}>
  {isToolsVisible && <div className={`tools`}></div>}
  {isSearchPanelVisible && <div className={`searchPanel`}></div>}
  <div className={`mainContent`}></div>
</div>
.reference-container {
  $toolHeight: 100px;
  $searchPanelHeight: 50px;

  height: 100%;
  display: grid;
  grid-template-rows: 1fr;
  
  &.with-tools {
    grid-template-areas: 
      "tools"
      "mainContent";
    grid-template-rows: $toolHeight 1fr;
  }
  
  &.with-search-panel {
    grid-template-areas: 
      "searchPanel"
      "mainContent";
    grid-template-rows: $searchPanelHeight 1fr;
  }
  
  .tools {
    grid-area: tools;
  }
  
  .searchPanel {
    grid-area: searchPanel;
  }
  
  .mainContent {
    grid-area: mainContent;
  }
}

但这种方式需要维护多个条件类组合,扩展性差,寻求更优方案。


优化方案

方案1:使用Flexbox(推荐)

Flexbox天生适合这种垂直方向的剩余空间分配场景,无需处理动态模板,代码更简洁:

.reference-container {
  $toolHeight: 100px;
  $searchPanelHeight: 50px;

  height: 100%;
  display: flex;
  flex-direction: column; // 垂直排列子元素
  gap: 0; // 可根据需求设置区块间距

  .tools {
    height: $toolHeight;
    flex-shrink: 0; // 防止被压缩
  }

  .searchPanel {
    height: $searchPanelHeight;
    flex-shrink: 0; // 防止被压缩
  }

  .mainContent {
    flex: 1; // 占据剩余所有空间
    overflow: auto; // 内容超出时可滚动,按需添加
  }
}

原理:父容器设为垂直Flex布局,固定高度的子元素通过flex-shrink: 0保持高度,mainContent通过flex: 1自动填充剩余空间。无论tools/searchPanel是否显示,布局都会自动适配。

方案2:改进Grid布局(无需条件类)

如果坚持使用Grid,可以利用grid-template-rows的auto值自动适配动态区块:

.reference-container {
  $toolHeight: 100px;
  $searchPanelHeight: 50px;

  height: 100%;
  display: grid;
  grid-template-rows: auto auto 1fr; // 前两行自动适应内容高度,第三行占剩余空间
  gap: 0; // 按需设置间距

  .tools {
    height: $toolHeight;
  }

  .searchPanel {
    height: $searchPanelHeight;
  }

  .mainContent {
    // 无需额外设置grid-area,按默认顺序排列即可
  }
}

原理:auto轨道会根据是否存在对应子元素自动调整高度——如果子元素不存在,轨道高度会坍缩为0;如果存在,轨道高度由子元素的固定高度决定,最后一行的1fr始终占据剩余空间。


内容的提问来源于stack exchange,提问作者Георгий Барсегян

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 11:47:13