【问题标题】:Nested flexbox with scrolling area带有滚动区域的嵌套弹性框
【发布时间】:2021-09-20 15:03:41
【问题描述】:

我正在尝试在最新的 Chrome、Firefox 和 IE11 中实现这种布局:

我可以通过以下方式来解决这个问题:

html {
  box-sizing: border-box;
}
*, *:before, *:after { 
  box-sizing: inherit;
}

html, body { height: 100%; padding: 0; margin: 0; }

p { line-height: 2em; }

header, footer, article { padding: 10px; }

#parent {
    height: 100%;
    display: flex;
    flex-flow: column nowrap;
    background-color: limegreen;
}

#parent > header {
    flex: none;
    background-color: limegreen;
}

#parent > footer {
    flex: none;
}

#child {
    display: flex;
    flex-direction: column;
    background-color: red;
    height: 100%;
    min-height: 0;
}

#child > header {
    flex: none;
    background-color: #aaa;
}
#child > article {
    flex: 1 1 auto;
    overflow-y: auto;
    min-height: 0px;
}
#child > footer {
    flex: none;
    background-color: #aaa;
}
<section id="parent">
    <header>Parent flex header </header>
    
    <section id="child" >
        <header>Child flex header</header>
        <article>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
            <p>Lots of content.</p>
        </article>
        <footer>Child flex footer</footer>
    </section>
    
    <footer>Parent flex footer</footer>
</section>

然而我觉得有些 CSS 有点奇怪,我想确保我有最大的机会不生成会在某些浏览器更新中中断的 CSS。这样做的原因是该软件将在实际硬件上运行(有点像您的路由器管理界面),并且不能像常规网站那样容易地更新。

所以困扰我的CSS是可滚动的article

#child {
    display: flex;
    flex-direction: column;
    background-color: red;
    height: 100%;
    min-height: 0;
}

我摆弄了heightmin-height 以使其在所有三个中都起作用。最初我只有height: 100%,但这在 Firefox 中不起作用。指定 min-height: 0 可以在 Chrome 和 FF 中工作,但不能在 IE 中工作。这个组合似乎满足了所有 3 个,但谁是正确的?我可以合理地确定这不会在下一个 FF 或 Chrome 中中断吗?从“规范角度”来看,这段代码有意义吗?

【问题讨论】:

    标签: css flexbox


    【解决方案1】:

    确实需要设置min-height,以及实现所需布局的正确方法。 From the spec:

    默认情况下,弹性项目不会缩小到其最小内容大小(最长单词或固定大小元素的长度)以下。要更改此设置,请设置 min-width 或 min-height 属性。

    因此,只有通过设置 min-height,您才能让您的 &lt;article&gt; 实际使用 flex-shrink 并适合父 flex 容器。

    如果我没看错,您在 IE 中看到的问题与错误 described here 和确认的 here 相符:

    在 IE 10-11 中,列方向上的 flex 容器上的 min-height 声明用于确定容器本身的大小,但它们的 flex 项子项似乎不知道其父项的大小。它们的行为就好像根本没有设置高度一样。

    这可能(或可能不)包含有关溢出的问题。

    【讨论】:

    【解决方案2】:

    替代答案:只需指定 #child 中缺少的 flex:1 这会隐式设置 flex: 1 1 0,即第三个 0 表示 flex-basis:0。这很重要,因为flex-basis 的默认初始值不是 0,而是auto,这实际上意味着content-sized。

    From the spec:

    [flex 中的第三个组件] 设置 flex-basis 长手并指定 flex 基础:弹性项目的初始主尺寸,在可用空间之前 根据弹性系数分配。它采用相同的值 width 属性(除了 auto 的处理方式不同)和 附加内容关键字。当从 flex 速记中省略时,它的 指定值为 0%。

    如果指定的 flex-basis 是 auto,则使用 弹性基础是弹性项目主要尺寸的计算值 财产。如果该值本身是自动的,那么使用的弹性基础是 根据其内容自动确定(即大小为 内容)。

    这里是修改后的sn-p:

    html {
      box-sizing: border-box;
    }
    *, *:before, *:after { 
      box-sizing: inherit;
    }
    
    html, body { height: 100%; padding: 0; margin: 0; }
    
    p { line-height: 2em; }
    
    header, footer, article { padding: 10px; }
    
    #parent {
        height: 100%;
        display: flex;
        flex-flow: column nowrap;
        background-color: limegreen;
    }
    
    #parent > header {
        flex: none;
        background-color: limegreen;
    }
    
    #parent > footer {
        flex: none;
    }
    
    #child {
        display: flex;
        flex-direction: column;
        background-color: red;
        height: 100%;
        flex: 1;
    }
    
    #child > header {
        flex: none;
        background-color: #aaa;
    }
    #child > article {
        flex: 1 1 auto;
        overflow-y: auto;
        min-height: 0px;
    }
    #child > footer {
        flex: none;
        background-color: #aaa;
    }
    <section id="parent">
        <header>Parent flex header </header>
        
        <section id="child" >
            <header>Child flex header</header>
            <article>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
                <p>Lots of content.</p>
            </article>
            <footer>Child flex footer</footer>
        </section>
        
        <footer>Parent flex footer</footer>
    </section>

    【讨论】:

    • flex-basis: 0 是我的解决方案
    【解决方案3】:

    这是 Tailwind 中的一个解决方案(悬停类名以查看 CSS 属性)。

    关键的解决办法是使用

    min-height: 0px;
    

    在嵌套容器上。

    <div class="h-screen flex flex-col">
      <div class="h-12 p-1 flex-none bg-gray-400">Header</div>
      <div class="min-h-0 flex-1 flex flex-col">
        <div class="h-12 p-1 flex-none bg-gray-200">Child Header</div>
        <div class="min-h-0 flex-1 overflow-y-auto p-4 space-y-4">
          <div class="h-[600px] bg-white border border-gray-700 rounded-sm"></div>
          <div class="h-[600px] bg-white border border-gray-700 rounded-sm"></div>
          <div class="h-[600px] bg-white border border-gray-700 rounded-sm"></div>
        </div>
        <div class="h-12 p-1 flex-none bg-gray-200">Child Footer</div>
      </div>
      <div class="h-12 p-1 flex-none bg-gray-400">Footer</div>
    </div>
    

    https://play.tailwindcss.com/b33HpTdUWu

    【讨论】:

    • 请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。
    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
    猜你喜欢
    • 2010-09-16
    • 2021-05-23
    • 1970-01-01
    • 2021-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-09
    相关资源
    最近更新 更多