如何让所有项目二维收缩到最大的项目内容?

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-fillauto-fit) 具有固有灵活尺寸。

intrinsic 大小调整函数是 min-contentmax-contentautofit-content()

flexible 大小调整函数是 &lt;flex&gt; (fr)。

您可以通过以下方式绕过auto 限制:

repeat(auto-fill, minmax(min-content, 1px))

minmax(min,max)

定义大于或等于 min 且小于或 等于 max

如果 max ,则 max 被忽略,minmax(min,max) 被视为 min

作为最大值,&lt;flex&gt; 值设置轨道的弹性系数;至少是无效的。

也许其他人可以从这里拿走它。

【讨论】:

@Micheal_B 感谢您的洞察力。这几乎是我要去的地方,我昨天阅读了整个规范。我认为这会很简单,但网格似乎无法实现。【参考方案2】:

看起来没有JS你不能不这样做。

使用 JS 可以计算最大宽度并将其设置为所有元素。

然后将所有子元素显示为 inline-blockblock 父 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 在这种情况下脚本执行的顺序很重要。编辑我的代码后丢失了什么。人家一味地把脚本代码抄在脑子里,是不会为他们工作的。

以上是关于如何让所有项目二维收缩到最大的项目内容?的主要内容,如果未能解决你的问题,请参考以下文章

让 WPF Tabcontrol 高度假设最大项目的高度?

如何删除git远程仓库项目的所有内容,重新提交所有内容

只用CSS能否制作可以收缩的下拉菜单

项目营销经理搜索引擎排名机制,网站轻松快速排名

Vue项目 UI框架介绍(第六天上)

《Android App开发进阶与项目实战》资源下载和内容勘误