具有固定列宽的流动 flexbox 网格

Posted

技术标签:

【中文标题】具有固定列宽的流动 flexbox 网格【英文标题】:Fluid flexbox grid with fixed column widths 【发布时间】:2016-04-13 19:45:01 【问题描述】:

我有一个通过 flexbox 设置的容器。我想平均分配容器内的每个图块,但将它们保持在 220 像素的固定宽度。

我已经接近使用flex-grow 并设置了min-width: 220px,但它显然已经通过计算调整了瓷砖的大小以填充容器。

我还设置了一些媒体查询,以便在某些断点上堆叠图块。

使用我当前的样式是否可以将这些图块保持在 220 像素而不拉伸?这可以通过 flexbox 完成吗?有没有和 flexbox 一样好的替代品?

Fiddle

.container 
  border: 1px solid red;
  display: flex;
  flex-wrap: wrap;
  margin: 0 auto;
  max-width: 2000px;

.tiles 
  border: 1px solid black;
  margin: 0 15px 30px 15px;
  flex-grow: 1;
  padding: 0;
  height: 220px;
  min-width: 220px;

@media screen and (max-width: 1140px) 
  .container 
    max-width: 850px;
  

@media screen and (max-width: 2040px) 
  .container 
    max-width: 1750px;
  

@media screen and (max-width: 1790px) 
  .container 
    max-width: 1500px;
  

@media screen and (max-width: 1540px) 
  .container 
    max-width: 1250px;
  

@media screen and (max-width: 1290px) 
  .container 
    max-width: 1000px;
  

@media screen and (max-width: 1040px) 
  .container 
    max-width: 750px;
  

@media screen and (max-width: 790px) 
  .container 
    max-width: 500px;
  
<div class="container">
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="tiles"></div>
</div>

【问题讨论】:

你还需要tiles总是在中心吗? 您是否尝试过简单地设置.tileswidth 属性? 看到这个updated fiddle,我猜你不需要那些媒体查询。 @Pangloss 对不起,我似乎用错了我之前的评论。我基本上希望网格能够正常工作(不使用float:jsfiddle.net/danield770/EBncj/6。通过:***.com/a/21245751/3046413 知道了!好的,请参阅这篇文章 - ***.com/q/33192745/483779 我实际上在不久前为它提供了 200 个代表的赏金,到目前为止仍然没有更好的解决方案,即使使用 flexbox。 【参考方案1】:

我想平均分配容器内的每个图块 但将它们保持在 220 像素的固定宽度。

根据我当前的样式,是否可以将这些图块保持在 220 像素 没有他们伸展?

这可以通过 flexbox 完成吗?

是的,是的。

不要在图块上使用flex-growmin-width,而是使用flex 属性。

所以,而不是:

.tiles 
    flex-grow: 1;
    min-width: 220px;

试试这个:

.tiles 
    flex: 0 0 220px; /* don't grow, don't shrink, stay at 220px width */

flex 属性是 flex-growflex-shrinkflex-basis 的简写。

flex-grow 属性控制在分配额外空间时弹性项目相对于容器中其他弹性项目的增长方式。通过将值设置为0,它根本不会从初始主大小(由flex-basis 定义)增长。

flex-shrink 属性控制当弹性项目溢出容器时相对于其他弹性项目如何收缩。通过将值设置为0,它根本不会从初始主大小(由flex-basis 定义)缩小。

flex-basis 属性设置弹性项目的初始主尺寸。


我还设置了一些媒体查询,以便在某些断点上堆叠图块。

通过使用上面指定的flex 属性以及代码中已有的flex-wrap,您可能不需要媒体查询。考虑报废它们。


此时,你的布局可能是:DEMO

您可能遇到了一个共同的问题:当 flex 项目包装时,容器不会重新计算其宽度以收缩包装更少的列,从而导致large area of whitespace on the right。

有关更多详细信息和可能的解决方法,请参阅我的回答:Flexbox Limitation & Challenge


更新

在cmet中做了一些澄清和修改后,找到了解决办法:

HTML

<ul id="content">
    <li class="box"></li>
    <li class="box"></li>
    <li class="box"></li>
            ...
            ...
            ...
</ul>

CSS

*

    margin:0;padding:0;


#content 
    display: flex;
    flex-wrap: wrap;
    list-style: none;
    margin:0 auto;

.box 
    flex: 0 0 90px;
    height: 90px;
    margin: 5px;
    background-color: blue;


@media (min-width: 200px) 
  #content 
    width: 200px;
  

@media (min-width: 300px) 
  #content 
    width: 300px;
  

@media (min-width: 400px) 
  #content 
    width: 400px;
  

@media (min-width: 500px) 
  #content 
    width: 500px;
  

@media (min-width: 600px) 
  #content 
    width: 600px;
  

@media (min-width: 700px) 
  #content 
    width: 700px;
  

@media (min-width: 800px) 
  #content 
    width: 800px;
  

@media (min-width: 900px) 
  #content 
    width: 900px;
  

@media (min-width: 1000px) 
  #content 
    width: 1000px;
  

@media (min-width: 1100px) 
  #content 
    width: 1100px;
  

DEMO

【讨论】:

【参考方案2】:

所以 flexbox 具有增长和缩小的能力,你可以关闭它(你可以阅读更多关于 here 的内容,我发现这是一个很好、快速的 flexbox 指南)。一次性定义flex-growflex-shrinkflex-basis 的简写是flex: 0 0 auto,零表示框不会扩大或缩小,但仍保持您之前定义的大小。我修改了你的 jsfiddle 来展示它是如何工作的:

FIDDLE

【讨论】:

【参考方案3】:

阅读 Michael_B 上的 cmets 答案后,我相信缺少的是 justify-content: center ...

.container 
  display: flex;
  flex-wrap: wrap;
  margin: 0 auto;
  max-width: 2000px;
  justify-content: center;


.tiles 
  border: 1px solid black;
  margin: 0 15px 30px 15px;
  flex: 0 0 220px;
  padding: 0;
  height: 220px;


.filler 
  border: 1px solid transparent;
  margin: 0 15px 0px 15px;
  flex: 0 0 220px;
  padding: 0;
  height: 0px;
  
<div class="container">
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="tiles"></div>
  <div class="filler"></div>
  <div class="filler"></div>
  <div class="filler"></div>
  <div class="filler"></div>
  <div class="filler"></div>
  <div class="filler"></div>
  <div class="filler"></div>
  <div class="filler"></div>
  <div class="filler"></div>
  <div class="filler"></div>
</div>

【讨论】:

我在justify-content 中发现的问题是,剩余的奇数瓷砖中心(应该如此)与左对齐。 html 添加额外元素可以吗? 嗯..瓷砖将动态生成,所以我无法确定容器中有多少/几个。 你不需要。您只需要添加一个足够高的数字以应对最坏的情况。请参阅使用 10 个填充物的示例

以上是关于具有固定列宽的流动 flexbox 网格的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5:具有相等列宽的布局按钮

具有不同列宽的 XHTML 严格表

QTableView自适应填充伸展列宽的基础上 再固定特定某列宽

EXCEL里面如何设置能把行高和列宽的长度固定?

Kivy 网格布局固定了某些列的列宽

基础固定列宽的表格及示例演示