【问题标题】:Nested flexbox's overflow: scroll not working嵌套弹性框溢出:滚动不起作用
【发布时间】:2021-04-28 06:28:20
【问题描述】:

我正在尝试创建一个 3 列布局,其中一列在溢出时滚动。

我有一个工作原型here in this code sandbox

看起来像这样:

青色/青色是溢出滚动部分 - 最上面的父级填充在框架周围以灰色可见。

不起作用的部分 - 当我想将这个工作的 flexbox 嵌入/嵌套在另一个也包含标题的 flexbox 中时 - 但是当我这样做时,包含的滚动一个中断 - 整个 flexbox 溢出屏幕。

Codesandbox of version that doesn't work

截图:

我想我不明白关于 flexbox 大小的一些问题,因为我使用了不同的 height/flex 值并且无法解决这个问题。

我做错了什么?


附:我将Chakra-UI 用于组件+样式 - 但属性与普通 CSS 相同。我认为这对这个问题没有任何影响。标记更加简洁。

【问题讨论】:

    标签: html css flexbox overflow


    【解决方案1】:

    h="100%" 添加到父Flex 容器,从第一个子Flex 容器中删除h="100%" 并将minH="0" 添加到它会得到所需的结果。

    这里的问题是父级高度是无限的,这意味着子级可以占用尽可能多的空间,并且由于子级设置为flex-grow: 1,因此父级会重新排列以解决这个问题。

    import React from "react";
    import _ from "lodash";
    import {
      Flex,
      Box,
      Center,
      UnorderedList,
      ListItem,
      Heading
    } from "@chakra-ui/react";
    
    const Container = (props) => {
      const list = [];
      _.times(100, (i) => list.push(`Item ${i}`));
    
      return (
        <Flex id="container" flex={1} direction="column" h="100%">
          <Center id="header" h="75px" bg="yellow.300">
            <Heading>Flexbox Scroll Overflow Prototype</Heading>
          </Center>
          <Flex
            id="3-col-container"
            flex={1}
            bg="gray.100"
            p={4}
            minH="0"
            alignItems="stretch"
            gridColumnGap={2}
          >
            <Flex flex={1} bg="gray.50" direction="column" gridRowGap={2}>
              <Box minH="200px" bg="gray.500" />
              <Flex
                direction="column"
                pl={4}
                pt={2}
                flex={1}
                bg="teal.100"
                overflow="scroll"
              >
                <UnorderedList>
                  {list.map((item) => (
                    <ListItem mb={1} listStyleType="none" color="gray.700">
                      {item}
                    </ListItem>
                  ))}
                </UnorderedList>
              </Flex>
            </Flex>
            <Flex flex={1} bg="blue.100" />
            <Flex flex={1} bg="blue.200" />
          </Flex>
        </Flex>
      );
    };
    
    export default Container;
    

    【讨论】:

    • 嗯,我知道这行得通,但是min-height: 0 做了什么让它可以工作? min-height 不会默认为零吗?
    • min-height 的默认值取决于使用的布局模块。对于弹性项目,您可以参考此链接 -> w3.org/TR/css-flexbox-1/#min-size-auto 对于您的情况,所有弹性项目中的 min-height 都是基于内容的。
    【解决方案2】:

    解决方案

    将此添加到您的代码中:

    #container {
      height: calc(100vh - 75px);
    }
    
    #header {
      flex-shrink: 0;
    }
    

    说明

    列容器上的height: 100% 不起作用。

    这是因为它的父级没有定义高度,这是使用百分比值时height 定义所要求的。

    通过从百分比值切换,滚动功能起作用。

    通过减去标题的高度,可以防止不必要的溢出。

    #container {
       height: calc(100vh - 75px);
    }
    

    在某些浏览器中,尽管有calc 公式,但标题仍可能缩小(记住它存在于列方向的弹性容器中)。我猜这是因为渲染引擎在其他规则之前考虑了height: 100vh

    为避免跨浏览器出现这种情况,只需禁用 flex-shrink

    #header {
      flex-shrink: 0;
    }
    

    详细了解如何将 height 属性与百分比值结合使用。


    更多关于 overflow 属性的信息。

    一般来说,overflow 属性需要有一个固定的长度才能工作。

    这样想:使用动态长度,溢出是不可能的,因为元素只是收缩或扩展以满足需要。

    MDN 是这样说的:

    为了让overflow有效果,块级容器 必须具有设定的高度(heightmax-height)或 white-space 设置为 nowrap

    https://developer.mozilla.org/en-US/docs/Web/CSS/overflow

    【讨论】:

    • 感谢您的详细回答 - 我选择将另一个标记为已接受的解决方案,因为它更易于实施。
    猜你喜欢
    • 1970-01-01
    • 2014-06-17
    • 2017-02-11
    • 1970-01-01
    • 2014-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多