How to display an unordered list in two columns?

HtmlCssHtml ListsCss Multicolumn-Layout

Html Problem Overview


With the following HTML, what is the easiest method to display the list as two columns?

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

Desired display:

A B
C D
E

The solution needs to work with Internet Explorer.

Html Solutions


Solution 1 - Html

Modern Browsers

leverage the css3 columns module to support what you are looking for.

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

CSS:

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

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

Legacy Browsers

Unfortunately for IE support you will need a code solution that involves JavaScript and dom manipulation. This means that anytime the contents of the list changes you will need to perform the operation for reordering the list into columns and reprinting. The solution below uses jQuery for brevity.

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

EDIT:

As pointed out below this will order the columns as follows:

A  E
B  F
C  G
D

while the OP asked for a variant matching the following:

A  B
C  D
E  F
G

To accomplish the variant you simply change the code to the following:

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

Solution 2 - Html

I was looking at @jaider's solution which worked but I'm offering a slightly different approach that I think is more easy to work with and which I've seen to be good across browsers.

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

By default un-ordered list display the bullet position outside but then in some browsers it would cause some display problems based on the browser's way of laying out your website.

To get it to display in the format:

A B
C D
E

etc. use the following:

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

This should solve all your problems with displaying columns. All the best and thanks @jaider as your response helped to guide me to discover this.

Solution 3 - Html

I tried posting this as a comment, but couldn't get the columns to display right (as per your question).

You are asking for:

A B

C D

E

... but the answer accepted as the solution will return:

A D

B E

C

... so either the answer is incorrect or the question is.

A very simple solution would be to set the width of your <ul> and then float and set the width of your <li> items like so

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

Example here http://jsfiddle.net/Jayx/Qbz9S/1/

If your question is wrong, then the previous answers apply (with a JS fix for lacking IE support).

Solution 4 - Html

I like the solution for modern browsers, but the bullets are missing, so I add it a little trick:

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

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


li:before {
  content: "• ";
}

enter image description here

Solution 5 - Html

Here's a possible solution:

Snippet:

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>

And it is done.
For 3 columns use li width as 33%, for 4 columns use 25% and so on.

Solution 6 - Html

Now days, for the expected result, display:grid; would do (be the easiest ?):

ul {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
}

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

you can also get the columns shrinking on the left and able to have different width:

ul {
  display: grid;
  grid-template-columns: repeat(2, auto);
  justify-content: start;
}

li {
  margin-left: 1em;
  border: solid 1px;/*see me */
}

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

Solution 7 - Html

This is the simplest way to do it. CSS only.

  1. add width to the ul element.

  2. add display:inline-block and width of the new column (should be less than half of the ul width).

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>

Solution 8 - Html

You can use CSS only to set two columns or more

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

Solution 9 - Html

This can be achieved using column-count css property on parent div,

like

 column-count:2;

check this out for more details.

https://stackoverflow.com/questions/5484215/how-to-make-floating-div-list-appear-in-columns-not-rows

Solution 10 - Html

You can do this really easily with the jQuery-Columns Plugin for example to split a ul with a class of .mylist you would do

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

Here's a live example on jsfiddle

I like this better than with CSS because with the CSS solution not everything aligns vertically to the top.

Solution 11 - Html

more one answer after a few years!

in this 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%; }

Solution 12 - Html

In updateColumns() need if (column >= columns.length) rather than if (column > columns.length) to list all elements (C is skipped for example) so:

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/

Solution 13 - Html

With Bootstrap... This answer (https://stackoverflow.com/a/23005046/1128742) got me pointed towards this solution:

<ul class="list-unstyled row">
   <li class="col-xs-6">Item 1</li>
   <li class="col-xs-6">Item 2</li>
   <li class="col-xs-6">Item 3</li>
</ul>

http://jsfiddle.net/patrickbad767/472r0ynf/

Solution 14 - Html

The legacy solution in the top answer didn't work for me because I wanted to affect multiple lists on the page and the answer assumes a single list plus it uses a fair bit of global state. In this case I wanted to alter every list inside a <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]);
    }
});

Solution 15 - Html

Though I found Gabriel answer to work to a degree i did find the following when trying to order the list vertically (first ul A-D and second ul E-G):

  • When the ul had an even number of li's in it, it was not evenly spreading it across the ul's
  • using the data-column in the ul didn't seem to work very well, I had to put 4 for 3 columns and even then it was still only spreading the li's into 2 of the ul generated by the JS

I have revised the JQuery so the above hopefully doesn't happen.

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

Solution 16 - Html

This worked for me. is the best solution because the cells in a row have the same height without taking care of the content

ul {
  display: grid;
  grid-template-columns: repeat(2, 1fr); 
  list-style-position: inside;
  list-style-type: none;
}

li { border: solid 1px; }

<ul>
  <li>asdasd asdad asdasd asdasd adasdasdasd adasdadadada adadas dasdadasdasd asd aA</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
  <li>E</li>
</ul>

Solution 17 - Html

Here is an easy way to make a multiple column list using nothing more than simple CSS. The style tags can obviously be put into a CSS if desired.

<p>Materials List</p>
<ul style="display: inline-block; float: left">
	<u>Item Description<u>
	<li>1/2" x 4' wood dowel</li>
	<li>1/2" x 12"	PVC pipe</li>
	<li>1/2" PVC pipe end cap</li>
	<li>7/16" x 3" light duty expansion spring</li>
	<li>6" plastic zip ties</li>
	<li>Light weight antenna</li>
</ul>
<div style="display: inline-block; margin-left: 1em">
	<u>Qty</u>
	<div style="text-indent: 0.5em">3</div>
	<div style="text-indent: 0.5em">1</div>
	<div style="text-indent: 0.5em">1</div>
	<div style="text-indent: 0.5em">2</div>
	<div style="text-indent: 0.5em">8</div>
	<div style="text-indent: 0.5em">1</div>
</div>
<p></p>

Solution 18 - Html

Thisd was a perfect solution for me, looking it for years:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionatp03View Question on Stackoverflow
Solution 1 - HtmlGabrielView Answer on Stackoverflow
Solution 2 - HtmlWinnifredView Answer on Stackoverflow
Solution 3 - HtmlJayxView Answer on Stackoverflow
Solution 4 - HtmlJaiderView Answer on Stackoverflow
Solution 5 - HtmlAbdulView Answer on Stackoverflow
Solution 6 - HtmlG-CyrillusView Answer on Stackoverflow
Solution 7 - HtmlAviv ShaalView Answer on Stackoverflow
Solution 8 - HtmlBouhejba ziedView Answer on Stackoverflow
Solution 9 - Htmlmaximus ツView Answer on Stackoverflow
Solution 10 - HtmlnewUserNameHereView Answer on Stackoverflow
Solution 11 - Htmluser3632930View Answer on Stackoverflow
Solution 12 - HtmlDaverView Answer on Stackoverflow
Solution 13 - HtmlpatrickbadleyView Answer on Stackoverflow
Solution 14 - HtmlTomView Answer on Stackoverflow
Solution 15 - HtmlAnthony MedhurstView Answer on Stackoverflow
Solution 16 - HtmlFabiel LeónView Answer on Stackoverflow
Solution 17 - HtmlNOYBView Answer on Stackoverflow
Solution 18 - HtmlrokView Answer on Stackoverflow