Come visualizzare un elenco non ordinato in due colonne?


216

Con il seguente HTML, qual è il metodo più semplice per visualizzare l'elenco come due colonne?

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

Display desiderato:

A B
C D
E

La soluzione deve poter funzionare su Internet Explorer.


1
Ecco un esempio dal vivo di come farlo facilmente in jquery: jsfiddle.net/EebVF/5 Usando questo plugin jquery: github.com/fzondlo/jquery-columns - Mi piace di più che con i CSS perché con la soluzione CSS non tutto si allinea verticalmente verso l'alto.
newUserNameHere

Risposte:


372

Browser moderni

sfruttare il modulo colonne css3 per supportare ciò che stai cercando.

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

CSS:

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

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

Browser legacy

Sfortunatamente per il supporto di IE avrai bisogno di una soluzione di codice che preveda la manipolazione di JavaScript e dom. Ciò significa che ogni volta che il contenuto dell'elenco cambia, sarà necessario eseguire l'operazione per riordinare l'elenco in colonne e ristampare. La soluzione seguente utilizza jQuery per brevità.

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

MODIFICARE:

Come indicato di seguito, le colonne verranno ordinate come segue:

A  E
B  F
C  G
D

mentre l'OP ha richiesto una variante corrispondente a quanto segue:

A  B
C  D
E  F
G

Per realizzare la variante è sufficiente modificare il codice nel modo seguente:

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

2
Non stai visualizzando gli articoli nell'ordine corretto: jsfiddle.net/HP85j/258 Ad esempio, la visualizzazione desiderata nella prima riga è A B(il secondo elemento dovrebbe essere aggiunto a destra), ma nei tuoi esempi è A E.
Paolo Moretti,

1
Ottimo lavoro, sebbene la logica sia imperfetta se ci sono più di 2 colonne, ho creato la correzione qui: jsfiddle.net/HP85j/393
Tr1stan,

2
mancano i proiettili
Jaider,

1
Probabilmente è più probabile che si desideri che l'elenco riempia la colonna 1 prima della colonna 2. Potrebbe essere più semplice semplicemente riordinare gli elementi dell'elenco in modo che appaiano riempiti prima. Naturalmente ciò può richiedere la ripetizione se l'elenco cambia. Comunque, la risposta CSS di Gabriel era proprio quello di cui avevo bisogno, grazie!
Punstress

3
Solo un aggiornamento in ritardo, credo che la prima opzione ora funzionerà nei moderni browser IE.
Fizz,

83

Stavo esaminando la soluzione di @ jaider che ha funzionato, ma sto offrendo un approccio leggermente diverso che penso sia più facile da lavorare e che ho visto essere buono su tutti i browser.

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

Per impostazione predefinita, l'elenco non ordinato visualizza la posizione del punto elenco all'esterno, ma in alcuni browser causerebbe alcuni problemi di visualizzazione in base al modo in cui il browser ha predisposto il sito Web.

Per farlo visualizzare nel formato:

A B
C D
E

ecc. utilizzare quanto segue:

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

Questo dovrebbe risolvere tutti i tuoi problemi con la visualizzazione delle colonne. Ti auguro il meglio e grazie @jaider per la tua risposta che mi ha aiutato a guidarmi nella scoperta di questo.


3
Si è verificato un problema con questo metodo. Funziona benissimo per la visualizzazione di voci di elenco molto brevi (1 carattere in questo esempio). Crea un elenco con descrizioni più lunghe e la seconda colonna si sovrappone alla prima, oltre a esaurire il contenitore ul.
Shaggy,

1
L'ho modificato leggermente cambiando float: left to display: inline-block per gli elementi li, a parte questo ha funzionato a meraviglia per me.
ZeRemz,

41

Ho provato a postare questo come commento, ma non sono riuscito a visualizzare correttamente le colonne (come da tua domanda).

Stai chiedendo:

AB

CD

E

... ma la risposta accettata come soluzione restituirà:

ANNO DOMINI

ESSERE

C

... quindi o la risposta è errata o la domanda è.

Una soluzione molto semplice sarebbe quella di impostare la larghezza del tuo <ul>e quindi galleggiare e impostare la larghezza dei tuoi <li>oggetti in questo modo

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

Esempio qui http://jsfiddle.net/Jayx/Qbz9S/1/

Se la tua domanda è sbagliata, si applicano le risposte precedenti (con una correzione JS per mancanza di supporto IE).


@Gabriel la tua soluzione e il comportamento sono buoni e come previsto, quindi non sto cercando di bussare alla tua risposta ehi ... Penso solo che la domanda potrebbe essere stata male interpretata ... in entrambi i casi - alla domanda è stata data una risposta, non importa che è la domanda corretta: D
Jayx,

16

Mi piace la soluzione per i browser moderni, ma mancano i punti elenco, quindi aggiungo un piccolo trucco:

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

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


li:before {
  content: "• ";
}

inserisci qui la descrizione dell'immagine


Qui possiamo cambiare il colore degli oggetti senza cambiare il colore del proiettile jsfiddle.net/HP85j/444
Jaider

3
Penso che list-style-position: inside;sia una soluzione migliore per mostrare correttamente i proiettili.
Alexis Wilke,

11

Ecco una possibile soluzione:

Frammento:

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>

Ed è fatto.
Per 3 colonne usa la lilarghezza come 33%, per 4 colonne usa il 25% e così via.


5

Questo è il modo più semplice per farlo. Solo CSS.

  1. aggiungi larghezza all'elemento ul.
  2. aggiungi display: blocco in linea e larghezza della nuova colonna (dovrebbe essere inferiore alla metà della larghezza 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
Aggiungi una spiegazione con la risposta su come questa risposta aiuta OP nel risolvere il problema attuale
ρяσѕρєя K

4

Puoi usare CSS solo per impostare due o più colonne

AE

B

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

3

Ciò può essere ottenuto utilizzando la proprietà css conteggio delle colonne sul div parent,

piace

 column-count:2;

controlla questo per maggiori dettagli.

Come far apparire l'elenco DIV mobile nelle colonne, non nelle righe


1
column-countnon visualizzerà gli articoli nell'ordine corretto. Ad esempio, la visualizzazione desiderata nella prima riga è A B(il secondo elemento deve essere aggiunto a destra), ma se lo si utilizza column-countlo sarà A E.
Paolo Moretti,

2

Puoi farlo molto facilmente con il plugin jQuery-Columns, ad esempio per dividere un ul con una classe di .mylist che faresti

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

Ecco un esempio dal vivo su jsfiddle

Mi piace di più rispetto ai CSS perché con la soluzione CSS non tutto si allinea verticalmente verso l'alto.


Interessante, ma in realtà suddivide l' <ul>elenco in più elenchi ... Ciò potrebbe complicare altre cose.
Alexis Wilke,

Questa era in realtà la soluzione che stavo cercando, grazie al downvoter questa risposta è valida se leggi la domanda del PO e non c'era bisogno di DV.
Tricky,

2

più una risposta dopo qualche anno!

in questo articolo: 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%; }

1

In updateColumns()necessità if (column >= columns.length)piuttosto che if (column > columns.length)alla lista di tutti gli elementi (C viene saltato per esempio) così:

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/



1

La soluzione legacy nella risposta principale non ha funzionato per me perché volevo influenzare più elenchi sulla pagina e la risposta presuppone un unico elenco e utilizza un bel po 'di stato globale. In questo caso, volevo modificare ogni elenco all'interno di un <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]);
    }
});

come è possibile, ad esempio, generare due colonne, una contiene solo il riquadro e l'altra un elenco non ordinato?
Dalek,

Non sono sicuro di cosa intendi. Se hai una serie di articoli con titoli, potresti metterli in un unico elenco andando titolo, oggetto, titolo, oggetto e quindi questo dovrebbe funzionare per te.
Tom,

1

Anche se ho trovato la risposta di Gabriel al lavoro, ho trovato quanto segue quando ho cercato di ordinare l'elenco in verticale (primo ul AD e secondo ul EG):

  • Quando l'ul aveva un numero pari di li dentro, non lo stava distribuendo uniformemente tra gli ul
  • usando la colonna di dati in ul non sembra funzionare molto bene, ho dovuto mettere 4 per 3 colonne e anche allora stava ancora diffondendo i li in 2 degli ul generati da JS

Ho rivisto JQuery in modo che quanto sopra si spera non accada.

(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

Questa è stata una soluzione perfetta per me, cercandola per anni:

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


3
"Citare sempre la parte più rilevante di un collegamento importante, nel caso in cui il sito di destinazione non è raggiungibile o va in modo permanente non in linea" - stackoverflow.com/help/how-to-answer
Sk8erPeter

Non è necessario: è il collegamento / riferimento per il codice utilizzato da Abdulnella sua risposta, identico anche alla larghezza e all'ID utilizzati.
cssyphus,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.