缩小以适应 flexbox 或 flex-basis: content 解决方法中的内容?

Posted

技术标签:

【中文标题】缩小以适应 flexbox 或 flex-basis: content 解决方法中的内容?【英文标题】:Shrink to fit content in flexbox, or flex-basis: content workaround? 【发布时间】:2016-02-07 00:35:27 【问题描述】:

我有一个使用 flexbox 进行布局的 web 应用程序。

我正在尝试填充屏幕(它是一个应用程序,而不是文档),并且尽可能不指定任何固定的宽度或高度,因为内容可能是各种各样的东西(完全流畅的布局!梦想!)

所以我需要流体高度,全宽页眉和页脚,然后在中间的一个主面板填充剩余的垂直空间,分成列,每列在太高时滚动,以及每个非主的宽度列应缩小以适应其内容,而主列会用完剩余空间。

我非常接近,但不得不明确调整非主列的大小 - 我相信 flex-basis: content; 应该这样做,但浏览器尚不支持。

这是一个 minimal demo 显示固定大小的列:

var list = document.querySelector('ul')

for (var i = 0; i < 100; i++) 
  var li = document.createElement('li')
  li.textContent = i
  list.appendChild(li)
html,
body 
  height: 100%;
  width: 100%;
  margin: 0;

body 
  display: flex;
  flex-direction: column;

main 
  display: flex;
  flex-direction: row;
  overflow: hidden;

main > section 
  overflow-y: auto;
  flex-basis: 10em;
  /* Would be better if it were fluid width/shrink to fit, unsupported: */
  /* flex-basis: content; */

main > section:last-child 
  display: flex;
  flex: auto;
  flex-direction: column;

main > section:last-child > textarea 
  flex: auto;
<header>
  <h1>Heading</h1>
</header>

<main>
  <section>
    <h1>One</h1>
    <ul>
    </ul>
  </section>

  <section>
    <h1>Two</h1>
  </section>

  <section>
    <header>
      <h1>Three</h1>
    </header>
    <textarea></textarea>
    <footer>
      <p>Footer</p>
    </footer>
  </section>
</main>

<footer>
  <p>Footer</p>
</footer>

看起来像这样 - 我希望列 OneTwo 缩小/增长以适应而不是固定:

我的问题是,flex-basis: content 是否有纯 CSS 的解决方法,或者实现此目标的替代方法?

我可以像上面那样固定列大小,或者使用 javascript,但我有一个该死的梦想。

【问题讨论】:

【参考方案1】:

我希望第一列和第二列缩小/增长以适应而不是 固定。

你试过了吗:flex-basis: auto

或者这个:

flex: 1 1 auto,简称:

flex-grow: 1(按比例增长) flex-shrink: 1(按比例缩小) flex-basis: auto(初始大小基于内容大小)

或者这个:

main > section:first-child 
    flex: 1 1 auto;
    overflow-y: auto;


main > section:nth-child(2) 
    flex: 1 1 auto;
    overflow-y: auto;


main > section:last-child 
    flex: 20 1 auto;
    display: flex;
    flex-direction: column;  

revised demo

相关:

Make flex items take content width, not width of parent container Make flex container take width of content, not width 100%

【讨论】:

是的 - 前者使列太小,截断部分内容,后者在所有三列之间均匀分配空间 然后您可以将flex 属性分别应用于具有唯一值的每一列。我修改了答案并添加了修改后的小提琴演示。 我们离梦想更近了吗? 所以也许你正在寻找的是flex: 0 0 auto。意思是,不要增长不要缩小调整宽度以适应内容:jsfiddle.net/4ovu226m/3 我现在有了 - 您关于填充的评论让我尝试了一些启发我了解 真正 问题是什么的方法 - 请参阅下面的答案 :)【参考方案2】:

事实证明,它一直在正确地缩小和增长,提供所需的行为;除了在所有当前的浏览器中,flexbox 没有考虑垂直滚动条!这就是内容似乎被截断的原因。

你可以在这里看到,这是我在添加固定宽度之前使用的原始代码,看起来列没有增长以容纳文本:

http://jsfiddle.net/2w157dyL/1/

但是,如果您使该列中的内容变宽,您会发现它总是将其截断相同的量,即滚动条的宽度。

所以修复非常非常简单 - 添加足够的右填充来考虑滚动条:

http://jsfiddle.net/2w157dyL/2/

  main > section 
    overflow-y: auto;
    padding-right: 2em;
  

当我尝试 Michael_B 建议的一些东西(特别是添加一个填充缓冲区)时,我发现了这一点,非常感谢!

编辑:我看到他还发布了一个做同样事情的小提琴 - 再次感谢您的所有帮助

【讨论】:

是的,这是我的padding 建议的基础,在内容和边缘之间创建一些空间。我很高兴问题得到解决。干得好。 是的,我很困惑。我认为 flexbox 有效 ​​- 嗯,flexbox 确实 的工作方式 - 然后当我看到该列被这样切断时,我开始质疑我的心智模型,做出一些愚蠢的假设 - 它一定是让你试图理解我在说什么很困惑,对不起! 我有点困惑。问题不清楚。但我知道您不确定问题出在哪里,因此很难将问题集中在任何具体问题上。 在阅读了您的回答后,我实际上搜索了是否有办法将滚动条 div 之外呈现,而不是在内部。但是我发现没有什么比 padding 解决方案更好的了,它既简单又有效。 是的,我也研究过 - 填充似乎是最好的方法

以上是关于缩小以适应 flexbox 或 flex-basis: content 解决方法中的内容?的主要内容,如果未能解决你的问题,请参考以下文章

flexbox布局

scss Flexbox SASS Mixin:11。flex-basis

Safari 中的 Flexbox:增长和缩小

css3弹性盒模型(Flexbox)

弹性盒模型

使 JQuery UI Dialog 自动增长或缩小以适应其内容