绝对定位的flexbox不会扩展以适应内容[重复]

Posted

技术标签:

【中文标题】绝对定位的flexbox不会扩展以适应内容[重复]【英文标题】:Absolutely positioned flexbox doesn't expand to fit contents [duplicate] 【发布时间】:2015-06-14 16:16:55 【问题描述】:

正如您从下面的代码片段 (View as Fiddle) 中看到的那样,绝对定位的柱状 flexbox 不会扩展以适应其子级。

例如,在 Chrome 中,它只会与最宽的子元素一样宽,与最短的列一样高。

任何人都可以在不使用任何附加标记的情况下提出解决方案吗?

编辑:列表中的项目数量是动态的,每个项目中的文本也是如此。在一定数量的项目之后,我需要换一个新列。

*box-sizing:border-box;
ul
    background:#090;
    display:flex;
    flex-flow:column wrap;
    left:0;
    list-style:none;
    max-height:202px;
    padding:5px;
    position:absolute;
    top:0;

li
    background:rgba(255,0,0,.75);
    color:#fff;
    flex:1 0 30px;
    font-family:arial;
    line-height:30px;
    max-height:30px;
    margin:1px;
    padding:0 2px;
    min-width:100px;
<ul>
    <li>Line 0</li>
    <li>Line 1</li>
    <li>Line 2</li>
    <li>Line 3</li>
    <li>Line 4</li>
    <li>Line 5</li>
    <li>Line 6</li>
    <li>Line 7</li>
    <li>Line 8 is a little bit longer</li>
</ul>

【问题讨论】:

您需要将数据分成两列吗? 列表中的项目数将是动态的,我试图让它在设定的数字后进入一个新列,因此可能有任意数量的列。跨度> 那么你可能不得不使用百分比。 你能详细说明一下吗,lharby? 抱歉,我不太了解 flex 属性。我尝试将其设置为 clearfix 的默认属性,并带有 display:block 的后备功能,因此较旧的浏览器会解释它。我在想你可以浮动 li,然后给它们 50%、33%、25% 等宽度,但我认为这违背了使用 flex 属性的目的。 【参考方案1】:

带有position:absolute; 的弹性盒子不再被视为弹性盒子,因此您当前的问题。

如果要使用position:absolute;,则必须使用预定义的宽度和高度。


请参阅此处了解关于 flexbox 的 w3c http://www.w3.org/TR/css3-flexbox/#flex-items

“弹性项目本身是弹性级盒子,而不是块级盒子:它们参与容器的弹性格式化上下文,而不是块格式化上下文。”

通过更改为position:absolute;,你强制弹性容器成为一个块元素(这发生在所有带有position:absolute;的元素上),从而消除了它的灵活性,也因为它的内容不是块元素,它们是弹性的孩子们,他们只能影响一个弹性级别的容器,而不是一个块。


Jquery 解决方案

没错,所以有一种方法可以用 jquery 来做到这一点。

这可能不是你想要的,因为它不仅仅是 CSS,但它确实有效。

我在这里所做的是将容器的宽度设为原始宽度。

然后获取每 6 个元素的最大宽度(因为那是您的行中断以形成新列的时间)。

然后计算总列数,并用它来将每列的最大宽度乘以列数,然后最后将它们加在一起以获得所需的容器宽度。

随意删除并添加新列以进行全面测试。

Fiddle

var count = $("ul.flex-container li:nth-child(6n)").length;

var firstWidth = Math.max.apply(null, $("ul.flex-container").map(function() 
  return $(this).outerWidth(true);
).get());

var childWidth = Math.max.apply(null, $("ul.flex-container li:nth-child(6n+6)").map(function() 
  return $(this).outerWidth(true);
).get());

var totalWidth = childWidth * count

$("ul.flex-container").css(
  width: firstWidth + totalWidth,
);
ul.flex-container 
  background: #090;
  display: flex;
  flex-flow: column wrap;
  list-style: none;
  max-height: 192px;
  padding: 5px;
  position: absolute;

ul.flex-container li 
  background: rgba(255, 0, 0, .75);
  color: #fff;
  flex: 1 0 30px;
  font-family: arial;
  line-height: 30px;
  margin: 1px;
  padding: 0 2px;
  min-width: 100px;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul class="flex-container">
  <li>Line 0</li>
  <li>Line 1</li>
  <li>Line 2</li>
  <li>Line 3</li>
  <li>Line 4</li>
  <li>Line 5</li>
  <li>Line 6</li>
  <li>Line 7</li>
  <li>Line 8 is a little bit longer</li>
  <li>Line 0</li>
  <li>Line 1</li>
  <li>Line 2</li>
  <li>Line 3</li>
  <li>Line 4</li>
  <li>Line 5</li>
  <li>Line 6</li>
  <li>Line 7</li>
  <li>Line 8 is a little bit longer</li>
</ul>

【讨论】:

谢谢,DCdaz。我再次阅读了该文档,虽然它指出“一个绝对定位的 child flex 容器不参与 flex 布局”,但我没有看到绝对定位的 flex 容器。跨度> HI Shaggy 最好通读一遍以了解其要点,这是一个关键领域。 “弹性项目本身是弹性级别的盒子,而不是块级的盒子:它们参与其容器的弹性格式化上下文,而不是块格式化上下文。” 通过更改为绝对值,您可以强制弹性容器成为一个块元素,从而消除了它的灵活性,反过来它的内容不是块元素,有弹性子元素,只能影响弹性级别容器而不是块元素。 您应该将其添加到您的答案中:) 暂时赞成。如果第二天或第二天没有人提出解决方案,我会接受这个作为答案,因为它解释了问题发生的原因。不过,我不知道我是否能够奖励赏金,因为您的答案不包括我真正想要的解决方案。 我们得到了你想要的完全可用的版本,尽管它确实使用了 jquery。【参考方案2】:

您的子元素不适合 flex-container 的原因是您在容器上设置了 max-height

但是在您的原始示例中发生的事情很奇怪(特别是子元素从 column 中取出);

看起来 flex-items 无法识别容器边框,而 flexbox 正在尝试填充它们(甚至更改 flex-direction:column); 唯一真正有意义的是最宽元素的最大宽度。

这是一个没有最大宽度的 sn-p:

ul
    background:#090;
    display:flex;
    flex-flow:column wrap;
    list-style:none;
    padding:5px;
    position:absolute; /*max-height:192px;*/

/*ul::afterdisplay:table;clear:both; content:''clearfix*/
li
    background:rgba(255,0,0,.75);
    color:#fff;
    flex:1 0 30px;
    font-family:arial;
    line-height:30px;
    margin:1px;
    padding:0 2px;
    min-width:100px;
<ul>
    <li>Line 0</li>
    <li>Line 1</li>
    <li>Line 2</li>
    <li>Line 3</li>
    <li>Line 4</li>
    <li>Line 5</li>
    <li>Line 6</li>
    <li>Line 7</li>
    <li>Line 8 is a little bit longer</li>
</ul>

编辑

我不知道你想要的输出是什么,但典型的 flexbox 实现可能是这样的:

ul
    background:#090;
    display:flex;
    flex-flow:column wrap;
    list-style:none;
    padding:5px;
    /*position:absolute;*/
    height:192px;

   /*ul::afterdisplay:table;clear:both; content:''/*clearfix*/
li
    background:rgba(255,0,0,.75);
    color:#fff;
    flex:1 0 30px;
    font-family:arial;
    line-height:30px;
    margin:1px;
    padding:0 2px;
   /* width:100px;*/
<ul>
    <li>Line 0</li>
    <li>Line 1</li>
    <li>Line 2</li>
    <li>Line 3</li>
    <li>Line 4</li>
    <li>Line 5</li>
    <li>Line 6</li>
    <li>Line 7</li>
    <li>Line 8 is a little bit longer</li>
</ul>

【讨论】:

这并不能以任何方式回答我的问题,它只是本质上重复了我所说的话。 删除max-height 不能解决您的问题吗? sn-p 似乎还可以 不,它没有。当达到max-height 时,我想换一个新列。 flex-flow 属性是 flex-direction + flex-wrap 的简写,因此在您的情况下 flex-direction 的值为 column ,预期的行为是它垂直扩展,并且 max-height正在破坏 flexbox 它垂直扩展并在必要/可能的情况下进行换行,因此flex-wrap 属性。 max-height 属性不是这里的问题,它是导致子元素完全按照我想要的方式布局的原因。问题在于父母的行为不符合预期。

以上是关于绝对定位的flexbox不会扩展以适应内容[重复]的主要内容,如果未能解决你的问题,请参考以下文章

CSS flexBox不会定位到底部[重复]

使 HTML 元素扩展以适应内容

如何使用 Tailwind 在 Flexbox 中阻止子 div 扩展以适应其父级的宽度

具有绝对位置的 Flexbox 容器不适合 IE 中的内容宽度

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

展开 div 以包含绝对定位的内容