首页 > 解决方案 > 居中网格内容,同时左对齐每一行的内容,具有任意项/列宽度

问题描述

我有一排任意宽度的项目。它们在容器内居中(注意红色容器左右两侧的空白区域):

在此处输入图像描述

有时容器变得小于所有项目的宽度:

在此处输入图像描述

发生这种情况时,我希望最后的项目像这样包装到下一行:

在此处输入图像描述

对我来说非常重要的是每一行的内容必须左对齐,但整个网格必须居中

在此处输入图像描述

最初,我尝试使用 FlexBox 实现它。在经历了很多挫折和拉扯之后,我了解到这在 FlexBox 中是不可能的:https ://stackoverflow.com/a/32811002/901944

同一页面上的另一个答案建议使用 CSS 网格而不是 flexbox。

CSS 网格产生的结果略有不同,但这也适合我:

在此处输入图像描述

这是使它工作的代码:

.red-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, max-content));
  justify-content: center;
}

这段代码包含很多我看不懂的关键字:grid-template-columns, repeat, auto-fit,minmaxmax-content. 我尝试阅读它们但失败了。没有任何指南和 API 文档明确解释这种特定组合的工作原理。MDN 文档太短太神秘了。

我特别纠结的是这个210px神奇的数字。为什么有必要?(嗯,我知道这是必要的,因为规范是如何设计的,但这并不能帮助我理解。)

我的网格中项目的大小是任意的,所以我不能使用固定值。此外,设置此固定值会使结果略有偏差:小项目增长而大项目溢出容器。

我本质上想要的是:

  grid-template-columns: repeat(auto-fit, minmax(min-content, max-content));

但是该规则被浏览器识别为错误的。

我偶然发现了这个答案,它解释了在这种情况下,规范禁止min-content同时使用两者。max-content答案建议的解决方案是……使用 Flexbox!

循环已关闭。我回到了我开始的地方,期待我现在头上的头发又少了一轮。

如何在左对齐每行内容的同时将网格居中,并且项目具有任意宽度?

为了您的方便,这里有一个样板文件:https ://jsbin.com/vuguhoj/edit?html,css,output

可以通过拖动右下角来调整容器的大小。

PS不display: inlinefloat: left请。

.page {
  border: 1px solid black;
  overflow: hidden;
  resize: horizontal;
  max-width: 500px;
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(max-content, 50px));
  justify-content: center;
}

.item {
  border: 1px solid black;
  margin: 1px;
}
<div class="page">
  <div class="grid">
    <div class="item">
      Foofoofoo
    </div>
    <div class="item">
      Bar
    </div>
    <div class="item">
      BazBaz
    </div>
    <div class="item">
      QuuxQuuxQuux
    </div>
  </div>
</div>

标签: cssflexboxcss-grid

解决方案


CSS 网格方法
- 根答案 - joe82

.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(179px, max-content));
  grid-gap: 10px;
  justify-content: center;
  background: #999;
  overflow: hidden;
  padding: 10px;
}

.background {
  width: 179px;
  height: 64px;
  background: #99d9ea;
}

.background .child {
  border: 2px solid #000;
}

.background:nth-child(1) .child {
  width: 110px;
  height: 50px;
}

.background:nth-child(2) .child {
  width: 120px;
  height: 60px;
}

.background:nth-child(3) .child {
  width: 50px;
  height: 55px;
}

.background:nth-child(4) .child {
  width: 175px;
  height: 40px;
}
<div class="container">
    <div class="background"><div class="child"></div></div>
    <div class="background"><div class="child"></div></div>
    <div class="background"><div class="child"></div></div>
    <div class="background"><div class="child"></div></div>
</div>

新手来了!

我承认上面的输出不是你想要的,但这是我最好的尝试,使用 CSS 网格。在这里,您可以理解,如果我们想让它响应式,那么需要一个最小宽度,在此之后,列(内容)将被带到下一行,并且该宽度在此处定义(grid-template-columns: repeat(auto-fit, minmax(204px, max-content));)204px。但正因为如此,每列至少会占用这么多的宽度,这就是为什么我用蓝色背景表示一列的实际尺寸和边框内的实际内容。我只是将它发布为您的确认和方法,以便您可以更接近到实际答案。

顺带一提,Flex Approach-
根思想-随机COSMOS

.container {
  min-width: 130px;
  max-width: 340px;
  overflow: auto;
  background: #999;
  padding: 10px 40px;
  resize: horizontal;
  border: 1px solid #000;
}

.main-content {
  display: flex;
  flex-wrap: wrap;
  background: #fff;
  max-width: 340px;
  overflow: hidden;
}

.child {
  margin: 5px;
  padding: 5px;
  background: #99d9ea;
  border: 1px solid black;
}
<div class="container">
  <div class="main-content">
    <div class="child">Foofoofoo</div>
    <div class="child">Bar</div>
    <div class="child">BazBaz</div>
    <div class="child">QuuxQuuxQuux</div>
  </div>
</div>
Resize the window or the above div to see the results 

以上说明 div 居中,内容在左侧,但不根据内容调整大小。

我个人的看法——

你应该使用@media它来让它响应,就像你想要的那样,就像为一个简单的输出编写很多代码一样,但它可以通过你的努力和时间给你最好的和令人满意的结果!

如果你想让我让它响应你,请告诉我,我的意思是就像一个演示-

问候,
奥姆·乔杜里


推荐阅读