Smart Columns w/ CSS & jQuery
Tags: Intermediate
As I observe other liquid based websites, I see two commonly used techniques on displaying columns, the fixed columns and the liquid columns. There are drawbacks to both that I would like to point out, and later would like to pitch my solution.
Fixed Columns
The great thing about having fixed columns in a liquid layout, is that it will fill up the view port with as many columns as it can fit. But as you can see there will be certain viewport resolutions, where it leaves excess white space where a column was just not able to squeeze in.

Liquid Columns
Liquid columns do not leave any excess white space and fits perfectly within its layout, only downside of this is that we are restricted to having a fixed number of columns per row.

Smart Columns with CSS & jQuery
One solution that would be able to benefit the situations is to take the good of both scenarios and mash it into one.
- Allow as many fixed columns to line up across the viewport (as many as it will fit based on the base column size)
- Take excess white space and evenly distribute them to each of the columns to complete the full row. This way the columns will always fit perfectly.
- Keep a default fixed width as the base, so that the columns are reasonably within the intended columns sizes while maintaining enough flexibility to accommodate for the expandable viewport.
HTML
Start by creating an unordered list that would behave as columns.
<ul class="column">
<!--Repeating list item-->
<li>
<div class="block">
<!--Content-->
</div>
</li>
<!--end repeating list item-->
</ul>
CSS
ul.column{
width: 100%;
padding: 0;
margin: 10px 0;
list-style: none;
}
ul.column li {
float: left;
width: 200px; /*Set default width*/
padding: 0;
margin: 5px 0;
display: inline;
}
.block {
height: 355px;
font-size: 1em;
margin-right: 10px; /*Creates the 10px gap between each column*/
padding: 20px;
background: #e3e1d5;
}
.block h2 {
font-size: 1.8em;
}
.block img {
/*Flexible image size with border*/
width: 89%; /*Took 1% off of the width to prevent IE6 bug*/
padding: 5%;
background:#fff;
margin: 0 auto;
display: block;
-ms-interpolation-mode: bicubic; /*prevents image pixelation for IE 6/7 */
}
jQuery
function smartColumns() { //Create a function that calculates the smart columns
//Reset column size to a 100% once view port has been adjusted
$("ul.column").css({ 'width' : "100%"});
var colWrap = $("ul.column").width(); //Get the width of row
var colNum = Math.floor(colWrap / 200); //Find how many columns of 200px can fit per row / then round it down to a whole number
var colFixed = Math.floor(colWrap / colNum); //Get the width of the row and divide it by the number of columns it can fit / then round it down to a whole number. This value will be the exact width of the re-adjusted column
$("ul.column").css({ 'width' : colWrap}); //Set exact width of row in pixels instead of using % - Prevents cross-browser bugs that appear in certain view port resolutions.
$("ul.column li").css({ 'width' : colFixed}); //Set exact width of the re-adjusted column
}
smartColumns();//Execute the function when page loads
$(window).resize(function () { //Each time the viewport is adjusted/resized, execute the function
smartColumns();
});
Conclusion
I am planning on using this technique in the future, if anyone has any other ideas or techniques they use, please don’t hesitate to share it. If you have any questions, comments, or suggestion please let me know!
Related Posts
Author Bio
My name is Soh Tanaka and I am a Los Angeles based designer/front-end developer specializing in CSS driven web design with an emphasis on usability and search engine optimization. I also run a CSS Gallery which is updated daily with the best CSS websites from around the world. Come check it out!
You can learn more about me or
Follow me on twitter for more updates and resources!
Did You Enjoy This Post?
Subscribe via RSS or by email to get all upcoming tutorials and articles delivered straight to you.





+ Add Comment141 Peeps Have Spoken Their Minds...
Very creative, thanks to share ..
Interesting solution, I like new approaches. Good work!
Very nice – thanks for the tip
Now this is something I would definitely use! Awesome idea/solution.
Great technique and seems to degrade gracefully when javascript is turned off.
Hi really nice and useful stuff its a good solution for the common problems for all web developers.
Lovely!
beautiful, beautiful, beautiful, beautiful.
No comments.
This is really interesting.. might have to find a use for it!
Great article as usual. I was working on something similar but you get there first! :)
jQuery make things so easy….
thanks
great info. thanks for sharing .. tweeting about it !
http://www.twitter.com/veeroo18
Great. I love it.
Definetely very useful. Thank you :D
Nacho
Hey that’s very nice.
I saw a website wich use this kind of layout.
http://skreen.it.twodecember.com/
This works with Mootools, but it works perfectly.
Take a look at it.
Thanks.
Amazing styling and great simple to use product,One of the best web app implementations I have have ever seen.
Very smart! Maybe I’ll use this technique on my next project ;)
Very nice Soh. I love the design on your demo. This article will definitely be useful. Thanks.
Awesome. Would definately use it. Liquid images are also great!
hey cool article, i made a framework 6 months ago on this theory called elastic css framework
Perfect! I am working on something right now (just realized it was inspired by the ‘fancy thumbnail hover effect’ post from you a while back!!) that this technique will work perfectly for! I was going to go about it a different way, but this is slicker I think. I’ll post the results. Thanks Soh!
Thats a great idea and the solution, as you posted is really simple! A must have.
Very cool plugin! Another CSS3 property made possible by jQuery.
PS. I love the design of this comment field!
I see an improvement with the smart columns, your current solution does Math.floor which leads to the following stack error:
columns
column
…
column
doing a Math.floor on every column will make a blank space column(realWidth%1) * column(n) pixels.
This can be fixed with the next algorithm:
Math.round(column(realWidth))
column.last.css(width, parentWidth – sum(column:not(:last)(width)))
the actual algorithm is implemented in the elastic css framework
Thanks very much for this solution. I actually needed something like this for a project I’m working on at this moment. So it came at a good time!
jQuery rocks!
Oh, Your very clever and that looks very nice.
Thanks for sharing.
*claps*. Nice technique. I’ll try to use it in my future websites.
If this can be somehow integrated with the (fluid)960 grid system, it will be more helpful I guess.
oh.. great. thank
Great blog, thanks for sharing this.
woow good solution slick design
Dang, that’s a sweet technique. Thanks!
there is right margin!
Now thats what i call sexy! Fantastic, i love it!!!
Excellent write up – a beautifully simple approach to a complex problem. This would be a fantastic way to mark-up an e-commerce product list… *opens Coda*
Thank you so much for posting this. This gives me some ideas on how to create my own CSS-website.
Great tutorial man, it’s very simple and help me remind me that method. thanks!
a link to download the code would be nice. I hate to type…
Where were you a couple months ago when I needed *exactly* this functionality?! :)
Curious to know if you’ve tested performance when the block count dynamically changes? This was the problem I ran into. I have X blocks that display on init which I then allow to be filtered (show/hide) via jQuery. It’s functional for the most part but a bit inconsistent in some cases (ex. 1 row with 2-4 blocks visible). Still debugging but suspect my math is off.
If interested: http://www.incalas.com
Code (still in dev mode so bear with me): http://incalas.com/site_media/js/section/portfolio_grid.js
Select a category > value to filter. For example, YEAR > 2007
Regardless, a great solution that I’m exited to use if the filtration works. Thanks for this!
awesome tutorial, thanks for sharing.
youre Best tips and tricks… Hay Soh… I try youre simple page peel trick and thumbnail image and rotate image gallery… but its failed… can you give a tutorial with the example file maybe… Thank…
Very creative solution, I like the idea, man.
I was browsing Creative Depart (http://www.creativedepart.com/) on the other day, and I thought their columned layout solution.
Your solution really rocks. I was designing an elastic (
embased) layout for an upcoming project and I’ll think about this one if it fits the portfolio page.Very nice technique. Thanx a lot for sharing your ideas.
there is right margin!
there’s a pure CSS way to do this,without the JS.
if you have control of all the widths all you need to do is add an extra div around the the list and play with some widths and overflows
really nice idea.
Very nice. I’m definitely gonna try this. Thanks for sharing.
this is rocknroll.
Very nice! I already see a ton of uses for this. Thanks for sharing!
That’s pretty interesting. I know exactly where I can use it, cheers.
Hey – Can we get a download of this: http://www.sohtanaka.com/web-design/examples/smart-columns/?
Cheers
This would be an excellent improvement for my Museum Theme. Nice work.
Turned it into a plugin:
(function($) {
$.fn.smartColumns = function(options) {
var opts = $.extend({}, $.fn.smartColumns.defaults, options);
$(this).css({ 'width' : "100%"})
var colWrap = $(this).width();
var colNum = Math.floor(colWrap / opts.dimensions);
var colFixed = Math.floor(colWrap / colNum);
$(this).css({ 'width' : colWrap})
$(this).children('li').css({ 'width' : colFixed});
return $(this);
};
$.fn.smartColumns.defaults = {
dimensions : 200
};
})(jQuery);
Call it like this:
$(‘ul.column’).smartColumns();
Or hand in the dimension:
$(‘ul.column’).smartColumns({ dimensions : 300 });
Daniel, thank you!
You da man :-)
Really cool, thanks
Impressed O.O
I was developing a similar project but I’ve never make it work right. Then I saw this post and it make my day!
Thanks for share!!
Came for the columns, found out about:
-ms-interpolation-mode: bicubic;
Thank you very much!
Fantastic Solution !!!!!
Hi this is really helpful but if i want in detail What books would you recommend for beggining to learn css and javascript? Any suggestion would be appreciated.
Hi I’m using this plugin and it’s working very well except for one problem. It seems to be interfering with the jQuery ui dialog feature. When I include $.idleTimer(120000) in my script firebug shows a ‘too much recursion’ error when I attempt to close an open modal dialog. When I remove that line of code it works fine. Any ideas? Thanks in advance
Thanks for posting this. Awesome idea!
Great idea. I have been looking for this type of solution for a couple of days. It is working well in my webpage.
Thanks a lot.
Will give this a try. Love it! Appreciate you sharing. Thanks.
but its not working in ie
Fantastic Solution !!!!!
Nice work…thanks for sharing this post.
This is a beautiful solution.
This has always been an issue for me, occurring on many sites. I usually end up having to contain the columns in a fixed size box, so small viewports have a scroll bar. A non-solution really, but that was what suited my situation the best – until now!!!!
Can’t wait to try this out. Thank you,
Paul.
PS Great site, lovely design, keep up the fantastic work!
@ramya
” …but its not working in ie…. ”
YES IT DOES!!!!
Paul.
Something I have to try. Thank for improving my CSS chops!
Great Code. Thank you. I definitely try this next time i create columns…
Very nice as always Soh, but is there a way to do this with fixed column size instead of liquid. Just want the space between divs to equalize when the browser window size changes. Thanks for the great ideas!
これは最高にクールですね
是非参考にさせていただきます
Nice, Thanks.
1 comment:
in the CSS i found “width: 89%; to prevent IE6 bug”
i am not sure deserves such a global recognition, you could of styling IE6 with width:90%; _width:89%;
Anyway,
Thanks
Great tutorial! This is perfect for a photography portfolio!
I, for one, prefer the fixed sizes. Looks more natural.
very interesting tutorial, thanks!
quick question: I’m trying to integrate the page with lightbox, but it seem that the page load either the resize or the lightbox, but never together
Suggestions?
thanx!
Thanks for sharing…
Thanks a lot for this tutorial. Really smart and useful technique. I have released a wordpress theme based on this tutorial at http://premiumthemes.net/news/snippet-magazine-wordress-theme-with-smart-flexi-columns.html
thanks
Thank you so much. It’s so creative and inspiring!..
Has a anyone seen what happens when the browser window is only big enough to display two or even one column? It stretches them out to fill the space. Has anyone found a fix or workaround or something for that part? Otherwise this is very nice.
greate!
but why it doesnt work when I remove the “container” div?
Excellent article. I always have this kind of problem when i want to show some thumbnail images. Now I have a solution to use in future projects.
Thanks so much for making this available. It’s made things very easy for me to display book covers in nice, neat columns.
I added columns on my site http://slo-novice.com and when i open a lot of tabs in firefox and not looking the loading of the current site, sometimes columns doesn`t stretch :\
And yeah content is dynamic.
Is it possible to include funtionality to specify the number of rows you wish to have?
If I have 12 items at 100px wide each, and my browser is only 500px wide, how can I display 1 row with 5 items? If I resize my browser to 800px wide, how can I show the additional 3 in the row?
If I want to have 2 rows, and my browser is only 500px wide, how can I limit the 12 item list to 10 items or 5 on each row?
Friggen brilliant. Thanks for sharing!
Create tutorial, Thanks I like this
감사합니다.
So creative and inspiring, Thank you
you are a genius, thanks for show us this. [",] manny
This is a short, simple, but wonderful technique!
Thx for sharing!
its creative and useful solutions ….. i like it
One option would be to add a timeout to the resize event so that the javascript doesn’t fire with each delta in the resolution (only after the user has stopped resizing for say 400ms). It *could* help from overloading the browser with js processes on ones that have high resolutions on their resize events. Although I’m not sure how that display would look in the meantime before the smartColumns() fires. Hmmm.
Hi!
Loved this article and also the page design ;)
I’ve been recently develloping a website, on witch earh results are presented to fit on the screen… So, have a with floating ‘s inside. So, instead of changing the items’s width with the remaining space, i splitt that space in two, and turned it into left/right margin. The gets centered, and it’s width is calculated based on how many items fit on the screen. The function needs to be called on $(document).ready() and also on $(document).resize()
Excellent, thank you.
Genius. Thanks for the inspiration!
Wow ! Love simple trick for definitivly GREAT EFFECT … Thùnks!! (I know it’s not a «ù» but sounds funny and looks funny!
Arlequin
Thank you for the knowledge :)
Great Code,
Thank you :)
can you send to me the source file pliiiz
because i dont know haw i creat this
pliiz
Love this, very awesome for liquid layout design. Pulled the demo up on my iPhone and was hoping to see things resize for the dimension restraints, but I still see a page 4 columns wide. Was hoping it might be smart enough to go 1 column wide due to the size of the screen.
It’s so creative and inspiring!..
额,支持中文发言不?我试试
Very nice, looks great love your blog. I’ve seen something similar to this done with comments on a blog and they had a tutorial on it, anyone happen to know the blog I’m talking about? I saw it a few months ago and didn’t bookmark and can’t find it. Thanks.
I’m so sorry I just found the webpage a few minutes after I posted that (after hours of searching previously) http://digitalmash.com/journal/articles/dynamic-columns/ :(
thanx perfect div css :)
Great. I will use it on our websites
Thanks for the awesome tutorial. I generally code with Prototype as my first preference, so I turned it into a Prototype Class:
http://www.hotwaxmedia.com/apache-ofbiz-blog/prototype-tutorials-smart-columns/
Genius. Thanks for the inspiration!
Excellent idea. I had been trying to figure out a nice way to do this. Have implemented it on an upcoming project :)
Thanks again.
Really, its a nice sharing and very cool posting, which give best code for us. thanks and keep it up.
Good to see more techniques applied in Liquid layout design. Great post!
Hey, I am looking for a way that emulates the -moz-columns way of doing things. just telling it how many columns and have it do the rest. Will post it if I get it working. Thanks for the help. -s
great post, i look forward to reading more updates in your blog. Keep the hard work rolling
All right, you’ve inspired me to try this.
Perhaps it is just my code but I seem to run into issues when using lists inside your columns. Specifically if the block has any sort of margin or padding the nested list inside it expands outside of the .column li.
Any thoughts?
just found this from the smashing magazine site –
very intestering and creative method – will return for a full read later to get me head around it.
thanks for sharing.
thanks! Is there any way to distribute the content vertically ? I mean the blocks flow…
thanks
really simple and great! =)
Soh is my Hero
Great solution to may problems.
Nice article, but how about in IE7 and IE8?
Many thanks.
In extreme case where viewport width is less than single column width can add ensure colFixed is at least as wide as single column by adding colFixed = colFixed < colWrap ? colFixed : 200; after var colFixed = Math.floor(colWrap / colNum);
You site is a great resource – thanks for sharing.
Thank you!
…I have a problem though with Daniel’s “plugin” version – when I resize viewport the effect takes place only after page reload. Any ideas?…
How can I view the content vertically?
Hi! Awesome solution, but… anybody know who centralize items when last line have odd items???
Tanks!
How would you change it so that you only have 3 per line?
One problem I see is when you want to place something directly beneath such a section.
Since the ‘li’ are floating, the UL does not have any height. Hence anything placed ahead of the ul, gets overlapped with it.
1st off, THANKS for tut.
HELP:
I just wana ask is it possible or any way i can use “block” Class in ?
Cus i wana use this for WordPress.
HELP: use BLOCK Class for li tag
Brilliant brilliant brilliant! I’ve been looking for this for weeks (forgot to bookmark this page when I first stumbled across it – lesson learnt). I am implementing it in my WordPress theme right now. Thanks!
Thank you for sharing! I’m a beginner yet I understood everything you explained.
Soh-
First off… excellent job! All of these tutorials and how-to’s have been extremely helpful to me in learning what jQuery can do, and some very simple yet immediately beneficial techniques.
In regards to the “Smart Columns” piece… I noticed one thing that I’d like to figure out a solution to for a more enterprise scale deployment… your column fixed with (200px) in the example is done both in the CSS file and the jQuery script. This causes a dangerous dependency if someone were to alter one or the other and not keep them in sync, and limits its usability throughout subsites other developers might create. Is there a way that the fixed size could be done declaratively by those developers who use the script and classes? Below is some pseudo-code to show what I mean.
// this @imports smartcolumn.css
// this is your script.
so if a user only gets those… how could a user
1) choose the column width he needs (change the 200px values)?
2) how could we make the script intelligent enough to use the value within the CSS spreadsheet… so that the width value is not hard coded in both places?
That make sense?
Get back to me if you have a second… thanks Soh. You are most excellent.
You are definitely a skilled writer. You definitely know how to write to keep the audience engaged. Cheers
As a Newbie, I am always searching online for articles that can help me. Thank you
Wow! Thank you! I always wanted to write in my site something like that. Can I take part of your
post to my blog?
would I be able to do this in a word press template and where exactly would i place the jquery. thanks
For anyone who hasn’t found the solution for getting 3 columns per row, all you have to do is change the the colNum value from 200 to 250 depending on the situation.
Hi! Awesome solution, but… anybody know who centralize items when last line have odd items???
Fantastic Solution !!!!!
Thanks a lot for this cute icons..
Thanks for sharing.Good web site
Thanks a lot, great post. Nice.
Its a nice concept and I think it has changed the way I look at items that are bein floated in a fixed width structure, but I do have one question though.
Does this technique affect the width of the content of this list item? For instance, a wrapper div contains an unordered list of news articles. In every list item, there is an image (of say) with width 200px and when you float the list items they have a margin-right of say 20px. That brings us to 880px, leaving us with 120px. Assuming your solution is used to distribute the visible list-items evenly, each list-item expands to a width of 230px, right?
Now the question here is, does this solution also increase the width of the image to 230px or it only considers the list-item while ignoring the image?
Speak Your Mind...