像 CSS 中的弹性项目一样收缩网格项目

Posted

技术标签:

【中文标题】像 CSS 中的弹性项目一样收缩网格项目【英文标题】:Shrink grid items just like flex items in css 【发布时间】:2019-03-25 17:19:51 【问题描述】:

是否可以像 CSS 中的 flex 项一样缩小网格项?

网格项目

.container 
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));


.child 
  display: flex;
  flex-flow: row wrap;
  align-items: center;
  justify-content: center;
  padding: 5px;
  border: 3px solid #a07;
<div class="container">
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
</div>

jsfiddle

弹性项目

.container 
  display: flex;
  margin-left: -10px;
  flex-flow: row wrap;


.child 
  display: flex;
  flex-flow: row wrap;
  align-items: center;
  justify-content: center;
  padding: 5px;
  border: 3px solid #a07;
  flex: 200px 1 1;
  margin-left: 10px;
  margin-bottom: 10px;
<div class="container">
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
</div>

jsfiddle

简而言之,我可以通过上面的 flex 对元素进行以下定位:

enter image description here

虽然我无法通过使用网格布局来实现相同的行为。 Flex 布局允许项目在小屏幕上缩小,而网格布局不允许。同时,我想保留这样的行为,即只有在这样的放置之后,该项目将与另一个项目一起移动到下一行,并且每个项目都不会短于特定大小(在我们的例子中为 200 像素)。

我使用网格布局是因为它允许保留所有子项的宽度相同的不变量。使用 flex 布局,如果最后一项单独在行上,则最后一项将被拉伸到整行。

【问题讨论】:

好问题。当前版本的网格看起来不可能,因为minmax() 函数定义了轨道的实际最小宽度。这篇文章可能对你有用:***.com/q/42176419/3597276 @Michael_B,谢谢。检查了所提供问题中的所有内容。将等待我的问题的解决方案出现。 ( : @Michael_B 比方说,有一个伪解决方案:) 【参考方案1】:

新解决方案

使用min()的初始解决方案的优化版本

.container 
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(min(200px,100%), 1fr));


.child 
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 5px;
  border: 3px solid #a07;


body 
  margin:0;
<div class="container">
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
</div>

旧解决方案

一种解决方案是为依赖视口单元的子元素指定max-width,因为百分比值是相对于minmax() 定义的轨道大小而无法使用的。此解决方案不是通用的,您需要根据每种情况调整值。

例如,在您的情况下,我们可以使用100vw,因为容器是主体中唯一的元素并且占据了整个宽度:

.container 
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));


.child 
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 5px;
  border: 3px solid #a07;
  max-width:100vw;
  box-sizing:border-box; /* Don't forget this !*/


body 
  margin:0;
<div class="container">
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
</div>

如果有更多元素或一些填充/边距,您需要在 max-width 计算中考虑它们:

.container 
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));


.child 
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 5px;
  border: 3px solid #a07;
  max-width:calc(100vw - 40px); /*we remove the body margin*/
  box-sizing:border-box; 


body 
  margin:0 20px; 
<div class="container">
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
  <div class="child">
    text
  </div>
</div>

就像我们不再有 2 个约束,而是 3 个:

网格单元的最小尺寸为200px 网格单元填充剩余空间 网格单元内的元素具有相对于屏幕尺寸定义的最大尺寸。 (我们缺少的收缩约束)

【讨论】:

以上是关于像 CSS 中的弹性项目一样收缩网格项目的主要内容,如果未能解决你的问题,请参考以下文章

在不影响居中兄弟的情况下附加弹性项目

react - 弹性容器外的弹性项目

CSS Flexbox - 根据屏幕大小组织弹性项目

CSS3--Flex弹性盒子布局: flex项目的属性

CSS3--Flex弹性盒子布局: 实例篇-网格布局

CSS Flex Box:如何在不丢失弹性项目高度的情况下将“弹性项目”垂直对齐到中间?