How can I create multi columns from a single unordered list?
Yes, you can create a multi column list as described if you make the ul
a flex container, change the flex-direction
to column
, allow it to wrap by applying flex-wrap: wrap
and additionally force it to wrap by limiting its height
:
ul {
height: 100px;
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
<li>item 6</li>
<li>item 7</li>
<li>item 8</li>
<li>item 9</li>
<li>item 10</li>
<li>item 11</li>
<li>item 12</li>
<li>item 13</li>
<li>item 14</li>
<li>item 15</li>
<li>item 16</li>
<li>item 17</li>
<li>item 18 </li>
<li>item 19</li>
<li>item 20</li>
<li>item 21</li>
</ul>
Ordered/Unordered List on multiple columns
Columns are still a bit buggy. Your example looks fine in Firefox (as long as you've added the -moz- prefix so it works at all). In Chrome, it cuts off the bullet/number as you describe—but you can add list-style-position: inside to change where it gets drawn. This works great if your list items are all one line, but it does change the appearance if they extend to multiple lines.
How to display an unordered list in two columns?
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;
});
}
How do I create a responsive multi-column unordered list within a column in Bootstrap 4?
Put the unordered list into its own row-column pair (nesting) and add style="column-count: 2"
to that. Done!
In other words, replace your list with this code:
<div class="row"> <div class="col" style="column-count: 2"> <ul class="Test"> <li class= "pb-3 puzzle">Puzzles</li> <li class= "pb-3 wrench">Handy Work</li> <li class= "pb-3 plane ">Travel</li> <li class= "pb-3 car">Automobiles</li> <li class= "pb-3 volunteer">Volunteering</li> <li class= "pb-3 camera">Photography</li> </ul> </div></div>
Multiple column lists from one ul , CSS and maybe a bit of JS
The column-count
property
To get the effect you are after, you can use column-count: <number>
:
The column-count CSS property describes the number of columns of the
element.
<number>
Is a strictly positive integer describing the ideal number
of columns into which the content of the element will be flowed. If
the column-width is also set to a non-auto value, it merely indicates
the maximum allowed number of columns.
How the columns display is highly customizable, you can also configure column properties using: column-width
, column-gap
, column-rule
, column-rule-width
, column-rule-style
, column-rule-color
, column-span
, column-fill
, columns
(see above linked MDN article)
Demo
ul { -webkit-column-count: 5; column-count: 5;}
<ul> <li><a href="/link.html">Link1</a> </li> <li><a href="/link.html">Link2</a> </li> <li><a href="/link.html">Link3</a> </li> <li><a href="/link.html">Link4</a> </li> <li><a href="/link.html">Link5</a> </li> <li><a href="/link.html">Link6</a> </li> <li><a href="/link.html">Link7</a> </li> <li><a href="/link.html">Link8</a> </li> <li><a href="/link.html">Link9</a> </li> <li><a href="/link.html">Link10</a> </li></ul>
html multiple columns unordered list with header
I do not recommend you to use this function, as it is rife with improper programming practices and may not be that efficient.
It works fine on the first page load, but on window resize, it becomes a 'little' hectic.
However, I wanted to challenge myself today and I took it on.
What this function basically does is that it gets the coordinates of all occurrences of a specified HTML tag (labeldetailsmall
in this case), picks the elements closest to the top and appends a heading to each while removing the previously inserted heading elements.
The CSS is fuzzy and needs improving (for there is some overlapping of elements).
Once again, use this at your own risk... I just wanted to play with code, and ended up with this.
I just hope that you would get an idea of one way you could use to achieve what you want.
[UPDATED]
The jQuery:
function addThoseHeadings(elementTagInput, yourHEADING){
var elementTag = $( elementTagInput );
var allElementsObject = {positions : {}};
$(elementTag).each(function( index ) {
var theOffset = $(this).offset();
allElementsObject.positions[index] = {
left: theOffset.left,
top: theOffset.top
};
});
var arr = Object.keys( allElementsObject ).map(function ( key, subkey ) { return allElementsObject[key][subkey]['top']; });
var minimumOffset = Math.min.apply( null, arr );
$.each(allElementsObject.positions, function( indexUnwanted, valueOffsets ) {
if( valueOffsets.top == minimumOffset ){
var elementToAppendTo = document.elementFromPoint( valueOffsets.left, valueOffsets.top );
$( elementToAppendTo ).before( '<span class="replaceThese" style="left:'+(valueOffsets.left)+'px;top:'+(valueOffsets.top-35)+'px;">'+yourHEADING+'</span>' );
}
});
}
var yourHEADING = "Log No";
addThoseHeadings( "labeldetailsmall", yourHEADING );
$(window).resize(function() {
$( ".replaceThese" ).remove();
addThoseHeadings( "labeldetailsmall", yourHEADING );
});
The CSS (needs working on):
span {
display: inline-block;
position: fixed;
}
I hope that this would be of some
use to someone!
How to make a multicolumn unordered list?
Probably the only way you can achieve this cleanly (without javascript) is using the column-count
CSS property. IE only supports it from 10+ though: http://caniuse.com/multicolumn
Here's a demo: http://jsbin.com/efiqov/2/
Also, headers should be headers, not list items.
Related Topics
Single VS Multiple Stylesheets in Responsive Web Design
Is There a Google Chrome-Only CSS Hack
Firefox @Font-Face with Local File - Downloadable Font: Download Failed
Compiling and Maintaining Ie-Specific Stylesheets
How to Create a CSS Rule for All Elements Except One Class
Google Chrome > Textboxes > Yellow Border When Active..
Attribute Property Binding for Background-Image Url in Angular 2
CSS Flexbox: Difference Between Align-Items and Align-Content
Rounded Side, Not Rounded Corners
How to Use CSS Position Sticky to Keep a Sidebar Visible with Bootstrap 4
Fonts Are Not Rendered Correctly in Release Mode, But Is Working on Debug Mode in Asp Net Webforms