¿Cómo mostrar una lista desordenada en dos columnas?


215

Con el siguiente HTML, ¿cuál es el método más fácil para mostrar la lista como dos columnas?

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

Pantalla deseada:

A B
C D
E

La solución debe poder funcionar en Internet Explorer.


1
Aquí hay un ejemplo en vivo de cómo hacerlo fácilmente en jquery: jsfiddle.net/EebVF/5 Usando este complemento jquery: github.com/fzondlo/jquery-columns: me gusta más que con CSS porque con la solución CSS no todo se alinea verticalmente a la cima.
newUserNameHere

Respuestas:


371

Navegadores modernos

aproveche el módulo de columnas css3 para admitir lo que está buscando.

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

CSS:

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

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

Navegadores heredados

Desafortunadamente para el soporte de IE necesitará una solución de código que implique la manipulación de JavaScript y dom. Esto significa que cada vez que cambie el contenido de la lista, deberá realizar la operación para reordenar la lista en columnas y volver a imprimirla. La solución a continuación utiliza jQuery por brevedad.

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

EDITAR:

Como se señala a continuación, esto ordenará las columnas de la siguiente manera:

A  E
B  F
C  G
D

mientras que el OP solicitó una variante que coincida con lo siguiente:

A  B
C  D
E  F
G

Para lograr la variante, simplemente cambie el código a lo siguiente:

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

2
No está mostrando los elementos en el orden correcto: jsfiddle.net/HP85j/258 Por ejemplo, la visualización deseada en la primera línea es A B(el segundo elemento debe agregarse a la derecha), pero en sus ejemplos es A E.
Paolo Moretti

1
Gran trabajo, aunque la lógica es defectuosa si hay más de 2 columnas, he creado la solución aquí: jsfiddle.net/HP85j/393
Tr1stan

2
faltan las balas
Jaider

1
Probablemente sea más probable que desee que la lista llene la columna 1 antes que la columna 2. Puede ser más fácil simplemente reordenar los elementos de la lista para que parezca que se completaron antes. Por supuesto, eso puede requerir rehacer si la lista cambia. De todos modos, la respuesta CSS de Gabriel fue justo lo que necesitaba, ¡gracias!
Punstress

3
Solo una actualización tardía, creo que la primera opción ahora funcionará en los navegadores IE modernos.
Fizz

82

Estaba buscando la solución de @ jaider que funcionó, pero estoy ofreciendo un enfoque ligeramente diferente con el que creo que es más fácil de trabajar y que he visto que es bueno en todos los navegadores.

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

De forma predeterminada, la lista no ordenada muestra la posición de la viñeta en el exterior, pero luego en algunos navegadores podría causar algunos problemas de visualización en función de la forma en que el navegador diseña su sitio web.

Para que se muestre en el formato:

A B
C D
E

etc. use lo siguiente:

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

Esto debería resolver todos sus problemas al mostrar columnas. Todo lo mejor y gracias @jaider ya que su respuesta me ayudó a guiarme a descubrir esto.


3
Hay un problema con este método. Funciona muy bien para mostrar elementos de lista muy cortos (1 carácter en este ejemplo). Cree una lista con descripciones más largas y la segunda columna se superpone a la primera, y se agota del contenedor ul.
Shaggy

1
Ajusté esto ligeramente cambiando flotante: izquierda para mostrar: bloque en línea para elementos li, aparte de eso, esto funcionó de maravilla para mí.
ZeRemz

41

Intenté publicar esto como un comentario, pero no pude hacer que las columnas se mostraran correctamente (según su pregunta).

Usted está pidiendo:

AB

discos compactos

mi

... pero la respuesta aceptada como la solución devolverá:

ANUNCIO

SER

C

... entonces la respuesta es incorrecta o la pregunta es.

Una solución muy simple sería establecer el ancho de su <ul>y luego flotar y establecer el ancho de sus <li>elementos de esta manera

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

Ejemplo aquí http://jsfiddle.net/Jayx/Qbz9S/1/

Si su pregunta es incorrecta, se aplican las respuestas anteriores (con una solución JS por falta de soporte de IE).


@Gabriel, su solución y el comportamiento es bueno y como se esperaba, por lo que no estoy tratando de obtener su respuesta, hey ... Solo creo que la pregunta podría haber sido malinterpretada ... de cualquier manera, la pregunta ha sido respondida sin importar cual es la pregunta correcta: D
Jayx

16

Me gusta la solución para los navegadores modernos, pero faltan las viñetas, así que agrego un pequeño truco:

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

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


li:before {
  content: "• ";
}

ingrese la descripción de la imagen aquí


Aquí podemos cambiar el color de los artículos sin cambiar el color de la bala jsfiddle.net/HP85j/444
Jaider

3
Creo que list-style-position: inside;es una mejor solución para que las balas se muestren correctamente.
Alexis Wilke

11

Aquí hay una posible solución:

Retazo:

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>

Y ya está hecho.
Para 3 columnas use el liancho como 33%, para 4 columnas use 25% y así sucesivamente.


5

Esta es la forma más sencilla de hacerlo. CSS solamente.

  1. agregue ancho al elemento ul.
  2. agregar pantalla: bloque en línea y ancho de la nueva columna (debe ser inferior a la mitad del ancho 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
Agregue alguna explicación con la respuesta sobre cómo esta respuesta ayuda a OP a solucionar el problema actual
ρяσѕρєя K

4

Puede usar CSS solo para establecer dos columnas o más

AE

si

C

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


2

Puede hacer esto realmente fácilmente con el complemento jQuery-Columns, por ejemplo, para dividir un ul con una clase de .mylist que haría

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

Aquí hay un ejemplo en vivo en jsfiddle

Me gusta más que con CSS porque con la solución CSS no todo se alinea verticalmente en la parte superior.


Interesante, pero en realidad desglosa la <ul>lista en varias listas ... Eso podría complicar otras cosas.
Alexis Wilke

Esta fue en realidad la solución que buscaba, gracias al votante esta respuesta es válida si lees la pregunta del OP y no hay necesidad de DV.
Tricky

2

¡más una respuesta después de unos años!

en este artículo: 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

En updateColumns()necesidad if (column >= columns.length)en lugar de if (column > columns.length)a la lista de todos los elementos (C se omite por ejemplo) para:

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 solución heredada en la respuesta principal no funcionó para mí porque quería afectar varias listas en la página y la respuesta asume una lista única además de que usa un poco de estado global. En este caso, quería alterar cada lista dentro de 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]);
    }
});

¿Cómo es posible, por ejemplo, generar dos columnas, una solo contiene el mosaico y la otra una lista desordenada?
Dalek

No estoy muy seguro de lo que quieres decir. Si tiene una serie de elementos con títulos, puede ponerlos en una sola lista con título, elemento, título, elemento y esto debería funcionar para usted.
Tom

1

Aunque encontré la respuesta de Gabriel para trabajar hasta cierto punto, encontré lo siguiente al intentar ordenar la lista verticalmente (primero ul AD y segundo ul EG):

  • Cuando el ul tenía un número par de li's, no se extendía uniformemente por los ul
  • el uso de la columna de datos en el ul no parecía funcionar muy bien, tuve que poner 4 por 3 columnas e incluso entonces solo estaba extendiendo los li's en 2 de los ul generados por el JS

He revisado el JQuery para que lo anterior no ocurra.

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

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.