绝对定位的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不会扩展以适应内容[重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Tailwind 在 Flexbox 中阻止子 div 扩展以适应其父级的宽度
具有绝对位置的 Flexbox 容器不适合 IE 中的内容宽度