【问题标题】: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 - 但我想那是作弊:)

标签: css css-grid


【解决方案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】:

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

    1. 需要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 值。


    1. 为什么列宽不均匀分布,为什么不适应屏幕大小?这不是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
    猜你喜欢
    • 1970-01-01
    • 2020-02-09
    • 1970-01-01
    • 2018-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    • 1970-01-01
    相关资源
    最近更新 更多