jQuery.column

jQuery.column v1.0

Simulate CSS3-style automatic columnization for the few browsers (IE) that don’t support it.
It tries to follow CSS3 specification (http://www.w3.org/TR/css3-multicol/) closely.

Demo: http://www.vanderlee.com/martijn/demo/column
Source: https://github.com/vanderlee/column (MIT licensed)

Syntax:

[js]$(<context>).column(<options>);[/js]

Arguments:

  • context (required)
    This should point to the DOM node(s) that hold the content to be columnized.
    Typically this is a <div> element, but other elements are possible.
  • options (required)
    An array or object containing any of the following options (based on CSS3 options).
    • width (default ‘auto’)
      This option works like CSS3 “column-width”. Use it to specify the width of each individual column in pixels or set to ‘auto’ to use the “count” option.
    • count (default ‘auto’)
      Works like CSS3 “column-count”. Set the number of columns to use. If “width” is set, “count” is ignored. If both “width” and “count” are set to ‘auto’ (default), the content will NOT be columnized.
    • gap (default ‘normal’)
      Like CSS3 “column-gap”. Set the distance between two columns in pixels. If set to the default ‘normal’ value, the gap will be 1em, dependant on the context.
    • rule_color (default ” (empty string))
      Like CSS3 “column-rule-color”. Specify the color olf the rule between two columns using any valid CSS color qualifier or name such as ‘black’, ‘#ab37e9’ or ‘rgba(255,0,0,.5)’. If no color is specified or the value is set to an empty string, the color will be the same as CSS ‘color’ option.
    • rule_style (default ‘none’)
      Like CSS3 “column-rule-style”. Sets the line-style of the rule. These allowed names are the same as the border-style names. To show the ruler, you need to atleast set a visible rule-style such as ‘solid’ or ‘dotted’.
    • rule_width (default ‘medium’)
      Like CSS3 “column-rule-width”. Specify the width of the rule line between columns. You can either specify the width in pixels by using an integer number or use any of the border-width names ‘thin’, ‘medium’ or ‘thick’.
    • split (default ‘word’)
      jQuery.column works by splitting the content up in parts which may be rearranged over the columns. By default any text at the top DOM level is split at every whitespace. The ‘word’ mode most closely (though not completely) matches CSS3 splitting. Alternatively you can choose ‘sentence’, which splits text at punctuation end-marks or create your own method.

 Return:

  • Returns the selected DOM elements so you can chain this plug-in like regulaer jQuery.

 Examples:

[js]$(‘body’).column(); // Doesn’t columnize content, since neither "width" nor "count" is specified.[/js]

[js] $(‘body’).column({count: 3}); // Spreads the content of <body> over 3 columns. Columns are stretched to fit the available width.[/js]

[js]$(‘body’).column({width: 250}); // Spreads the content of <body> over columns of 250px. Number of columns depends on the available space.[/js]

[js]$(‘body’).column({ // Columnize with all options…
width: ‘auto’, // Default, this line is redundant.
count: 4, // Spread over 4 columns.
gap: 20, // Space columns 20 pixels apart.
rule_style: ‘dotted’, // Show a dotted rule between columns.
rule_width: ‘thin’, // Set width of rule to ‘thin’ (usually 1 pixel).
rule_color: ‘#ccc’, // Set color of rule to a light gray.
split: ‘sentence’ // Keeps sentences together.
});
[/js]

Checklist:

  1. Make sure you set atleast one of ‘count’ or ‘width’ to enable columnization.

Also see:

  1. http://welcome.totheinter.net/2008/07/22/multi-column-layout-with-css-and-jquery/
    A similar plug-in which works in a different way with different features

24 Responses

  1. Moss
    Moss · September 24, 2011 at 02:33:15 · →

    Is this supposed to be able to work with images? I tried it out on a div full of images (each wrapped in their own divs) and it made a mess. It made three columns but the second two are empty and it put all the sub divs underneath the first one in the hierarchy!

  2. Eitan
    Eitan · October 3, 2011 at 20:41:06 · →

    Doesn’t seem to work on ie checked on 7 & 8.

  3. Vyache
    Vyache · October 4, 2011 at 21:07:54 · →

    Can this thing handle tables that are bigger then a single column. Say I want to have a article, then a table, where the article content would flow around the table in a “S” motion or even turn the table on its side to fit the other content on the next page and the table will fit on its own page.

  4. aery
    aery · October 29, 2011 at 01:36:05 · →

    Your example does not works on IE 7, 8 and 9 on Windows.

  5. gv
    gv · November 7, 2011 at 11:23:45 · →

    line 140 should be:

    + (c > 0? 'left:'+(left - Math.floor(column_gap / 2))+'px;' : '')

    (you need to subtract the padding-left from the left: or else everything after the first column gets bumped too far to the right)

    Thanks for the plugin… hope you figure out an IE fix soon, because it works nice.

  6. gv
    gv · November 8, 2011 at 01:51:47 · →

    Works for me in IE8, but in IE9 it throws this error, if it helps:

    SCRIPT16389: Incorrect function.

    jquery.column-1.0.js, line 66 character 9

    I tried googling the error briefly, but haven’t had a chance to look deeper.

  7. Xandor Schiefer
    Xandor Schiefer · November 17, 2011 at 16:34:41 · →

    I used this on a section that had a definition list in it. In order to do so, I had to go several levels deeper. I replaced:

    function _split(parent) {
    var contents = new Array;
    $(parent).contents().each( function(index, value) {
    if (value.nodeType == 3) { // Node.TEXT_NODE
    contents = contents.concat(split_strategies[settings.split](value));
    } else {
    contents.push(value);
    }
    });
    return contents;
    }

    with:

    function _split(parent) {
    var contents = new Array;
    $(parent).contents().each( function(index, value) {
    if (value.nodeType == 3) { // Node.TEXT_NODE
    contents = contents.concat(split_strategies[settings.split](value));
    } else {
    $(value).contents().each( function(index, child) {
    if (value.nodeType == 3) {
    contents = contents.concat(split_strategies[settings.split](child));
    } else {
    $(child).contents().each( function(index, grandchild) {
    if (value.nodeType == 3) {
    contents = contents.concat(split_strategies[settings.split](grandchild));
    } else {
    contents.push(child);
    }
    });
    }
    });
    contents.push(value);
    }
    });
    return contents;
    }

    Perhaps you could add some recursion to make this work as deep as it needs to go?

  8. gv
    gv · December 14, 2011 at 00:18:59 · →

    I tried your ie9 fix, and it caused a bit of a ruckus… it worked fine in your demo, but on my site, everything got pushed to the last column. I did some digging around and found a cause and fix for the ie9 bug on the previous version of your code…

    change line 67 from:

    node = node.splitText(split);

    to:

    if (split < node.length) {
    node = node.splitText(split);
    } else {
    split = 0;
    }

    Apparently, IE9 is the only browser that can't handle splitText when the divider equals the length, so if you just check for that, everything's kosher. (btw, this should also be done under the sentence function as well…)

    Thanks again for an awesome script.

  9. 2012년 4월 2일 it 기술 동향 |
    2012년 4월 2일 it 기술 동향 | · April 2, 2012 at 02:09:47 · →

    […] 자동으로 컬럼을 나눠주는 column […]

  10. Duncan Malashock
    Duncan Malashock · January 7, 2013 at 06:53:52 · →

    Hi Martijn,

    Thanks for a great plugin! I’m trying to solve a problem with a responsive layout and I think your plugin is the closest I can find to a solution. I’m curious if it can be modified to use a maximum height, so users can read a long article of continuous text in multiple columns and rows without scrolling up and down to start the next column.

    That’s a mouthful, but see this StackOverflow post if you want a better explanation with images: http://stackoverflow.com/questions/14188659/managing-text-columns-in-responsive-layout

    Thanks again,
    Duncan

  11. Tony
    Tony · March 5, 2013 at 12:57:24 · →

    What about the height of the columns, how can you define that?

  12. Matt Chick
    Matt Chick · March 26, 2013 at 00:35:19 · →

    Great piece of work.

    I needed to use it “nested” within a layout – i.e. one where the columns would appear next to other elements. This meant the first column was not on the far left of the screen, but would be positioned to the left of another element.

    To do this I just changed the script around line 135 from

    var left = 0

    to

    var position = $(element).offset().
    var left = position;

    Seems to work fine and keeps works for responsive web design. Not sure if it is useful to anyone else, or whether there would be wider implications of its usage.

    Also – I found that I was getting an occassional bug (even before I amended the script) in ie (where esle!). It would make the first column disapear. To overcome this I called the function on window.load. Again – might be useful for someone.

  13. Frank
    Frank · November 9, 2013 at 21:19:46 · →

    How to fire two times on the same page with different option settings? Thanks for your help.

  14. aruffo3
    aruffo3 · February 27, 2014 at 21:54:28 · →

    Is there any support for em’s or percentages to come in the plugin? The site I’m working on uses em’s predominantly for width, height and font values. I would love to use this plugin.

  15. Robin
    Robin · March 7, 2014 at 11:28:50 · →

    Hi,

    i am using your plugin and it works pretty good!
    i just ran into a little problem, where i would override all my anchor tags in my application (for tracking reasons).

    im doing it like that:

    $(‘a’).click(function (event)
    {
    event.preventDefault();

    console.log(‘a click: #’ + event.currentTarget.id + ‘ clicked’);
    clickMonitorRDG(event.currentTarget.id);
    });

    now, when i call this in my “document ready” function after the column plugin, the markup is still in change, so it would not work with anchors in the columnized text.

    what i would need is an onComplete event from the plugin.. (i could do it with a fixed timeout, but this seems to be dirty and would only be my last hope)

    is there an easy way to implement that? just a little hint would be nice.
    im sorry, i am not really into javascript yet. 🙂

    thanks in advance!

    regards.Robin

  16. Robin
    Robin · March 7, 2014 at 11:43:17 · →

    Oh nevermind.. i just did it like that. 😉

    $(document).click(function (event)
    {
    console.log(‘target = ‘ + event.target.id);
    });

    but an oncomplete event might still be useful for some situations.

    regards

Leave a Reply