¿Hay alguna forma de dividir una lista en columnas?


119

Mi página web tiene una lista 'delgada': por ejemplo, una lista de 100 elementos de una palabra de longitud cada uno. Para reducir el desplazamiento, quiero presentar esta lista en dos o incluso cuatro columnas en la página. ¿Cómo debo hacer esto con 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>

Prefiero que la solución sea flexible para que si la lista crece a 200 elementos, no tenga que hacer muchos ajustes manuales para acomodar la nueva lista.


Hay una biblioteca que hace eso - github.com/yairEO/listBreaker
vsync

Creo que la opción de columna CSS servirá. Esta opción es fácil de usar y cambiar si es necesario. Aquí lo tienes explicado en detalle - kolosek.com/css-columns
Nesha Zoric

Respuestas:


254

La solución CSS es: http://www.w3.org/TR/css3-multicol/

La compatibilidad del navegador es exactamente lo que esperarías.

Funciona "en todas partes" excepto Internet Explorer 9 o anterior: 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;
}

Ver: http://jsfiddle.net/pdExf/

Si se requiere compatibilidad con IE, deberá utilizar JavaScript, por ejemplo:

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

Otra solución es volver a la normalidad solofloat: left para IE . El orden será incorrecto, pero al menos se verá similar:

Ver: http://jsfiddle.net/NJ4Hw/

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

Puede aplicar ese respaldo con Modernizr si ya lo está usando.


¿Hay alguna forma de eliminar el borde superior del primero lide cada columna?
Sí Barry

2
Esto funciona muy bien para un espacio fijo, pero se convierte en un problema con los diseños receptivos, ya que las columnas no se colapsan como cuando se usa display: inline o inline-block.
unifiedac

4
Dato interesante: IE es el único navegador de escritorio importante que admite completamente esta función sin prefijos (desde IE10) ... Oh, la ironía ...
NemoStein

1
Puede ser necesario para una mejor compatibilidad con list-style-position: inside;varios navegadores incluir esta propiedad adicional que aborde específicamente el problema señalado por @vsync, creo.
ThisClark

4
@PrafullaKumarSahu: Prueba li { break-inside: avoid; }: jsfiddle.net/thirtydot/pdExf/903 . No estoy muy familiarizado con las columnas CSS, por lo que podría haber una mejor manera.
Thirtydot

19

Si está buscando una solución que también funcione en IE, puede hacer flotar los elementos de la lista a la izquierda. Sin embargo, esto dará como resultado una lista que serpentea, como esta:

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

En lugar de columnas ordenadas, como:

item 1 | item 4
item 2 | 
item 3 | 

El código para hacer eso sería:

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

Puede agregar un borde inferior al li s para que el flujo de los elementos de izquierda a derecha sea más evidente.


Si bien podría funcionar para un número específico de elementos, el resultado no será agradable para solo 2 elementos.
vsync

Otra solución CSS funcional para las "columnas ordenadas": stackoverflow.com/q/54982323/1066234
Kai Noack

10

Si desea un número preestablecido de columnas, puede usar el recuento de columnas y el espacio entre columnas, como se mencionó anteriormente.

Sin embargo, si desea una sola columna con una altura limitada que se dividiría en más columnas si fuera necesario, esto se puede lograr simplemente cambiando la pantalla a flex.

Esto no funcionará en IE9 y algunos otros navegadores antiguos. Puede consultar el soporte en ¿Puedo usar

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


2
Muy cerca de lo que voy tras. El único inconveniente es que el ancho de las columnas no se adapta al contenido (pruebe con elementos de diferente longitud). No estoy seguro de cómo se define el ancho de columna. ¿Quizás el con del primer elemento? En cualquier caso, ¿alguna sugerencia sobre cómo superar esto?
jorgeh

¿Sería posible limitar el número de columnas en lugar de la altura? Necesito que los elementos se completen en cuatro columnas, y el CSS column-counthará un número desigual de filas dentro de las columnas. Como 6 elementos en la primera columna, luego 4, luego 6, luego 5.
Virge Assault

Sería bueno si etiquetara los elementos, por ejemplo, "Elemento 1", "Elemento 2" para que los espectadores puedan ver el flujo de los elementos
Allkenang

3

Esta respuesta no necesariamente escala, pero solo requiere ajustes menores a medida que crece la lista. Semánticamente, puede parecer un poco contraintuitivo, ya que son dos listas, pero aparte de eso, se verá como usted desea en cualquier navegador que se haya creado.

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>


2

2020: hazlo simple, usa CSS Grid

Muchas de estas respuestas están desactualizadas, estamos en 2020 y no deberíamos habilitar a las personas que todavía usan IE9. Es mucho más simple usar la cuadrícula CSS .

El código es muy simple y puede ajustar fácilmente cuántas columnas hay usando grid-template-columns. Vea esto y luego juegue con este violín para satisfacer sus necesidades.

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


1
Esta es la mejor solución para mí.
Patee Gutee

1

Descubrí que (actualmente) Chrome ( Version 52.0.2743.116 m) tiene toneladas de peculiaridades y problemas con CSS con column-countrespecto a los elementos de desbordamiento y los elementos de posición absoluta dentro de los elementos, especialmente con algunas transiciones de dimensiones.

es un desastre total y no se puede arreglar, así que intenté abordar esto a través de un simple javascript y había creado una biblioteca que hace eso: https://github.com/yairEO/listBreaker

Página de demostración


Prefiero el complemento jQuery columnizer, en mi opinión, tenía una mejor funcionalidad para lo que estaba haciendo (pude ordenar alfabéticamente, descendente o ascendente, recuento de columnas, ancho de columnas y más). jQuery Columnizer - WelcomeToTheInter.Net
Brandito

@Brandito - bueno, el código de Columnizer seguro tiene más opciones, ya que tiene casi 1,000 líneas de código, en comparación con el mío, que tiene aproximadamente 120 líneas ... pero hace bien el trabajo
vsync

sí, pero mi problema necesitaba que la lista permaneciera como una lista, lo que es más útil / necesario depende del caso de uso.
Brandito

0

Si puede admitirlo, CSS Grid es probablemente la forma más limpia de hacer una lista unidimensional en un diseño de dos columnas con interiores receptivos.

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>

Estas son las dos líneas clave que le darán su diseño de 2 columnas

display: grid;
grid-template-columns: 50% 50%;

0

La forma móvil primero es usar columnas CSS para crear una experiencia para pantallas más pequeñas y luego usar consultas de medios para aumentar la cantidad de columnas en cada uno de los puntos de interrupción definidos de su diseño.

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>


0

Aquí esta lo que hice

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>

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.