具有独立滚动列的材质 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 中,我会将这些类分别应用于 row
和 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 负责高度。
具体来说,我希望避免使用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
组件以实现可滚动的 <div>
列:
<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-section
、flex-col-scroll
和flex-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 网格的主要内容,如果未能解决你的问题,请参考以下文章