具有列顺序的响应式多列列表

Posted

技术标签:

【中文标题】具有列顺序的响应式多列列表【英文标题】:Responsive multi-column list with column order 【发布时间】:2017-12-05 18:13:03 【问题描述】:

我正在尝试创建一个有序的多列列表,但在使用 CSS 网格布局规则时遇到了困难。

期望的结果应该是响应式的。在小屏幕上 2 个网格列,在大屏幕上最多 4 个,同时保持列顺序。

而不是像这样被订购:

1  2  3  4
5  6  7  8
9  10 11 12
13 14 15

它们的顺序应该是这样的:

1 5 9  13
2 6 10 14
3 7 11 15
4 8 12

我觉得我和this fiddle很亲近。

ol 
  margin: 0;
  padding: 0;
  list-style: none;
  background-color: grey;
  
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(33.333%, 50%));
  grid-auto-flow: column;
  grid-template-rows: repeat(5, 1em);


li 
  outline: 1px solid orange;
<ol>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
  <li>Item 9</li>
  <li>Item 10</li>
  <li>Item 11</li>
  <li>Item 12</li>
  <li>Item 13</li>
  <li>Item 14</li>
  <li>Item 15</li>
</ol>

特别是,我正在努力解决这些问题:

a) 需要grid-auto-flow: column 才能使列换行工作,但也迫使我添加grid-template-rows: repeat(5, 1em) 来指定行数,这会破坏响应能力。有没有办法根据内容和列数自动计算行数?

b) 为什么列宽不均匀分布,为什么不适应屏幕尺寸?这不是minmax 的用途吗?

【问题讨论】:

由于某种原因,使用grid-auto-flow: column 似乎破坏了行的自动填充机制。我设法做到这一点的唯一方法是使用媒体查询。 codepen.io/danield770/pen/JJLpgR/?editors=1100 - 但我想那是作弊:) 【参考方案1】:

调整列数以更改列数:)

ol 
  margin: 0;
  padding: 0;
  list-style: none;
  /*---*/
  column-count: 4;
  column-gap: 0;
  width: 100%;


li 
  background-color: grey;
  outline: 1px solid orange;
<ol>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
  <li>Item 9</li>
  <li>Item 10</li>
  <li>Item 11</li>
  <li>Item 12</li>
  <li>Item 13</li>
  <li>Item 14</li>
  <li>Item 15</li>
</ol>

【讨论】:

【参考方案2】:

让我们来看看你的两个症结所在。

    需要grid-auto-flow: column 才能使列换行起作用,但也迫使我添加grid-template-rows: repeat(5, 1em) 来指定行数,这会破坏响应能力。有没有办法根据内容和列数自动计算行数?

grid-auto-flow: column 使列换行工作。事实上,它的作用恰恰相反。该规则会创建新列以容纳其他网格项。

这是它的工作原理(来自规范):

7.7. Automatic Placement: the grid-auto-flow property

未明确放置的网格项目会自动放置到 网格容器中自动放置的未占用空间 算法。

grid-auto-flow 控制自动放置算法的工作方式, 准确指定自动放置的项目如何流入网格。

column

自动放置算法通过填充每一列来放置项目 转,根据需要添加新列。

row

自动放置算法通过依次填充每一行来放置项目,并根据需要添加新行。如果既没有提供row 也没有提供column,则假定为row

关于你的问题:

有没有办法根据内容和列数自动计算行数?

单独使用 CSS Grid,我不这么认为。正如规范中所说,grid-auto-flow 旨在在指定方向(column / row)添加新轨道。

如果它可以用 Grid 完成,那么它就不会是全自动的。您至少需要一些已定义的展示位置,而且我猜还需要媒体查询。

最后,关于列换行,它来自grid-template-columnsgrid-template-rows 属性中的auto-fitauto-fill 值。


    为什么列宽不均匀分布,为什么不适应屏幕大小?这不是minmax 的用途吗?

这又回到了上面突出显示的规范部分。

这是你的列大小代码:

grid-template-columns: repeat(auto-fill, minmax(33.333%, 50%));

这意味着:每个显式列的宽度必须最小为 33.333%,最大为 50%。

问题在于第三列不是显式。它是隐式的,因为它是在grid-auto-flow: column 的指导下通过自动放置算法添加到网格中的。所以本专栏不受grid-template-columns的约束,只处理explicit track sizing

implicit track sizing 的属性是 grid-auto-columnsgrid-auto-rows。它们的默认值为auto,这就是您在布局中看到的:第三列是其内容的宽度。

ol 
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(33.333%, 50%));
  grid-auto-flow: column;
  grid-template-rows: repeat(5, 1em);

  margin: 0;
  padding: 0;
  list-style: none;
  background-color: grey;


li 
  outline: 1px solid orange;
<ol>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
  <li>Item 9</li>
  <li>Item 10</li>
  <li>Item 11</li>
  <li>Item 12</li>
  <li>Item 13</li>
  <li>Item 14</li>
  <li>Item 15</li>
</ol>

一旦你设置了grid-auto-columns的值,第三列的大小就可以适当地调整了。

ol 
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(33.333%, 50%));
  grid-auto-flow: column;
  grid-template-rows: repeat(5, 1em);
  grid-auto-columns: 33.333%; /* NEW */

  margin: 0;
  padding: 0;
  list-style: none;
  background-color: grey;


li 
  outline: 1px solid orange;
<ol>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
  <li>Item 9</li>
  <li>Item 10</li>
  <li>Item 11</li>
  <li>Item 12</li>
  <li>Item 13</li>
  <li>Item 14</li>
  <li>Item 15</li>
</ol>

当然,上面的信息只是一个解释,而不是主要问题的解决方案,因为我不相信 CSS Grid 提供了一个。

【讨论】:

特别注意,auto-fill 将使用 max 大小来计算要创建的轨道数量(如果可能)。在这种情况下, 50% 与之兼容,因此它将构成两列。 (从来没有理由使用百分比自动填充,因为您只需通过简单的除法就可以知道有多少列适合。) 感谢您的澄清。是的,我注意到minmax() 在轨道大小计算中使用了 max。此处探讨了该问题:minmax() defaulting to max。感谢posting an explanation。 @Xanthir 另外,关于这篇文章中的问题,这里有更详细的探讨:Make grid container fill columns not rows。事实上,如果 Grid 有一种方法可以在填充所有垂直空间后自动添加列(如 CSS 列),您可能想在此处提及它。 @Xanthir

以上是关于具有列顺序的响应式多列列表的主要内容,如果未能解决你的问题,请参考以下文章

bootstrap 3 多列响应式轮播

具有等高卡片的 Bootstrap 4 响应式卡片列

3 列响应式 CSS(排序内容位置)

如何使用 Bootstrap 在响应式视图中拆分列?

如何处理具有垂直节奏的响应式图像?

如何只将一个表列转换为响应式