Как отобразить неупорядоченный список в двух столбцах?

216

С помощью следующего 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.

atp03
источник
1
Вот живой пример того, как легко это сделать в jquery: jsfiddle.net/EebVF/5 Использование этого плагина jquery: github.com/fzondlo/jquery-columns - мне это нравится больше, чем с CSS, потому что с решением CSS не все выравнивается вертикально к вершине.
newUserNameHere

Ответы:

372

Современные браузеры

использовать модуль столбцов 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

в то время как ОП запросил вариант, соответствующий следующему:

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;
    });
}
Габриель
источник
2
Вы не отображаете элементы в правильном порядке: jsfiddle.net/HP85j/258 Например, желаемое отображение в первой строке A B(второй элемент должен быть добавлен справа), но в ваших примерах это A E.
Паоло Моретти
1
Отличная работа, хотя логика имеет недостатки, если имеется более 2 столбцов, я создал исправление здесь: jsfiddle.net/HP85j/393
Tr1stan
2
пули отсутствуют
Jaider
1
Вероятно, более вероятно, что список должен заполнить столбец 1 перед столбцом 2. Возможно, будет проще просто переупорядочить элементы списка, чтобы они казались заполненными раньше. Конечно, это может потребовать повторения, если список изменится. В любом случае, ответ Габриэля на CSS был именно тем, что мне было нужно, спасибо!
Качалка
3
Я считаю, что только позднее обновление первого варианта будет работать в современных браузерах IE.
Fizz
83

Я искал решение @ 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, поскольку ваш ответ помог мне разобраться в этом.

Уиннифред
источник
3
Есть проблема с этим методом. Он отлично подходит для отображения очень коротких (в данном примере 1 символа) элементов списка. Создайте список с более длинными описаниями, и второй столбец перекрывает первый, а также исчерпывает контейнер ul.
Лохматый
1
Я немного подправил это, изменив float: left для отображения: inline-block для элементов li, кроме того, что для меня это творит чудеса.
ZeRemz
41

Я попытался опубликовать это как комментарий, но не смог правильно отобразить столбцы (согласно вашему вопросу).

Вы просите:

AB

CD

Е

... но ответ, принятый в качестве решения, вернется:

ОБЪЯВЛЕНИЕ

БЫТЬ

С

... так что либо ответ неправильный, либо вопрос.

Очень простое решение было бы установить ширину вашего, <ul>а затем плавать и установить ширину ваших <li>предметов, как так

<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).

Jayx
источник
@ Габриэль ваше решение и поведение хорошее и, как и ожидалось, поэтому я не пытаюсь опровергнуть ваш ответ, эй ... Я просто думаю, что вопрос мог быть неверно истолкован ... в любом случае - на вопрос был дан ответ независимо от того, это правильный вопрос: D
Jayx
16

Мне нравится решение для современных браузеров, но маркеры отсутствуют, поэтому я добавлю его в небольшую хитрость:

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

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


li:before {
  content: "• ";
}

введите описание изображения здесь

Jaider
источник
Здесь мы можем изменить цвет предметов без изменения цвета пули jsfiddle.net/HP85j/444
Jaider
3
Я думаю, что list-style-position: inside;это лучшее решение для отображения пуль.
Алексис Уилк
11

Вот возможное решение:

Отрывок:

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

Это самый простой способ сделать это. Только CSS

  1. добавить ширину к элементу ul.
  2. добавить отображение: 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>
Авив Шаал
источник
2
Добавьте некоторое объяснение с ответом о том, как этот ответ помогает ОП в исправлении текущей проблемы
ρяσѕρєя K
4

Вы можете использовать CSS только для установки двух или более столбцов

AE

В

С

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;
 }
Бухейба Зиед
источник
3

Это может быть достигнуто с помощью свойства css столбца в родительском div,

лайк

 column-count:2;

проверьте это для более подробной информации.

Как заставить плавающий список DIV появляться в столбцах, а не в строках

максимус ツ
источник
1
column-countне будет отображать элементы в правильном порядке. Например, желаемое отображение в первой строке A B(второй элемент должен быть добавлен справа), но если вы используете column-countего, он будет A E.
Паоло Моретти
2

Вы можете сделать это очень легко с помощью плагина jQuery-Columns, например, чтобы разделить ul с классом .mylist, который вы бы сделали

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

Вот живой пример на jsfiddle

Мне это нравится больше, чем с CSS, потому что с решением CSS не все выравнивается вертикально вверх.

newUserNameHere
источник
Интересно, но на самом деле он разбивает <ul>список на несколько списков ... Это может усложнить другие вещи.
Алексис Вилке
Это было на самом деле решение, которое я получил после того, как спасибо, даунвотеру, этот ответ действителен, если вы прочитали вопрос ОП и не было необходимости в DV.
Хитрый
2

еще один ответ через несколько лет!

в этой статье: 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%; }
user3632930
источник
1

При updateColumns()необходимости, if (column >= columns.length)вместо того, if (column > 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/

Daver
источник
1

Устаревшее решение в верхнем ответе не сработало для меня, потому что я хотел повлиять на несколько списков на странице, и ответ предполагает один список, плюс он использует довольно много глобального состояния. В этом случае я хотел изменить каждый список внутри <section class="list-content">:

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]);
    }
});
Том
источник
как, например, можно сгенерировать два столбца, один из которых содержит только плитку, а другой - неупорядоченный список?
Далек
Не совсем уверен, что вы имеете в виду. Если у вас есть ряд элементов с заголовками, вы можете поместить их в единый список в виде заголовка, элемента, заголовка, элемента, и тогда это должно работать для вас.
Том
1

Хотя я нашел ответ Габриэля на работу до такой степени, я обнаружил следующее при попытке упорядочить список по вертикали (первый ul AD и второй ul EG):

  • Когда в ul было четное количество li, оно не распределялось равномерно по ul
  • использование столбца данных в ul, похоже, не очень хорошо работало, мне пришлось поставить 4 для 3 столбцов, и даже тогда он все еще только распространял li на 2 ul, сгенерированные JS

Я пересмотрел 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>
Энтони Медхерст
источник
-1

Это было идеальное решение для меня, смотреть его годами:

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

ROK
источник
3
«Всегда указывайте наиболее релевантную часть важной ссылки, если целевой сайт недоступен или постоянно недоступен» - stackoverflow.com/help/how-to-answer
Sk8erPeter
Нет необходимости - это ссылка / ссылка на код, использованный Abdulв его ответе, идентичный даже ширине и идентификатору.
cssyphus