...我正在寻找一种纯 CSS 方法来实现以下目标
行为...如果最宽的项目比...宽...
...我在想也应该有一个纯 CSS 的方式
这样做...
As indicated by @Paulie-D,CSS 无法检测到您孩子 divs 的不同宽度,因此不存在纯 CSS 解决方案。
这是因为您想要获取所有元素的宽度,然后获取其中的最大值,然后使用该宽度将元素分配到列中。这种计算超出了 CSS。您将需要 Javascript 来执行此操作。
如果没有,也许有一种优雅的纯 CSS 方式来分发 /
将动态大小的项目捕捉到容器中的列
宽度固定?
我将分两部分解释:
第 1 部分,CSS:
当我们说我们希望内容在列中时,这意味着从上到下的流程,而不是从左到右的包装流程。为此,我们需要 CSS 列。
诀窍是为column-count / column-width 指定auto。这将自动将内容分配到父宽度内所需的列数中。
我在上述陈述中犯了一个根本性错误(因此又进行了一次编辑)。根据specs here,算法说:
(01) if ((column-width = auto) and (column-count = auto)) then
(02) 退出; /* 不是多列元素 */
这是我之前错的地方。当column-count 和column-width 都设置为auto 时,它被视为不是多列元素。当这些属性之一设置为非自动值时,另一个属性由该属性确定。
来自above ref:
如果column-count 设置为auto,那么列数将由其他属性确定(例如,column-width,如果它具有非自动值)
和
如果column-width 设置为auto,则列宽将由其他属性确定(例如,column-count,如果它具有非自动值)
例如,将column-width 设置为固定宽度,例如120px(我们将在稍后的第 2 部分中处理这个问题):
.container { -webkit-columns: auto 120px; columns: auto 120px; }
这将导致容器在其自身宽度内将内容放入尽可能多的列中以适应120px 的列宽。如果增加容器宽度,它将获得更多列。如果您减小容器宽度,当可用空间不多时,它会减少最终折叠成一列的列。
请参阅下面的 sn-p 中的完整示例:
示例 1:
* { box-sizing: border-box; padding: 0; margin: 0; }
p { margin-left: 16px; }
.container { width: 400px; border: 1px solid #f00; margin: 16px; }
.container.col { -webkit-columns: auto 120px; columns: auto 120px; }
.container > div {
-webkit-column-break-inside: avoid; column-break-inside: avoid;
display: block; padding: 8px; border: 1px solid #ccc;
}
#one { width: 200px; }
#two { width: 300px; }
<p>Small Container (1-column):</p>
<div id="one" class="container col">
<div class="item-min">Maudie Mcmanus</div>
<div class="item-min">Remedios</div>
<div class="item-min">Chaya B</div>
<div class="item-min">Duncan</div>
<div class="item-min">Lashonda</div>
</div>
<p>Medium Container (2-column):</p>
<div id="two" class="container col">
<div class="item-min">Maudie Mcmanus</div>
<div class="item-min">Remedios</div>
<div class="item-min">Chaya B</div>
<div class="item-min">Duncan</div>
<div class="item-min">Lashonda</div>
</div>
<p>Large Container (3-column):</p>
<div id="three" class="container col">
<div class="item-min">Maudie Mcmanus</div>
<div class="item-min">Remedios</div>
<div class="item-min">Chaya B</div>
<div class="item-min">Duncan</div>
<div class="item-min">Lashonda</div>
</div>
小提琴 1:http://jsfiddle.net/abhitalks/tgwp4b7a/2/show
在上面的 sn-p 中,我们在容器上使用column-count: auto,以及任意的column-width: 120px(仅用于演示)。这就是它的全部。上面的代码中有三个例子:(1)容器宽度小,内容分布在一列中,因为它们受到column-width的约束; (2) 容器中等宽度,内容分布在两列中,因为现在有更多可用空间; (3) 容器的宽度要大得多,可以容纳三列。
作为副作用,如果容器的宽度是百分比,那么整个设备也会自动响应。在大屏幕上显示更多列,在小屏幕上折叠成一列。
但是,这取决于您为容器的 column-width 提供的固定宽度,因此也可以称为 magic-number 解决方案。 但是,这不是我们想要的。我们不想根据容器的宽度来确定列,我们希望列由内容的宽度来确定。我们将在接下来的第 2 部分中了解如何消除这种依赖关系。
第 2 部分,用 Javascript 扩展它:
现在我们已经确定元素可以通过 CSS 自动分布在列中,具体取决于父级可用的宽度,我们可以扩展它以通过 Javascript 消除对固定宽度的依赖。
回到你的问题:
...如果最宽的项比...宽...
为了确定最宽的项目并将该宽度应用于其余项目,您只需要 a well-known 两行 Javascript:
var maxWidth = Math.max.apply(null, $("div.item").map(function () {
return $(this).width();
}).get());
我们还将子divs 设置为inline-block 防止换行以识别实际宽度。因此,您需要添加到我们在第 1 部分中编写的 CSS 中的是:
.container > div {
display: inline-block;
white-space: nowrap; /* prevents wrapping and helps getting actual width */
}
然后我们需要做两件事:(1)将容器上的column-width设置为我们上面计算的这个最大宽度; (2) 将此宽度设置为所有子 div 以使它们整齐地堆叠。此外,我们不需要在 CSS 中设置 column-count / column-width,因为无论如何我们都必须在 Javascript 中进行设置。
$("#container").css({ "column-width": maxWidth }).find('div').width(maxWidth);
请参阅下面的 sn-p 中的完整示例:
示例 2:
//large
var maxWidth = Math.max.apply(null, $("#one > div").map(function () { return $(this).outerWidth(); }).get());
$("#one").css({ "-webkit-column-width": maxWidth, "column-width": maxWidth }).find('div').outerWidth(maxWidth);
// medium
var maxWidth2 = Math.max.apply(null, $("#two > div").map(function () { return $(this).outerWidth(); }).get());
$("#two").css({ "-webkit-column-width": maxWidth2, "column-width": maxWidth2 }).find('div').outerWidth(maxWidth2);
// small
var maxWidth3 = Math.max.apply(null, $("#three > div").map(function () { return $(this).outerWidth(); }).get());
$("#three").css({"-webkit-column-width": maxWidth3, "column-width": maxWidth3 }).find('div').outerWidth(maxWidth3);
* { box-sizing: border-box; padding: 0; margin: 0; }
p { margin-left: 16px; }
.container { width: 450px; border: 1px solid #f00; margin: 16px; }
.container > div {
-webkit-column-break-inside: avoid; column-break-inside: avoid;
display: inline-block; white-space: nowrap;
padding: 8px; border: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Normal children (wrapping):</p>
<div class="container">
<div class="item">Maudie Mcmanus</div>
<div class="item">Remedios Arrington</div>
<div class="item">Chaya B</div>
<div class="item">Duncan</div>
<div class="item">Lashonda Tatum Walls</div>
</div>
<p>Large children (1-column):</p>
<div id="one" class="container">
<div class="item-min">Maudie Mcmanus Mcmanus Mcmanus</div>
<div class="item-min">Remedios</div>
<div class="item-min">Chaya B</div>
<div class="item-min">Duncan</div>
<div class="item-min">Lashonda</div>
</div>
<p>Medium children (2-column):</p>
<div id="two" class="container">
<div class="item-min">Maudie Mcmanus Mcmanus</div>
<div class="item-min">Remedios</div>
<div class="item-min">Chaya B</div>
<div class="item-min">Duncan</div>
<div class="item-min">Lashonda</div>
</div>
<p>Small children (3-column):</p>
<div id="three" class="container">
<div class="item-min">Maudie Mcmanus</div>
<div class="item-min">Remedios</div>
<div class="item-min">Chaya B</div>
<div class="item-min">Duncan</div>
<div class="item-min">Lashonda</div>
</div>
小提琴 2:http://jsfiddle.net/abhitalks/ojd57678/4/show
(更改了上面的 sn-p 和小提琴。感谢@Yandy_Viera,他指出应该使用 jQuery .outerWdith 而不是 .width(忽略 box-sizing: border-box,导致要设置的宽度不正确。)
在上面的 sn-p 中,我们现在使用了三个示例的变体: (1) 其中子 divs 的宽度较大,并且由于受容器宽度的限制而分布在一列中; (2) 其中子divs 的宽度较小,并且分布在两列中,因为现在有更多可用空间; (3) 其中子divs 的宽度非常小,可以容纳在三列中。
如您所见,CSS 可以帮助根据可用宽度将内容分配到列中,但不能计算最宽的元素宽度并将其应用于每个列。为此,一个两行 Javascript 将使您完成您最初想要的工作。
注意:当我第一次阅读您的问题时,我的印象是您已经有了一个可用的 Javascript 解决方案,但我不确定您是否想要一个。但是,在第二次阅读时,我意识到您没有,并且 Javascript 角度对于理解是必不可少的。因此,此编辑添加了 Javascript 部分。
注意 2:此答案的先前版本存在一个缺陷,我在列属性的自动值中引入了一个基本错误。这需要再次编辑。