【问题标题】:How to display an unordered list in two columns?如何在两列中显示无序列表?
【发布时间】:2021-10-16 00:26:26
【问题描述】:

对于以下 HTML,将列表显示为两列的最简单方法是什么?

<ul>
    <li>A</li>
    <li>B</li>
    <li>C</li>
    <li>D</li>
    <li>E</li>
</ul>

想要的显示:

A B
C D
E

该解决方案需要与 Internet Explorer 配合使用。

【问题讨论】:

  • 这是一个如何在 jquery 中轻松完成的活生生的例子:jsfiddle.net/EebVF/5 使用这个 jquery 插件:github.com/fzondlo/jquery-columns - 我更喜欢这个而不是 CSS因为使用 CSS 解决方案并非所有内容都与顶部垂直对齐。

标签: html css html-lists css-multicolumn-layout


【解决方案1】:

现代浏览器

利用 css3 列模块来支持您正在寻找的内容。

http://www.w3schools.com/cssref/css3_pr_columns.asp

CSS:

ul {
  columns: 2;
  -webkit-columns: 2;
  -moz-columns: 2;
}

http://jsfiddle.net/HP85j/8/

旧版浏览器

不幸的是,对于 IE 支持,您需要一个涉及 JavaScript 和 dom 操作的代码解决方案。这意味着,只要列表的内容发生更改,您就需要执行将列表重新排序为列并重新打印的操作。为了简洁起见,下面的解决方案使用 jQuery。

http://jsfiddle.net/HP85j/19/

HTML:

<div>
    <ul class="columns" data-columns="2">
        <li>A</li>
        <li>B</li>
        <li>C</li>
        <li>D</li>
        <li>E</li>
        <li>F</li>
        <li>G</li>
    </ul>
</div>

JavaScript:

(function($){
    var initialContainer = $('.columns'),
        columnItems = $('.columns li'),
        columns = null,
        column = 1; // account for initial column
    function updateColumns(){
        column = 0;
        columnItems.each(function(idx, el){
            if (idx !== 0 && idx > (columnItems.length / columns.length) + (column * idx)){
                column += 1;
            }
            $(columns.get(column)).append(el);
        });
    }
    function setupColumns(){
        columnItems.detach();
        while (column++ < initialContainer.data('columns')){
            initialContainer.clone().insertBefore(initialContainer);
            column++;
        }
        columns = $('.columns');
    }

    $(function(){
        setupColumns();
        updateColumns();
    });
})(jQuery);

CSS:

.columns{
    float: left;
    position: relative;
    margin-right: 20px;
}

编辑:

如下所述,这将按如下方式对列进行排序:

A  E
B  F
C  G
D

当 OP 要求匹配以下变体时:

A  B
C  D
E  F
G

要完成变体,您只需将代码更改为以下内容:

function updateColumns(){
    column = 0;
    columnItems.each(function(idx, el){
        if (column > columns.length){
            column = 0;
        }
        $(columns.get(column)).append(el);
        column += 1;
    });
}

【讨论】:

  • 您没有以正确的顺序显示项目:jsfiddle.net/HP85j/258 例如,第一行中所需的显示是A B(第二个元素应该附加在右侧),但是在你的例子中是A E
  • 干得好,虽然如果有超过 2 列,逻辑有缺陷,我在这里创建了修复:jsfiddle.net/HP85j/393
  • 子弹不见了
  • 它可能更可能希望列表在第 2 列之前填充第 1 列。简单地重新排序列表中的项目可能更容易,以便看起来它们在向下之前填充。当然,如果列表发生变化,这可能需要重做。无论如何,Gabriel 的 CSS 答案正是我所需要的,谢谢!
  • 只是一个较晚的更新,我相信第一个选项现在可以在现代 IE 浏览器中使用。
【解决方案2】:

我正在查看 @jaider 的解决方案,该解决方案有效,但我提供了一种稍微不同的方法,我认为它更易于使用,并且我认为它在浏览器中表现良好。

ul{
    list-style-type: disc;
    -webkit-columns: 2;
    -moz-columns: 2;
    columns: 2;
    list-style-position: inside;//this is important addition
}

默认情况下,无序列表将项目符号位置显示在外面,但在某些浏览器中,它会根据浏览器的网站布局方式导致一些显示问题。

要让它以以下格式显示:

A B
C D
E

等等。使用以下内容:

ul li{
    float: left;
    width: 50%;//helps to determine number of columns, for instance 33.3% displays 3 columns
}
ul{
    list-style-type: disc;
}

这应该可以解决您显示列的所有问题。一切顺利,感谢@jaider,您的回复帮助我发现了这一点。

【讨论】:

  • 这个方法有问题。它非常适合显示非常短的(本例中为 1 个字符)列表项。创建一个具有较长描述的列表,第二列与第一列重叠,并且超出 ul 容器。
  • 我通过将 float: left 更改为 display: inline-block for li 元素稍微调整了这一点,除此之外,这对我来说是个奇迹。
【解决方案3】:

我尝试将此作为评论发布,但无法正确显示列(根据您的问题)。

你要求:

甲乙

C D

E

...但作为解决方案接受的答案将返回:

A D

B E

C

...所以要么答案不正确,要么问题是。

一个非常简单的解决方案是设置&lt;ul&gt; 的宽度,然后像这样浮动并设置&lt;li&gt; 项目的宽度

<ul>
    <li>A</li>
    <li>B</li>
    <li>C</li>
    <li>D</li>
    <li>E</li>
</ul>

ul{
    width:210px;
}
li{
    background:green;
    float:left;
    height:100px;
    margin:0 10px 10px 0;
    width:100px;
}
li:nth-child(even){
    margin-right:0;
}

这里的例子http://jsfiddle.net/Jayx/Qbz9S/1/

如果您的问题是错误的,那么前面的答案适用(通过 JS 修复缺少 IE 支持)。

【讨论】:

  • @Gabriel 你的解决方案和行为是好的和预期的那样,所以我不想敲你的答案嘿......我只是认为这个问题可能被误解了......无论哪种方式- 无论哪个是正确的问题,问题都已得到回答:D
【解决方案4】:

我喜欢现代浏览器的解决方案,但是缺少项目符号,所以我添加了一个小技巧:

http://jsfiddle.net/HP85j/419/

ul {
    list-style-type: none;
    columns: 2;
    -webkit-columns: 2;
    -moz-columns: 2;
}


li:before {
  content: "• ";
}

【讨论】:

  • 这里我们可以改变项目的颜色而不改变子弹的颜色jsfiddle.net/HP85j/444
  • 我认为list-style-position: inside; 是让子弹正确显示的更好解决方案。
【解决方案5】:

这是一个可能的解决方案:

片段:

ul {
  width: 760px;
  margin-bottom: 20px;
  overflow: hidden;
  border-top: 1px solid #ccc;
}
li {
  line-height: 1.5em;
  border-bottom: 1px solid #ccc;
  float: left;
  display: inline;
}
#double li {
  width: 50%;
}
<ul id="double">
  <li>first</li>
  <li>second</li>
  <li>third</li>
  <li>fourth</li>
</ul>

它已经完成了。
3 列使用 li 宽度为 33%,4 列使用 25%,依此类推。

【讨论】:

    【解决方案6】:

    现在,对于预期的结果,display:grid; 会这样做(是最简单的?)

    ul {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
    }
    <ul>
      <li>A</li>
      <li>B</li>
      <li>C</li>
      <li>D</li>
      <li>E</li>
    </ul>

    您还可以让列在左侧缩小并且能够具有不同的宽度:

    ul {
      display: grid;
      grid-template-columns: repeat(2, auto);
      justify-content: start;
    }
    
    li {
      margin-left: 1em;
      border: solid 1px;/*see me */
    }
    <ul>
      <li>A</li>
      <li>B</li>
      <li>C 123456</li>
      <li>D</li>
      <li>E</li>
    </ul>

    【讨论】:

    • 谢谢!这比接受的答案更好,因为它使列中的元素在高度上匹配
    【解决方案7】:

    这是最简单的方法。仅限 CSS。

    1. 为 ul 元素添加宽度。
    2. 添加 display:inline-block 和新列的宽度(应小于 ul 宽度的一半)。
    ul.list {
      width: 300px;  
    }
    
    ul.list li{
      display:inline-block;
      width: 100px;
    }
    <ul class="list">
        <li>A</li>
        <li>B</li>
        <li>C</li>
        <li>D</li>
        <li>E</li>
    </ul>

    【讨论】:

    • 添加一些解释,说明此答案如何帮助 OP 解决当前问题
    【解决方案8】:

    您可以使用 CSS only 设置两列或更多列

    A E

    C

    D

     <ul class="columns">
        <li>A</li>
        <li>B</li>
        <li>C</li>
        <li>D</li>
        <li>E</li>
    </ul>
    
    ul.columns  {
       -webkit-columns: 60px 2;
       -moz-columns: 60px 2;
        columns: 60px 2;
       -moz-column-fill: auto;
       column-fill: auto;
     }
    

    【讨论】:

      【解决方案9】:

      这可以使用父 div 上的 column-count css 属性来实现,

      喜欢

       column-count:2;
      

      查看这里了解更多详情。

      How to make floating DIV list appear in columns, not rows

      【讨论】:

      • column-count 不会以正确的顺序显示项目。例如,第一行中想要的显示是A B(第二个元素应该附加在右边),但如果你使用column-count,它将是A E
      【解决方案10】:

      您可以使用jQuery-Columns Plugin 非常轻松地做到这一点,例如将 ul 与您会做的 .mylist 类分开

      $('.mylist').cols(2);
      

      这是live example on jsfiddle

      我比使用 CSS 更喜欢这个,因为使用 CSS 解决方案并非所有内容都垂直对齐到顶部。

      【讨论】:

      • 有趣,但它实际上将&lt;ul&gt; 列表分解为多个列表...这可能会使其他事情复杂化。
      • 这实际上是我在感谢之后的解决方案,如果你阅读了 OP 的问题并且不需要 DV,那么这个答案是有效的。
      【解决方案11】:

      几年后还有一个答案!

      在这篇文章中:http://csswizardry.com/2010/02/mutiple-column-lists-using-one-ul/

      HTML:

      <ul id="double"> <!-- Alter ID accordingly -->
        <li>CSS</li>
        <li>XHTML</li>
        <li>Semantics</li>
        <li>Accessibility</li>
        <li>Usability</li>
        <li>Web Standards</li>
        <li>PHP</li>
        <li>Typography</li>
        <li>Grids</li>
        <li>CSS3</li>
        <li>HTML5</li>
        <li>UI</li>
      </ul>
      

      CSS:

      ul{
        width:760px;
        margin-bottom:20px;
        overflow:hidden;
        border-top:1px solid #ccc;
      }
      li{
        line-height:1.5em;
        border-bottom:1px solid #ccc;
        float:left;
        display:inline;
      }
      #double li  { width:50%;}
      #triple li  { width:33.333%; }
      #quad li    { width:25%; }
      #six li     { width:16.666%; }
      

      【讨论】:

        【解决方案12】:

        updateColumns() 中需要if (column &gt;= columns.length) 而不是if (column &gt; columns.length) 列出所有元素(例如跳过C)所以:

        function updateColumns(){
            column = 0;
            columnItems.each(function(idx, el){
                if (column >= columns.length){
                    column = 0;
                }
                console.log(column, el, idx);
                $(columns.get(column)).append(el);
                column += 1;
            });
        }
        

        http://jsfiddle.net/e2vH9/1/

        【讨论】:

          【解决方案13】:

          使用 Bootstrap... 这个答案 (https://stackoverflow.com/a/23005046/1128742) 让我指出了这个解决方案:

          <ul class="list-unstyled row">
             <li class="col-xs-6">Item 1</li>
             <li class="col-xs-6">Item 2</li>
             <li class="col-xs-6">Item 3</li>
          </ul>
          

          http://jsfiddle.net/patrickbad767/472r0ynf/

          【讨论】:

            【解决方案14】:

            最佳答案中的旧版解决方案对我不起作用,因为我想影响页面上的多个列表,并且答案假设一个列表加上它使用了相当多的全局状态。在这种情况下,我想更改 &lt;section class="list-content"&gt; 中的每个列表:

            const columns = 2;
            $("section.list-content").each(function (index, element) {
                let section = $(element);
                let items = section.find("ul li").detach();
                section.find("ul").detach();
                for (let i = 0; i < columns; i++) {
                    section.append("<ul></ul>");
                }
                let lists = section.find("ul");
                for (let i = 0; i < items.length; i++) {
                    lists.get(i % columns).append(items[i]);
                }
            });
            

            【讨论】:

            • 如何生成两列,一列只包含磁贴,另一列是无序列表?
            • 不太清楚你的意思。如果您有一系列带有标题的项目,您可以将它们放在一个单独的列表中,标题、项目、标题、项目,然后这应该适合您。
            【解决方案15】:

            虽然我发现 Gabriel 的回答在一定程度上起作用,但在尝试垂直排序列表时确实发现了以下内容(第一个 ul A-D 和第二个 ul E-G):

            • 当 ul 中有偶数个 li 时,它不会均匀地分布在 ul 中
            • 在 ul 中使用 data-column 似乎效果不佳,我不得不将 4 列放入 3 列中,即使这样它仍然只是将 li 传播到 JS 生成的 ul 的 2 中

            我已经修改了 JQuery,所以希望上述情况不会发生。

            (function ($) {
                var initialContainer = $('.customcolumns'),
                    columnItems = $('.customcolumns li'),
                    columns = null,
                    column = 0;
                function updateColumns() {
                    column = 0;
                    columnItems.each(function (idx, el) {
                        if ($(columns.get(column)).find('li').length >= (columnItems.length / initialContainer.data('columns'))) {
                            column += 1;
                        }
                        $(columns.get(column)).append(el);
                    });
                }
                function setupColumns() {
                    columnItems.detach();
                    while (column++ < initialContainer.data('columns')) {
                        initialContainer.clone().insertBefore(initialContainer);
                        column++;
                    }
                    columns = $('.customcolumns');
                    updateColumns();
                }
            
                $(setupColumns);
            })(jQuery);
            
            .customcolumns {
              float: left;
              position: relative;
              margin-right: 20px;
            }
            
            <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
            <div>
              <ul class="customcolumns" data-columns="3">
                <li>A</li>
                <li>B</li>
                <li>C</li>
                <li>D</li>
                <li>E</li>
                <li>F</li>
                <li>G</li>
                <li>H</li>
                <li>I</li>
                <li>J</li>
                <li>K</li>
                <li>L</li>
                <li>M</li>
              </ul>
            </div>
            

            【讨论】:

              【解决方案16】:

              这对我有用。 是最好的解决方案,因为一行中的单元格具有相同的高度而不考虑内容

              ul {
                display: grid;
                grid-template-columns: repeat(2, 1fr); 
                list-style-position: inside;
                list-style-type: none;
              }
              li {  border: solid 1px; }
              <ul>
                <li>asdasd asdad asdasd asdasd adasdasdasd adasdadadada adadas dasdadasdasd asd aA</li>
                <li>B</li>
                <li>C</li>
                <li>D</li>
                <li>E</li>
              </ul>

              【讨论】:

                【解决方案17】:

                这是一种使用简单 CSS 制作多列列表的简单方法。如果需要,样式标签显然可以放入 CSS 中。

                <p>Materials List</p>
                <ul style="display: inline-block; float: left">
                    <u>Item Description<u>
                    <li>1/2" x 4' wood dowel</li>
                    <li>1/2" x 12"  PVC pipe</li>
                    <li>1/2" PVC pipe end cap</li>
                    <li>7/16" x 3" light duty expansion spring</li>
                    <li>6" plastic zip ties</li>
                    <li>Light weight antenna</li>
                </ul>
                <div style="display: inline-block; margin-left: 1em">
                    <u>Qty</u>
                    <div style="text-indent: 0.5em">3</div>
                    <div style="text-indent: 0.5em">1</div>
                    <div style="text-indent: 0.5em">1</div>
                    <div style="text-indent: 0.5em">2</div>
                    <div style="text-indent: 0.5em">8</div>
                    <div style="text-indent: 0.5em">1</div>
                </div>
                <p></p>
                

                【讨论】:

                  【解决方案18】:

                  Thisd 对我来说是一个完美的解决方案,多年来一直在寻找它:

                  http://css-tricks.com/forums/topic/two-column-unordered-list/

                  【讨论】:

                  • “始终引用重要链接中最相关的部分,以防目标站点无法访问或永久离线” - stackoverflow.com/help/how-to-answer
                  • 不需要 - 这是Abdul 在他的回答中使用的代码的链接/参考,甚至与使用的宽度和 ID 相同。
                  猜你喜欢
                  • 2018-06-27
                  • 2017-11-28
                  • 2017-03-07
                  • 2022-01-08
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-10-30
                  相关资源
                  最近更新 更多