在嵌套的弹性框内滚动 [英] Scrolling inside nested flexboxes

查看:102
本文介绍了在嵌套的弹性框内滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个React应用程序,该应用程序具有一个模态,其中包含一些Tabbed内容,有时需要滚动.但是,问题是我无法设法获得正确的内容来滚动.

I'm working on a React app that has a modal with some Tabbed content inside that occasionally needs to scroll. However, the problem is that I can't manage to get the proper content to scroll.

模态分为三个主要部分:

The modal is broken into 3 main sections:

  1. 标题
    • 应该始终在模式顶部可见
  1. Header
    • Should always be visible at the top of the modal
  • 应该填充 Header (页眉)和 Footer (页脚)之间的空间,但切勿强行将其从视图中移除
  • Should fill space between Header and Footer but never force either from view
  • 应该始终在内容
  • 下方
  • 这可能意味着在模式的底部(如果 Content 填充剩余空间)或在 Content 的下方(如果 Content 不会填充空间)
  • Should always be visible underneath the Content
  • This may either mean at the bottom of the modal (if Content fill remaining space) or underneath the Content (if Content doesn't fill space)

虽然这很容易实现(并且我已经这样做了),但问题在于,内容不应该滚动,而是内部应该.下图是预期行为的两个示例,一个包含应滚动的较长内容,另一个不包含该内容.

While this would be simple to implement (and I have already done so), the problem arises in the fact that the Content isn't supposed to scroll, but rather something inside it should. In the images below are two example of the intended behaviour, one with long content that should scroll and one without.

我正在使用一个自定义的 Tabbed 组件,该组件可在容器内渲染某些内容.该容器(下图为白色)是必要时滚动的容器.

I am using a custom Tabbed component that renders something inside a container. This container (white in the images below) is what should scroll if necessary.

我所能找到的最远的代码可以在下面的CodePen和示例代码中找到.我目前可以滚动包含预期可滚动内容的元素,但实际上无法滚动该内容.如果您检查钢笔,您会发现它(出于某种原因)超出了包含元素的范围.

The furthest I have come can be found in the following CodePen and example code. I am currently able to scroll the element that contains intended scrollable content, but can't actually get that content to scroll. If you inspect the Pen you can see that it (for some reason) extends past the containing element.

CodePen示例

<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个小时弄乱了).预先感谢您的帮助!

I am nearly at my wits end with this (have spent 2 hours messing around so far). Thanks in advance for any help!

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

P.S. I also need to worry about stopping the background scroll while the modal is open at some point...

推荐答案

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

Generally speaking, for overflow: auto to render a vertical scrollbar, you need to define a height on the container.

为使overflow生效,块级容器必须具有设置的高度(heightmax-height)或white-space设置为nowrap.

In order for overflow to have an effect, the block-level container must have either a set height (height or max-height) or white-space set to nowrap.

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

但是,这并非总是可行的解决方案,尤其是在动态环境中.

However, this isn't always a practical solution, especially in dynamic environments.

在您的布局中,简单的解决方案是使容器(.content)成为flex容器.足以使布局在Chrome中正常工作(演示).

In your layout, the simple solution is to make the container (.content) a flex container. That's enough to make the layout work in Chrome (demo).

但是,要使布局在Firefox和Edge中也能使用,您需要覆盖弹性项目的默认最小高度,即min-height: auto.这样可以防止弹性项目收缩到其内容的大小以下,从而消除了overflow发生的可能性. (完整的说明)

However, for the layout to also work in Firefox and Edge, you need to override the default minimum height of flex items, which is min-height: auto. This prevents flex items from shrinking below the size of their content, which eliminates the possibility for an overflow to occur. (full explanation)

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

Make these adjustments to your code:

.tabbed_content {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  min-height: 0;                  /* NEW, esp for FF & Edge (see link below) */
}

.content {
  padding: 1rem;
  background-color: #EEEEEE;
  overflow: auto;                /* KEEP THIS, for FF & Edge (see link below) */
  display: flex;                 /* NEW */
  flex-direction: column;        /* NEW */
}

.scrollable {
  padding: 0.5rem;
  background-color: white;
  overflow: auto;               /* RESTORE */
  border: 1px dashed #CECECE;
}

修订后的代码笔

更多详细信息:为什么弹性商品不能超过内容尺寸?

这篇关于在嵌套的弹性框内滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆