Existe-t-il un moyen de diviser une liste en colonnes?

119

Ma page Web a une liste «maigre»: par exemple, une liste de 100 éléments d'un mot chacun. Pour réduire le défilement, je souhaite présenter cette liste en deux voire quatre colonnes sur la page. Comment dois-je faire cela avec CSS?

<ul>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
</ul>

Je préfère que la solution soit flexible pour que si la liste passe à 200 éléments, je n'ai pas à faire beaucoup d'ajustements manuels pour accueillir la nouvelle liste.

user776676
la source
Il existe une bibliothèque qui fait cela - github.com/yairEO/listBreaker
vsync
Je crois que l'option de colonne CSS fera l'affaire. Cette option est facile à utiliser et à modifier en cas de besoin. Ici, vous l'avez expliqué en détails - kolosek.com/css-columns
Nesha Zoric

Réponses:

254

La solution CSS est: http://www.w3.org/TR/css3-multicol/

Le support du navigateur est exactement ce à quoi vous vous attendez.

Il fonctionne "partout" sauf Internet Explorer 9 ou plus ancien: http://caniuse.com/multicolumn

ul {
    -moz-column-count: 4;
    -moz-column-gap: 20px;
    -webkit-column-count: 4;
    -webkit-column-gap: 20px;
    column-count: 4;
    column-gap: 20px;
}

Voir: http://jsfiddle.net/pdExf/

Si le support IE est requis, vous devrez utiliser JavaScript, par exemple:

http://welcome.totheinter.net/columnizer-jquery-plugin/

Une autre solution consiste à revenir à la normale float: leftpour IE uniquement . L'ordre sera erroné, mais au moins il aura l'air similaire:

Voir: http://jsfiddle.net/NJ4Hw/

<!--[if lt IE 10]>
<style>
li {
    width: 25%;
    float: left
}
</style>
<![endif]-->

Vous pouvez appliquer cette solution de secours avec Modernizr si vous l'utilisez déjà.

trentenaire
la source
Existe-t-il un moyen de supprimer la bordure supérieure de la première lide chaque colonne?
Oui Barry
2
Cela fonctionne très bien pour un espace fixe, mais devient un problème avec les conceptions réactives car les colonnes ne se réduisent pas comme lors de l'utilisation de l'affichage: en ligne ou en bloc en ligne.
unifiedac
4
Fait intéressant: IE est le seul grand navigateur de bureau à prendre pleinement en charge cette fonctionnalité sans préfixes (depuis IE10) ... Oh, l'ironie ...
NemoStein
1
Il peut être nécessaire pour une meilleure prise en charge de plusieurs navigateurs d'inclure cette propriété supplémentaire list-style-position: inside;qui résout spécifiquement le problème signalé par @vsync, je crois.
ThisClark
4
@PrafullaKumarSahu: Essayez li { break-inside: avoid; }: jsfiddle.net/thirtydot/pdExf/903 . Je ne suis pas trop familier avec les colonnes CSS, il pourrait donc y avoir un meilleur moyen.
thirtydot
19

Si vous recherchez une solution qui fonctionne également dans IE, vous pouvez faire flotter les éléments de la liste vers la gauche. Cependant, cela se traduira par une liste qui serpente, comme ceci:

item 1 | item 2 | item 3
item 4 | item 5

Au lieu de colonnes soignées, comme:

item 1 | item 4
item 2 | 
item 3 | 

Le code pour faire cela serait:

ul li {
  width:10em;
  float:left;
}

Vous pouvez ajouter une bordure en bas au lis pour rendre le flux des éléments de gauche à droite plus apparent.

Matt Hampel
la source
bien que cela puisse fonctionner pour un nombre spécifique d'articles, le résultat ne sera pas joli pour seulement 2 articles.
vsync le
Une autre solution CSS fonctionnelle pour les "colonnes nettes": stackoverflow.com/q/54982323/1066234
Kai Noack
10

Si vous voulez un nombre prédéfini de colonnes, vous pouvez utiliser le nombre de colonnes et l'écart de colonnes, comme mentionné ci-dessus.

Cependant, si vous voulez une seule colonne avec une hauteur limitée qui se diviserait en plusieurs colonnes si nécessaire, cela peut être réalisé tout simplement en changeant l'affichage en flex.

Cela ne fonctionnera pas sur IE9 et certains autres anciens navigateurs. Vous pouvez vérifier le support sur Puis-je utiliser

<style>
  ul {
    display: -ms-flexbox;           /* IE 10 */
    display: -webkit-flex;          /* Safari 6.1+. iOS 7.1+ */
    display: flex;
    -webkit-flex-flow: wrap column; /* Safari 6.1+ */
    flex-flow: wrap column;
    max-height: 150px;              /* Limit height to whatever you need */
  }
</style>

<ul>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
</ul>

Maciej Poleski
la source
2
Très proche de ce que je cherche. Le seul inconvénient est que la largeur des colonnes ne s'adapte pas au contenu (essayez avec des éléments de longueur différente). Je ne sais pas comment la largeur de la colonne est définie. Peut-être le avec du premier élément? Dans tous les cas, des conseils sur la façon de surmonter cela?
jorgeh
Serait-il possible de limiter le nombre de colonnes plutôt que la hauteur? J'ai besoin des éléments à remplir dans quatre colonnes, et le css column-countfera un nombre impair de lignes dans les colonnes. Comme 6 éléments dans la première colonne, puis 4, puis 6, puis 5.
Virge Assault
Ce serait bien si vous étiquetiez les éléments, par exemple "Item 1", "Item 2" afin que les téléspectateurs puissent voir le flux des éléments
allkenang
3

Cette réponse n'est pas nécessairement mise à l' échelle, mais ne nécessite que des ajustements mineurs à mesure que la liste s'allonge. Sémantiquement, cela peut sembler un peu contre-intuitif car il s'agit de deux listes, mais à part cela, cela ressemblera à ce que vous voulez dans n'importe quel navigateur jamais créé.

ul {
  float: left;
}

ul > li {
  width: 6em;
}
<!-- Column 1 -->
<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
<!-- Column 2 -->
<ul>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
</ul>

Alan Hape
la source
2

2020 - Restez simple, utilisez CSS Grid

Beaucoup de ces réponses sont dépassées, nous sommes en 2020 et nous ne devrions pas permettre aux personnes qui utilisent encore IE9. Il est beaucoup plus simple d'utiliser simplement la grille CSS .

Le code est très simple et vous pouvez facilement ajuster le nombre de colonnes à l'aide du grid-template-columns. Voyez cela , puis jouez avec ce violon pour répondre à vos besoins.

.grid-list {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}
<ul class="grid-list">
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
</ul>

maxshuty
la source
1
C'est la meilleure solution pour moi.
Patee Gutee le
1

J'ai trouvé que (actuellement) Chrome ( Version 52.0.2743.116 m) a des tonnes de bizarreries et de problèmes avec le CSS column-countconcernant les éléments de débordement et les éléments positionnés absolus à l'intérieur des éléments, en particulier avec certaines transitions de dimensions.

c'est un désordre total et ne peut pas être corrigé, alors j'ai essayé de résoudre ce problème via un simple javascript et j'ai créé une bibliothèque qui le fait - https://github.com/yairEO/listBreaker

Page de démonstration

vsync
la source
Je préfère le plugin jQuery columnizer, à mon avis, il avait une meilleure fonctionnalité pour ce que je faisais (était capable de trier par ordre alphabétique, décroissant ou croissant, le nombre de colonnes, la largeur des colonnes et plus). jQuery Columnizer - WelcomeToTheInter.Net
Brandito
@Brandito - eh bien, le code Columnizer a certainement plus d'options, car c'est presque 1000 lignes de code, comparé au mien qui fait environ 120 lignes .. mais fait bien le travail
vsync
oui mais mon problème avait besoin que la liste reste comme une seule liste, ce qui est plus utile / nécessaire dépend du cas d'utilisation.
Brandito
0

Si vous pouvez le supporter, CSS Grid est probablement le moyen le plus propre de créer une liste unidimensionnelle dans une disposition à deux colonnes avec des intérieurs réactifs.

ul {
  max-width: 400px;
  display: grid;
  grid-template-columns: 50% 50%;
  padding-left: 0;
  border: 1px solid blue;
}

li {
  list-style: inside;
  border: 1px dashed red;
  padding: 10px;
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
<ul>

Ce sont les deux lignes clés qui vous donneront votre disposition à 2 colonnes

display: grid;
grid-template-columns: 50% 50%;
mattLummus
la source
0

La méthode mobile-first consiste à utiliser les colonnes CSS pour créer une expérience pour les écrans plus petits, puis à utiliser les requêtes multimédias pour augmenter le nombre de colonnes à chacun des points d'arrêt définis par votre mise en page.

ul {
  column-count: 2;
  column-gap: 2rem;
}
@media screen and (min-width: 768px)) {
  ul {
    column-count: 3;
    column-gap: 5rem;
  }
}
<ul>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
</ul>

Josh Habdas
la source
0

Voici ce que j'ai fait

ul {
      display: block;
      width: 100%;
}

ul li{
    display: block;
    min-width: calc(30% - 10px);
    float: left;
}

ul li:nth-child(2n + 1){
    clear: left;
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
  <li>0</li>
</ul>

GuruKay
la source