如何让所有项目二维收缩到最大的项目内容?
Posted
技术标签:
【中文标题】如何让所有项目二维收缩到最大的项目内容?【英文标题】:How to get all items to shrink to the largest item content two dimensionally? 【发布时间】:2018-10-10 08:57:06 【问题描述】:在下面的示例中,我希望所有项目都为最大内容的宽度(例如项目 5)。
列表中的项目数是动态的,可能有一百个 其中。
每个item内容的宽度也是动态的。
每行中的项目数会因宽度而异 容器。
期望的输出
注意: 媒体查询不适用于我的场景。
使用 CSS FLEX
Flex
被认为是一维。这意味着它可以在单个轴(行)上达到预期的效果,除非内容小于可用空间。
非换行示例(单行)
.container
display: flex;
.item
background: #58c;
text-align: center;
white-space: nowrap;
margin: 0 10px 10px 0;
flex: 1;
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5 is longer</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>
Flex 的flex-wrap
属性可用于创建二维 布局。同样,这很好用,但需要 固定宽度 值来计算每个项目的宽度。
包装示例(多行)
.container
display: flex;
flex-wrap:wrap;
.item
background: #58c;
text-align: center;
white-space: nowrap;
margin: 0 10px 10px 0;
flex: 0 1 100px;
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5 is longer</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
使用 CSS 网格
对于二维设计,建议使用CSS Grid,但下面的示例使用固定宽度。似乎min-content
需要在这里考虑,但是如何?
失败的例子
grid-template-columns: repeat(auto-fit, min-content);
固定示例(多行)
.container
display: grid;
grid-template-columns: repeat(auto-fit, 100px);
grid-auto-rows: 20px;
grid-gap: 5px;
.item
background: #58c;
text-align: center;
white-space: nowrap;
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5 is longer</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
我不认为这是通过网格实现的,因为以下W3C note:
“自动重复(自动填充或自动适应)不能与 内在或灵活的尺寸。”
总结
从根本上说,我认为使用 css 没有内在的方法可以做到这一点。
要获得每个项目的宽度,它需要:
预定义(固定)。 使用百分比或分数水平推断。 从当前列垂直推断。我认为无法同时从另一行和列推断项目宽度。
【问题讨论】:
可能重复:***.com/questions/48003318/… @TemaniAfif 不完全相同的问题。我已修改我的问题以澄清。 我知道,这就是为什么我只是把它做成了一个可能的副本,我没有关闭它,因为这是一个相关的问题,不能给你一些想法 @leonheess 甚至没有接近。所有答案都有固定的 html 布局。它必须是动态的。 @DreamTeK 感谢您的快速回答,我撤回了我的近距离投票 【参考方案1】:这似乎是 CSS Grid 应该能够处理的问题。但是我在规范中没有看到任何提供解决方案的东西。我并不是说它不存在,无论是作为一个简单的命令还是规则的组合。我只是没有找到它(如果它存在的话)。
这是我能得到的最接近的:
.container
display: grid;
grid-auto-columns: min-content; /* max-content works, as well */
grid-gap: 10px;
.item
background: #58c;
text-align: center;
white-space: nowrap;
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5 is longer</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
上面的代码解决了宽度问题——所有项目都是最长项目的长度。但是没有包装。这个问题在下面的例子中被翻转了。
.container
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min-content, 1px));
grid-gap: 10px;
.item
background: #58c;
text-align: center;
white-space: nowrap;
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5 is longer</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
上面的代码开始包装,绕过intrinsic size limitation when using repeat()
。但是,最长内容等长要求不成立。
7.2.2.1. Syntax of
repeat()
无法组合自动重复(
auto-fill
或auto-fit
) 具有固有或灵活尺寸。intrinsic 大小调整函数是
min-content
、max-content
、auto
、fit-content()
。flexible 大小调整函数是
<flex>
(fr
)。
您可以通过以下方式绕过auto
限制:
repeat(auto-fill, minmax(min-content, 1px))
minmax(min,max)
定义大于或等于 min 且小于或 等于 max。
如果 max ,则 max 被忽略,
minmax(min,max)
被视为 min。作为最大值,
<flex>
值设置轨道的弹性系数;至少是无效的。
也许其他人可以从这里拿走它。
【讨论】:
@Micheal_B 感谢您的洞察力。这几乎是我要去的地方,我昨天阅读了整个规范。我认为这会很简单,但网格似乎无法实现。【参考方案2】:看起来没有JS你不能不这样做。
使用 JS 可以计算最大宽度并将其设置为所有元素。
然后将所有子元素显示为 inline-block
在 block
父 div 中。
var max = document.querySelector('.container .item').offsetWidth;
var styles = '.container .item width: ' + max + 'px; ';
var styleSheet = document.createElement("style");
styleSheet.type = "text/css";
styleSheet.innerText = styles;
document.head.appendChild(styleSheet);
document.querySelector('.container.init').classList.remove('init');
.container.init
display: inline-block;
max-height: 100px;
visibility: hidden;
.container .item
display: inline-block;
background: #58c;
text-align: center;
white-space: nowrap;
margin: 0 10px 10px 0;
.container.init .item
display: block;
<div class="container init">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5 is longest text ever</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>
【讨论】:
@DreamTeK 在这种情况下脚本执行的顺序很重要。编辑我的代码后丢失了什么。人家一味地把脚本代码抄在脑子里,是不会为他们工作的。以上是关于如何让所有项目二维收缩到最大的项目内容?的主要内容,如果未能解决你的问题,请参考以下文章