在嵌套的flexbox

时间:2017-05-27 15:58:28

标签: css scroll modal-dialog flexbox

我正在开发一个React应用程序,该应用程序的模态内部有一些Tabbed内容,偶尔需要滚动。但问题是,我无法设法获取适当的滚动内容。

模态分为3个主要部分:

  1. 标题
    • 应始终在模态顶部显示
  2. 内容
    • 应填充标题页脚之间的空格,但不要强行从视图
  3. 页脚
    • 内容
    • 这可能意味着在模式的底部(如果内容填充剩余空间)或内容下面(如果内容 没有填补空间)
  4. 虽然这很容易实现(我已经这样做了),但问题出现在内容不应该滚动,而是里面它应该。在下面的图像中是两个预期行为的示例,一个具有长滚动内容,一个不滚动。

    我正在使用自定义选项卡式组件来呈现容器内的内容。如果需要,这个容器(下图中的白色)应该滚动。

    我可以在下面的CodePen和示例代码中找到最远的地方。我目前能够滚动包含预期可滚动内容的元素,但实际上无法滚动该内容。如果您检查笔,您可以看到它(由于某种原因)延伸超过包含元素。

    Modal Examples

    代码示例

    CodePen Example

    HTML

    <div class="modal">
      <div class="background" />
      <div class="modal_content">
        <div class="header">Random header</div>
        <div class="tabbed_content">
          <div class="tabs">
            <div class="tab active">Tab 1</div>
            <div class="tab">Tab 2</div>
          </div>
          <div class="content">
            <div class="scrollable">
              Tabbed Content
              <br /><br /><br /><br /><br /><br />
              Another Couple Lines
              <br /><br /><br /><br /><br /><br />
              More Tabbed Content
              <br /><br /><br /><br /><br /><br />
              Even More Content!
              <br /><br /><br /><br /><br /><br />
              Why not more yet!
              <br /><br /><br /><br /><br /><br />
              Some Ending Content
              <br /><br /><br /><br /><br /><br />
              Final Content!
            </div>
          </div>
        </div>
        <div class='footer'>
          <button class='button'>
            Done
          </button>
        </div>
      </div>
    </div>
    

    CSS

    body {
      font-family: 'Montserrat', sans-serif;
    }
    
    /* Modal wrapper */
    .modal {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
    }
    
    /* Modal background styles */
    .background {
      position: absolute;
      height: 100%;
      width: 100%;
      background-color: rgba(0, 0, 0, 0.5)
    }
    
    /* Modal content */
    .modal_content {
      height: 100vh;
      display: flex;
      flex-direction: column;
      width: 85%;
      margin: 0 auto;
      background-color: white;
    }
    
    .header {
      margin-bottom: 1rem;
      padding: 1rem;
      font-size: 125%;
      text-align: center;
      font-weight: bold;
      background-color: #EEEEEE;
      border-bottom: 1px solid #CECECE;
    }
    
    /* Contains the tabs and content */
    .tabbed_content {
      display: flex;
      flex-direction: column;
      align-items: stretch;
    }
    
    /* IGNORE */
    .tabs {
      display: flex;
      /* NOTE: Added to stop them from hiding */
      flex-shrink: 0;
    }
    
    /* IGNORE */
    .tab {
      flex-grow: 1;
      margin-top: 8px;
      padding: 0.5rem;
      text-align: center;
      background-color: #CECECE;
    }
    
    /* IGNORE */
    .tab.active {
      margin-top: 0;
      font-weight: bold;
      background-color: #EEEEEE;
    }
    
    /* Contains the current tab's content */
    /* NOTE: This shouldn't scroll */
    .content {
      padding: 1rem;
      background-color: #EEEEEE;
    
      /* NOTE: Currently the closest I can come */
      /*overflow: auto;*/
    }
    
    /* IMPORTANT: This should scroll if necessary! */
    .scrollable {
      padding: 0.5rem;
      background-color: white;
      /* NOTE: Can't get this to scroll */
      /*overflow: auto;*/
      border: 1px dashed #CECECE;
    }
    
    .footer {
      display: flex;
      flex-align: center;
      flex-shrink: 0;
      justify-content: center;
      margin-top: 1rem;
      padding: 1rem;
      border-top: 1px dashed #CECECE;
    }
    
    /* IGNORE */
    .button {
      padding: 0.75rem 1rem;
      font-size: 90%;
      color: white;
      background-color: lightseagreen;
      border: none;
      border-radius: 2px;
      cursor: pointer;
    }
    

    我几乎已经知道了这个(到目前为止花了2个小时搞乱)。在此先感谢您的帮助!

    P.S。我还需要担心在某个时刻打开模态时停止背景滚动...

3 个答案:

答案 0 :(得分:5)

一般来说,要使overflow: auto呈现垂直滚动条,您需要在容器上定义高度。

  

要使overflow生效,块级容器的设置高度(heightmax-height)或white-space必须设置为{{ 1}}。

     

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

然而,这并不总是一个实用的解决方案,尤其是在动态环境中。

在您的布局中,简单的解决方案是使容器(nowrap)成为灵活容器。这足以使布局在Chrome中运行(demo)。

但是,要使布局也适用于Firefox和Edge,您需要覆盖弹性项目的默认最小高度,即.content。这可以防止弹性项目缩小到其内容大小以下,从而消除min-height: auto发生的可能性。 (full explanation

对您的代码进行以下调整:

overflow

revised codepen

更多详情:Why doesn't flex item shrink past content size?

答案 1 :(得分:0)

这样的布局很棘手!我通常会尝试构建简化版本并进行处理。

你可以做的一种方法是使用可滚动div的位置绝对值。

https://codepen.io/sheriffderek/pen/zwQxLr/ - 请参阅此笔了解长短示例

<aside class="window">

    <header>header</header>

    <main>
        <div class="scroll-area">
            <ul>
                <li>short conent</li>
                <li>2</li>
                <li>3</li>
                <li>4</li>
                <li>5</li>
            </ul>
        </div>
    </main>

    <footer>footer</footer>

</aside>

CSS(这是手写笔 - 但它只是语法 - 而且概念应该是明确的)

.window
    border: 10px solid $gray;
    max-width: 600px // arbitrary
    height: 80vh // arbitrary

    display: flex
    flex-direction: column

    header, main, footer
        padding: $pad

    header
        background: $color

    main
        flex-grow: 1
        background: $alternate
        position: relative

        .scroll-area
            position: absolute
            top: 0
            left: 0
            width: 100%
            height: 100%
            overflow: auto
            padding: $pad

    footer
        background: $highlight

对于您的其他问题,您可以在打开模态并停止滚动时从正文中添加/删除类。

Prevent body scrolling but allow overlay scrolling

答案 2 :(得分:0)

你必须在.scrollable以及overflow-y: auto;设置一个高度,否则溢出是可见的,因为它没有高度溢出。