Comment afficher une liste non ordonnée sur deux colonnes?

216

Avec le code HTML suivant, quelle est la méthode la plus simple pour afficher la liste sur deux colonnes?

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

Affichage souhaité:

A B
C D
E

La solution doit pouvoir fonctionner sur Internet Explorer.

atp03
la source
1
Voici un exemple en direct de la façon de le faire facilement dans jquery: jsfiddle.net/EebVF/5 Utilisation de ce plugin jquery: github.com/fzondlo/jquery-columns - J'aime mieux cela qu'avec CSS car avec la solution CSS tout ne s'aligne pas verticalement vers le haut.
newUserNameHere

Réponses:

372

Navigateurs modernes

exploitez le module de colonnes css3 pour prendre en charge ce que vous recherchez.

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

CSS:

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

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

Navigateurs hérités

Malheureusement, pour le support d'IE, vous aurez besoin d'une solution de code qui implique la manipulation de JavaScript et de dom. Cela signifie qu'à chaque fois que le contenu de la liste change, vous devrez effectuer l'opération de réorganisation de la liste en colonnes et de réimpression. La solution ci-dessous utilise jQuery pour plus de concision.

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

ÉDITER:

Comme indiqué ci-dessous, les colonnes seront ordonnées comme suit:

A  E
B  F
C  G
D

tandis que le PO a demandé une variante correspondant à ce qui suit:

A  B
C  D
E  F
G

Pour accomplir la variante, vous changez simplement le code comme suit:

function updateColumns(){
    column = 0;
    columnItems.each(function(idx, el){
        if (column > columns.length){
            column = 0;
        }
        $(columns.get(column)).append(el);
        column += 1;
    });
}
Gabriel
la source
2
Vous n'affichez pas les éléments dans le bon ordre: jsfiddle.net/HP85j/258 Par exemple, l'affichage souhaité dans la première ligne est A B(le deuxième élément doit être ajouté à droite), mais dans vos exemples, c'est A E.
Paolo Moretti
1
Excellent travail, bien que la logique soit défectueuse s'il y a plus de 2 colonnes, j'ai créé le correctif ici: jsfiddle.net/HP85j/393
Tr1stan
2
les balles manquent
Jaider
1
Il est probablement plus probable que la liste remplisse la colonne 1 avant la colonne 2. Il peut être plus facile de simplement réorganiser les éléments de la liste afin qu'il semble qu'ils soient remplis avant la fin. Bien sûr, cela peut nécessiter de refaire si la liste change. Quoi qu'il en soit, la réponse CSS de Gabriel était exactement ce dont j'avais besoin, merci!
punstress
3
Juste une mise à jour tardive, je pense que la première option fonctionnera désormais dans les navigateurs IE modernes.
Fizz
83

Je cherchais la solution de @ jaider qui a fonctionné, mais j'offre une approche légèrement différente avec laquelle je pense qu'il est plus facile de travailler et que j'ai vue être bonne sur tous les navigateurs.

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

Par défaut, la liste non ordonnée affiche la position de la puce à l'extérieur, mais dans certains navigateurs, cela entraînerait des problèmes d'affichage en fonction de la façon dont le navigateur présente votre site Web.

Pour l'afficher au format:

A B
C D
E

etc., utilisez les éléments suivants:

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

Cela devrait résoudre tous vos problèmes d'affichage des colonnes. Tous mes meilleurs vœux et merci @jaider, car votre réponse m'a aidé à le découvrir.

Winnifred
la source
3
Il y a un problème avec cette méthode. Cela fonctionne très bien pour afficher des éléments de liste très courts (1 caractère dans cet exemple). Créez une liste avec des descriptions plus longues et la deuxième colonne chevauche la première, ainsi que s'exécute hors du conteneur ul.
Shaggy
1
J'ai légèrement modifié cela en changeant float: left pour afficher: inline-block pour les éléments li, à part cela, cela a fait des merveilles pour moi.
ZeRemz
41

J'ai essayé de poster ceci en tant que commentaire, mais je n'ai pas pu afficher les colonnes correctement (selon votre question).

Vous demandez:

UN B

CD

E

... mais la réponse acceptée comme solution reviendra:

UN D

ÊTRE

C

... soit la réponse est incorrecte, soit la question l'est.

Une solution très simple serait de définir la largeur de votre <ul>, puis de flotter et de définir la largeur de vos <li>articles comme suit

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

Exemple ici http://jsfiddle.net/Jayx/Qbz9S/1/

Si votre question est fausse, les réponses précédentes s'appliquent (avec un correctif JS pour manque de support IE).

Jayx
la source
@Gabriel votre solution et le comportement est bon et comme prévu, donc je n'essaie pas de frapper votre réponse hé ... Je pense juste que la question a peut-être été mal interprétée ... de toute façon - la question a été répondue peu importe quelle est la bonne question: D
Jayx
16

J'aime la solution pour les navigateurs modernes, mais les puces manquent, alors j'ajoute un petit truc:

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

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


li:before {
  content: "• ";
}

entrez la description de l'image ici

Jaider
la source
Ici, nous pouvons changer la couleur des articles sans changer la couleur de la balle jsfiddle.net/HP85j/444
Jaider
3
Je pense que list-style-position: inside;c'est une meilleure solution pour que les balles apparaissent correctement.
Alexis Wilke
11

Voici une solution possible:

Fragment:

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>

Et c'est fait.
Pour 3 colonnes, utilisez une lilargeur de 33%, pour 4 colonnes, utilisez 25%, etc.

Abdul
la source
5

C'est la manière la plus simple de le faire. CSS uniquement.

  1. ajouter de la largeur à l'élément ul.
  2. add display: inline-block et largeur de la nouvelle colonne (doit être inférieure à la moitié de la largeur 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
la source
2
Ajoutez une explication avec la réponse pour savoir comment cette réponse aide OP à résoudre le problème actuel
ρяσѕρєя K
4

Vous pouvez utiliser CSS uniquement pour définir deux colonnes ou plus

AE

B

C

 <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
la source
3

Cela peut être réalisé en utilisant la propriété css de comptage de colonnes sur div parent,

comme

 column-count:2;

consultez ceci pour plus de détails.

Comment faire apparaître une liste DIV flottante dans des colonnes, pas des lignes

maximus ツ
la source
1
column-countn'affichera pas les articles dans le bon ordre. Par exemple, l'affichage souhaité dans la première ligne est A B(le deuxième élément doit être ajouté à droite), mais si vous l'utilisez, column-countil le sera A E.
Paolo Moretti
2

Vous pouvez le faire très facilement avec le plugin jQuery-Columns par exemple pour diviser un ul avec une classe de .mylist que vous feriez

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

Voici un exemple en direct sur jsfiddle

J'aime mieux cela qu'avec CSS car avec la solution CSS tout ne s'aligne pas verticalement vers le haut.

newUserNameHere
la source
Intéressant, mais il décompose en fait la <ul> liste en plusieurs listes ... Cela pourrait compliquer d'autres choses.
Alexis Wilke
C'était en fait la solution que je recherchais, grâce au downvoter, cette réponse est valable si vous lisez la question de l'OP et qu'il n'y a pas besoin de DV.
Tricky
2

plus une réponse après quelques années!

dans cet article: 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
la source
1

Dans le updateColumns()besoin if (column >= columns.length)plutôt que if (column > columns.length)de lister tous les éléments (C est sauté par exemple) donc:

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
la source
1

La solution héritée dans la réponse du haut ne fonctionnait pas pour moi car je voulais affecter plusieurs listes sur la page et la réponse suppose une seule liste et elle utilise un bon état global. Dans ce cas, je voulais modifier chaque liste dans 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]);
    }
});
À M
la source
comment est-il possible par exemple de générer deux colonnes, l'une ne contient que la tuile et l'autre une liste non ordonnée?
Dalek
Je ne sais pas trop ce que tu veux dire. Si vous avez une série d'éléments avec des titres, vous pouvez les mettre dans une seule liste allant du titre, de l'élément, du titre, de l'élément, puis cela devrait fonctionner pour vous.
Tom
1

Bien que j'ai trouvé la réponse de Gabriel pour travailler à un degré, j'ai trouvé ce qui suit en essayant de classer la liste verticalement (premier ul AD et deuxième ul EG):

  • Lorsque l'ul avait un nombre pair de li, il ne l'étalait pas uniformément sur l'ul
  • l'utilisation de la colonne de données dans le ul ne semblait pas très bien fonctionner, j'ai dû mettre 4 pour 3 colonnes et même alors, cela ne faisait que répartir les li dans 2 des ul générés par le JS

J'ai révisé le JQuery afin que ce qui précède ne se produise pas.

(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
la source
-1

Thisd était une solution parfaite pour moi, à la recherche depuis des années:

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

rok
la source
3
"Citez toujours la partie la plus pertinente d'un lien important, au cas où le site cible serait inaccessible ou se déconnecterait définitivement" - stackoverflow.com/help/how-to-answer
Sk8erPeter
Pas besoin - c'est le lien / référence pour le code utilisé par Abduldans sa réponse, identique à la largeur et à l'ID utilisées.
cssyphus