具有列顺序的响应式多列列表
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-columns
和grid-template-rows
属性中的auto-fit
或auto-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-columns
和 grid-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以上是关于具有列顺序的响应式多列列表的主要内容,如果未能解决你的问题,请参考以下文章