具有独立滚动列的材质 UI 网格

Posted

技术标签:

【中文标题】具有独立滚动列的材质 UI 网格【英文标题】:Material UI grid with independent scrolling columns 【发布时间】:2019-02-23 19:59:10 【问题描述】:

我希望在 React 中使用 Material UI 制作多个滚动列。我有一种在引导程序中使用 flex 的方法,但我无法将其翻译过来。我整理了一个 hacky 方式的演示,它需要知道您要滚动的内容上方的内容的大小(在本例中为 AppBar)

https://codesandbox.io/s/pmly895mm

html,
body 
  margin: 0;
  height: 100%;


#root 
  height: 100%;


.grid-container 
  height: calc(100% - 64px);


.grid-column 
  height: 100%;
  overflow-y: auto;

在这个演示中,我将所有高度设置为 100%(html、body、#root),然后创建了两个高度为 100% 的类 grid-container - AppBar 高度和高度为 100 的 grid-column % 和一个溢出的 auto。

在 Bootstrap 中,我会将这些类分别应用于 rowcolumn 元素

.flex-section 
  flex-grow: 1;

  display: flex;
  flex-direction: column;

  min-height: 0;


.flex-col-scroll 
  flex-grow: 1;

  overflow: auto;

  min-height: 100%;

元素上方的东西并不重要,因为 flex 负责高度。

具体来说,我希望避免使用height: calc(100% - 64px),因为这需要我事先知道元素高度。我将有一些页面,我想在滚动区域上方放置一些内容,这些内容将具有动态的高内容。

【问题讨论】:

要不要通过jss应用css? @SakhiMansoor 我知道如何将其翻译成 JSS,这不是问题所在。我正在寻找一种更动态的方式来实现这一点。我将有一些页面不仅仅是顶部的 AppBar,我宁愿不计算元素的高度(特别是如果它可以变化)。这就是我喜欢使用 flexbox 的原因。 我仍然不确定您真正关心的是什么。很抱歉误读。即使仅将 calc 替换为 100% 高度,您的代码也能正常工作 对不起,我不够清楚。当您删除计算并仅执行 100% 时,您最终会在底部得到一些额外的滚动。您被卡住向下滚动到列的底部,然后还有 64px 剩余,然后您可以再次滚动它并隐藏 AppBar codesandbox.io/s/kow9ww5kj5 【参考方案1】:

我发现使用 Material UI 的 Grids 确实很难做到这一点,因为正如对另一个答案的评论中所指出的那样,如果没有“flex-wrap: nowrap”并添加"flex-wrap: nowrap" 破坏了 Material UI 的网格布局系统。

不过,我确实发现,如果我使用 Material UI 的 Boxes 而不是 Grids,我可以相当轻松地重现 Josh Sherman 的 Layout with fixed header and independently scrolling columns。

在 index.html 中:

<style>
  body,
  html,
  #root 
    height: 100%;
  
</style>

#root 当然是由 create-react-app 创建的。

在 App.tsx 中:

import React from "react";
import  AppBar, Box, Toolbar  from "@material-ui/core";

function App() 
  return (
    <>
      <AppBar>
        <Toolbar />
      </AppBar>
      <Box flexDirection="column" display="flex" >
        <Toolbar />
        <Box flexGrow=1 display="flex" overflow="hidden">
          <Box overflow="auto">
             <!-- The contents of the left column go here -->
          </Box>
          <Box overflow="auto">
            <!-- The contents of the right column go here -->
          </Box>
        </Box>
      </Box>
    </>
  );


export default App;

【讨论】:

【参考方案2】:

2020 年更新

FWIW 我只是能够将这两个样式属性添加到 Box 组件以实现可滚动的 &lt;div&gt; 列:

<Box style=maxHeight: '100vh', overflow: 'auto'>...</Box>

【讨论】:

也适用于Grid 戴维斯谢谢你! @yogesnsamy 除非您将其垂直居中 xD【参考方案3】:

我决心重新创建过去在引导程序 (https://jsfiddle.net/aq9Laaew/226591/) 中的操作方式,我实际上也能够使其在 Material UI 中工作。而且由于我无法为这个特定用例(React / Material UI 可滚动列)在线找到任何类型的示例,希望这对其他人有帮助。

示例如下:https://codesandbox.io/s/z24wl3n58m

html,
body 
  margin: 0;
  height: 100%;


#root 
  height: 100%;
  display: flex;
  flex-direction: column;


.flex-section 
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;


.flex-col-scroll 
  flex-grow: 1;
  overflow: auto;
  min-height: 100%;


.flex-no-shrink 
  flex-shrink: 0;

我缺少的是在根上设置 flex。一旦我们这样做了,我们就可以使用flex-sectionflex-col-scrollflex-no-shrink(后者用于防止滚动上方的元素被压缩)

【讨论】:

感谢您分享您的解决方案。这对我帮助很大。对于 material-ui 1.5.1,我必须将 flex-wrap: nowrap 添加到 flex-section 类。我还需要删除flex-direction: column 谢谢。不过,我有一个问题……如果 h1 标签中的文本稍长一点,它似乎就会分崩离析。你能帮忙吗? 这帮助很大!非常感谢。【参考方案4】:

你只需要修复你的导航栏。它将保持完好无损。之后,为您添加一个填充grid container,它将包含您的所有内容。您甚至可以提供百分比填充以确保响应能力。

这里是工作代码框:Fixed Navbar

如果问题仍然存在,请告诉我。

【讨论】:

感谢您的回复。这是我正在努力实现的一个完美例子。但是,我认为将栏固定与静态不会有帮助。现在它是静态的,您必须为每个视图添加填充以消除重叠。继续,您在初始网格上方添加了一些文本。那太棒了。这也是我希望能够做到的。但是,如您所见,主视图和两列上现在还有另一个滚动条。这可以通过将height: calc(100% - 36px); 添加到.grid-container 来补偿新行的额外空间 但是,这让我回到了最初的问题,我不想计算/确定可滚动内容上方的内容高度;如果我能够像使用 flexbox 那样动态地做到这一点,那就太棒了。我将举一个例子来说明它在引导程序中是如何工作的。也许这会有所帮助。 我实际上认为我是在下定决心创建我的引导版本时想出来的(请参阅此处:jsfiddle.net/aq9Laaew/226591)

以上是关于具有独立滚动列的材质 UI 网格的主要内容,如果未能解决你的问题,请参考以下文章

过滤后如何在剑道 ui 网格上显示水平滚动条?

在材质网格中添加滚动条

如何在材质ui中为网格项添加新行?

React - 网格内的材质 UI 项目拒绝居中

material UI datagrid 垂直滚动条

锁定列的网格中的对齐问题