Jak wyświetlić nieuporządkowaną listę w dwóch kolumnach?

215

W przypadku poniższego kodu HTML jaka jest najłatwiejsza metoda wyświetlenia listy jako dwóch kolumn?

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

Żądany wyświetlacz:

A B
C D
E

Rozwiązanie musi działać w przeglądarce Internet Explorer.

atp03
źródło
1
Oto żywy przykład, jak łatwo to zrobić w jquery: jsfiddle.net/EebVF/5 Korzystanie z tej wtyczki jquery: github.com/fzondlo/jquery-columns - Podoba mi się to lepiej niż w przypadku CSS, ponieważ w przypadku rozwiązania CSS nie wszystko się zgadza pionowo do góry.
newUserNameHere

Odpowiedzi:

371

Nowoczesne przeglądarki

wykorzystaj moduł kolumn css3, aby wesprzeć to, czego szukasz.

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

CSS:

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

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

Starsze przeglądarki

Niestety do obsługi IE potrzebujesz rozwiązania w postaci kodu, które wymaga JavaScript i manipulacji domem. Oznacza to, że za każdym razem, gdy zmienia się zawartość listy, będziesz musiał wykonać operację zmiany kolejności listy na kolumny i przedruku. Poniższe rozwiązanie używa jQuery dla zwięzłości.

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;
}

EDYTOWAĆ:

Jak wskazano poniżej, uporządkuje kolumny w następujący sposób:

A  E
B  F
C  G
D

podczas gdy OP poprosił o wariant pasujący do następującego:

A  B
C  D
E  F
G

Aby zrealizować wariant, wystarczy zmienić kod na następujący:

function updateColumns(){
    column = 0;
    columnItems.each(function(idx, el){
        if (column > columns.length){
            column = 0;
        }
        $(columns.get(column)).append(el);
        column += 1;
    });
}
Gabriel
źródło
2
Nie wyświetlasz elementów we właściwej kolejności: jsfiddle.net/HP85j/258 Na przykład pożądanym wyświetleniem w pierwszym wierszu jest A B(drugi element powinien być dołączony po prawej stronie), ale w twoich przykładach jest A E.
Paolo Moretti
1
Świetna robota, chociaż logika jest błędna, jeśli są więcej niż 2 kolumny, stworzyłem poprawkę tutaj: jsfiddle.net/HP85j/393
Tr1stan
2
brakuje kul
Jaider
1
Prawdopodobnie bardziej prawdopodobne jest, że lista będzie wypełniać kolumnę 1 przed kolumną 2. Może być łatwiej po prostu zmienić kolejność elementów listy, aby wyglądało na to, że wypełniły się przed nią. Oczywiście może to wymagać ponownego wykonania, jeśli lista się zmieni. W każdym razie odpowiedź CSS Gabriela była właśnie tym, czego potrzebowałem, dziękuję!
punstress
3
Tylko późna aktualizacja, uważam, że pierwsza opcja będzie teraz działać w nowoczesnych przeglądarkach IE.
Fizz,
82

Patrzyłem na rozwiązanie @ jaider, które działało, ale oferuję nieco inne podejście, które moim zdaniem jest łatwiejsze w obsłudze i które uważałem za dobre w różnych przeglądarkach.

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

Domyślnie nieporządkowana lista wyświetla pozycję pocisku na zewnątrz, ale w niektórych przeglądarkach powodowałaby pewne problemy z wyświetlaniem w zależności od sposobu rozmieszczenia witryny przez przeglądarkę.

Aby wyświetlić go w formacie:

A B
C D
E

itp. użyj następujących czynności:

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

To powinno rozwiązać wszystkie problemy z wyświetlaniem kolumn. Wszystkiego najlepszego i dziękuję @jaider, ponieważ Twoja odpowiedź pomogła mi to odkryć.

Winnifred
źródło
3
Wystąpił problem z tą metodą. Działa doskonale do wyświetlania bardzo krótkich (1 znak w tym przykładzie) elementów listy. Utwórz listę z dłuższymi opisami, a druga kolumna nachodzi na pierwszą, a także zabraknie kontenera ul.
Shaggy
1
Poprawiłem to nieco, zmieniając float: left to display: inline-block dla elementów li, poza tym działało to dla mnie cuda.
ZeRemz
41

Próbowałem opublikować to jako komentarz, ale nie udało mi się poprawnie wyświetlić kolumn (zgodnie z pytaniem).

Pytasz o:

AB

Płyta CD

mi

... ale odpowiedź zaakceptowana jako rozwiązanie zwróci:

OGŁOSZENIE

BYĆ

do

... więc albo odpowiedź jest nieprawidłowa, albo pytanie brzmi.

Bardzo prostym rozwiązaniem byłoby ustawienie szerokości, <ul>a następnie przesunięcie i ustawienie szerokości <li>przedmiotów w ten sposób

<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;
}

Przykład tutaj http://jsfiddle.net/Jayx/Qbz9S/1/

Jeśli twoje pytanie jest błędne, zastosowanie mają poprzednie odpowiedzi (z poprawką JS na brak obsługi IE).

Jayx
źródło
@ Gabriel twoje rozwiązanie, a zachowanie jest dobre i zgodne z oczekiwaniami, więc nie próbuję obalić twojej odpowiedzi hej ... Po prostu myślę, że pytanie mogło zostać źle zinterpretowane ... tak czy inaczej - odpowiedź na pytanie bez względu na to które jest prawidłowe pytanie: D
Jayx
16

Podoba mi się rozwiązanie dla nowoczesnych przeglądarek, ale brakuje pocisków, więc dodaję małą sztuczkę:

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

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


li:before {
  content: "• ";
}

wprowadź opis zdjęcia tutaj

Jaider
źródło
Tutaj możemy zmienić kolor przedmiotów bez zmiany koloru pocisku jsfiddle.net/HP85j/444
Jaider
3
Myślę, że list-style-position: inside;jest lepszym rozwiązaniem, aby pociski prawidłowo się wyświetlały.
Alexis Wilke,
11

Oto możliwe rozwiązanie:

Skrawek:

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>

I gotowe.
Dla 3 kolumn użyj liszerokości jako 33%, dla 4 kolumn użyj 25% i tak dalej.

Abdul
źródło
5

To najprostszy sposób na zrobienie tego. Tylko CSS.

  1. dodaj szerokość do elementu ul.
  2. dodaj display: blok wstawiany i szerokość nowej kolumny (powinna być mniejsza niż połowa szerokości 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>
Aviv Shaal
źródło
2
Dodaj wyjaśnienie z odpowiedzią na pytanie, w jaki sposób ta odpowiedź pomaga OP w rozwiązaniu bieżącego problemu
ρяσсρєя K
4

Możesz użyć CSS tylko do ustawienia dwóch lub więcej kolumn

AE

b

do

re

 <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;
 }
Bouhejba zied
źródło
3

Można to osiągnąć za pomocą właściwości css zliczania kolumn na div div,

lubić

 column-count:2;

sprawdź to, aby uzyskać więcej informacji.

Jak sprawić, by pływająca lista DIV była wyświetlana w kolumnach, a nie w wierszach

maximus ツ
źródło
1
column-countnie wyświetli elementów we właściwej kolejności. Na przykład pożądanym wyświetlaniem w pierwszym wierszu jest A B(drugi element powinien być dołączony po prawej stronie), ale jeśli column-countgo użyjesz, to będzie A E.
Paolo Moretti
2

Możesz to zrobić naprawdę łatwo za pomocą wtyczki jQuery-Columns, na przykład, aby podzielić ul z klasą .mylist, którą zrobiłbyś

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

Oto przykład na żywo na jsfiddle

Podoba mi się to lepiej niż w CSS, ponieważ w rozwiązaniu CSS nie wszystko wyrównuje się pionowo do góry.

newUserNameHere
źródło
Ciekawe, ale tak naprawdę rozkłada <ul>listę na wiele list ... To może skomplikować inne rzeczy.
Alexis Wilke,
To było właściwie rozwiązanie, za którym chciałem podziękować, dla downvoter'a ta odpowiedź jest poprawna, jeśli przeczytałeś pytanie OP i nie było potrzeby DV.
Tricky
2

jeszcze jedna odpowiedź po kilku latach!

w tym artykule: 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%; }
użytkownik3632930
źródło
1

Na updateColumns()potrzeby if (column >= columns.length)zamiast if (column > columns.length)wymienienie wszystkich elementów (C jest pominięty, na przykład), wię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
źródło
1

Starsze rozwiązanie w górnej odpowiedzi nie działało dla mnie, ponieważ chciałem wpłynąć na wiele list na stronie, a odpowiedź zakłada jedną listę i wykorzystuje całkiem sporo stanu globalnego. W tym przypadku chciałem zmienić każdą listę w <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]);
    }
});
Tomek
źródło
jak można na przykład wygenerować dwie kolumny, jedna zawiera tylko kafelek, a druga nieuporządkowaną listę?
Dalek,
Nie jestem pewien, co masz na myśli. Jeśli masz serię elementów z tytułami, możesz umieścić je na pojedynczej liście, przechodząc do tytułu, elementu, tytułu, elementu, a wtedy powinno to działać.
Tom
1

Chociaż znalazłem odpowiedź Gabriela do pracy w pewnym stopniu, znalazłem następujące przy próbie uporządkowania listy w pionie (pierwsza ul AD i druga ul EG):

  • Kiedy ul zawierał parzystą liczbę li, nie rozkładał go równomiernie na ul
  • użycie kolumny danych w ul nie wydawało się działać zbyt dobrze, musiałem umieścić 4 na 3 kolumny, a nawet wtedy to tylko rozkładało li do 2 ul wygenerowanych przez JS

Poprawiłem JQuery, więc mam nadzieję, że powyższe nie nastąpi.

(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>
Anthony Medhurst
źródło