Link to home
Create AccountLog in
Avatar of Robert Granlund
Robert GranlundFlag for United States of America

asked on

CSS 2 Columns

If I have an UL that I am spliting into 2 columns is there a way to choose at which LI it splits into the second Column?  Say I have 10LI's and I want it to split after the 7th so there are 7 on one side and 3 on the other?

.nav ul  {
  columns: 2;
  -webkit-columns: 2;
  -moz-columns: 2;

  -webkit-column-rule: 1px outset #25aae2; /* Chrome, Safari, Opera */
  -moz-column-rule: 1px outset #25aae2; /* Firefox */
   column-rule: 1px outset #25aae2;
   
   -webkit-column-gap: 20px; /* Chrome, Safari, Opera */
   -moz-column-gap: 20px; /* Firefox */
    column-gap: 20px;
}

Open in new window

Avatar of Alexandre Simões
Alexandre Simões
Flag of Switzerland image

Well, this is hacky and not well supported, as far as I know.
Another problem is that it's not that configurable either, meaning that you cannot specify how many items you want per column, it just splits it by itself, evenly as possible.

In this case I would go either for SASS or for JavaScript.

SASS has the advantage of still being CSS, so there's no lag or things moving in the page, but will require you to know how many items you have. It needs to be a fixed value.

JavaScript, on the other hand, is more flexible, it can be completely dynamic and calculate the number of columns and items dynamically based on a rule you set. The problem is that you'll be moving items around which will feel kind of sluggish on slower machines while the page loads; unless you hide the container.

So, what is exactly your scenario?
As you have .nav in your example, is this for a static menu that you know in advance how many items it will have?
Avatar of Robert Granlund

ASKER

Is there a javascript example?
Well, I just did this. It's not quite bullet proof but it should be a nice start:
https://jsfiddle.net/AlexCode/r8bgxtom/ 
(function ($) {
 
    $.fn.colsplit = function(options) {
        var settings = $.extend({
          cols: 1,
          rows: this.length
        }, options );
 
        return this.each(function(idx, item){
        	var $this = $(item),
          		result = [],
          		items = $this.children('li');
          
          for(var c=0;c<settings.cols;c++){
          	var $col = $('<ul></ul>'),
            		colItems = items.splice(0, settings.rows);

            $col
            	.append(colItems)	// add computed column
              .width(Math.floor(100 / settings.cols) + '%') // set the col width
              .css('float', 'left');	// make them side by side
              
            result.push($col);	// add column to the result
          }
          
          $this.html(result);
        });
 
    };
 
}( jQuery ));

Open in new window

It's done as a jQuery plugin so you just need to call it like:
$('ul').colsplit({cols: 2, rows: 6});

Open in new window

Like this it will apply to all ul elements on the page. Make sure you make it more restrictive, like by id or something like that.

You still need to consider some validations that I'm not doing, like if you say 2 columns and 6 rows but you have 20 items on the list, it will only show 12 (2x6). So either you do proper math or you implement your own distribution logic. The basis is there.

Cheers mate
Have fun! :)
ASKER CERTIFIED SOLUTION
Avatar of Rob
Rob
Flag of Australia image

Link to home
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
See answer
That is what I was looking for.  Thanks.