如何从单个无序列表中创建多列?

60

我想创建一个像这样的多列列表: https://jsfiddle.net/37dfwf4u/

如果为每列使用不同的列表,则没有问题:

<ul>
    <li>item1</li>
    <li>item2</li>
    <li>item3</li>
    <li>item4</li>
</ul>
<ul>
    <li>item5</li>
    <li>item6</li>
    <li>item7</li>
    <li>item8</li>
</ul>
ul {
    display:inline-block;
}

然而,是否可以通过连续列表和纯CSS来实现,以便CSS自动排列列?例如,使用我还不熟悉的flex布局?

3个回答

97

是的,您可以按照描述创建多列列表,只需将 ul 设为弹性容器,更改 flex-directioncolumn,应用 flex-wrap: wrap 允许它换行,并通过限制其 height 来进一步强制换行:

ul {
  height: 100px;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
}
<ul>
  <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>
  <li>item 16</li>
  <li>item 17</li>
  <li>item 18 </li>
  <li>item 19</li>
  <li>item 20</li>
  <li>item 21</li>
</ul>

这里是另一种可能性,是在@Andrew Koper的评论半年后添加的:

您还可以使用colummn-count参数,它不需要固定高度(也不需要flex),但定义了一个固定列数。因此,在下面的示例中,即使只有两个列表项,它们也会被分成两列,每列一个列表项:

ul {
  column-count: 2;
}
<ul>
  <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>
  <li>item 16</li>
  <li>item 17</li>
  <li>item 18 </li>
  <li>item 19</li>
  <li>item 20</li>
  <li>item 21</li>
</ul>


这似乎是一个不错的解决方案。完全自适应,无需定义列数,无需额外元素,只需一个连续列表。 - Sempervivum
顺便问一下:我该如何制作这样的内联演示(“运行代码片段”)? - Sempervivum
@Sempervivum 在问题和答案框中有不同的符号。如果你将鼠标悬停在它们上面,你会看到它们的意义。其中之一是用于创建代码片段。 - Johannes
感谢@Johannes,找到了这个解释并最终明白了:http://meta.stackoverflow.com/questions/269753/feedback-requested-runnable-code-snippets-in-questions-and-answers - Sempervivum
@AndrewKoper 我添加了另一种使用 column-count 的解决方案,这使得这种情况成为可能。然而,在这种情况下,您将始终获得相同数量的列。 - Johannes
显示剩余3条评论

23
考虑使用 CSS3 多列布局来实现:

CSS3 多列

您只需使用一个列表,并使用 CSS 定义列数。如果您在此处检查 CSS3 多列布局浏览器支持here,您会发现大多数浏览器仅支持部分功能,因为它们不支持 break-before、break-after 和 break-inside 属性。但是他们支持您需要创建带前缀的多列列表所需的属性。

.container {
  -webkit-column-count: 2; /* Chrome, Safari, Opera */
  -moz-column-count: 2; /* Firefox */
  column-count: 2;
}

ul {
  margin: 0;
}
<div class="container">
  <ul>
    <li>item1</li>
    <li>item2</li>
    <li>item3</li>
    <li>item4</li>
    <li>item5</li>
    <li>item6</li>
    <li>item7</li>
    <li>item8</li>
  </ul>
</div>


2
也是一个不错的解决方案。但是由于列数必须进行调整,因此它并不完全自适应。 - Sempervivum
6
实际上,对于那些需要添加或删除列表项的列表来说,这是一个更好的解决方案。你可以在响应式断点处设置列数并忘记它。使用第一个(被接受的)解决方案时,每次添加或删除列表项时,你都需要手动调整高度;而且很难确定哪种高度适合特定数量的项目:需要进行大量的试错。 - Ray
4
使用 column-width 代替 column-count 将会根据容器的宽度自动调整列数。 - jnnnnn

0
对于容器,使用display:flex和flex-wrap:wrap。给每个li元素添加一个类,例如container__item,然后为该类设置flex:0 0 50%(不增长、不缩小,宽度为50%)。

1
根据目前的写法,你的回答不够清晰。请编辑以添加更多细节,帮助其他人理解这如何回答所提出的问题。你可以在帮助中心找到关于如何撰写好回答的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接