FWIW: It's now 2017 and the grid layout module does this out of the box (codepen demo). If the browser support suits you - then use grid. If not, then read on....
As mentioned in @Skadi2k3's answer, the best you can do with CSS is with a series of media queries.
That being said, if you are using a preprocessor such as LESS - this isn't such a difficult or error-prone task. (although, yes, the CSS will still be long and ugly)
Here's how to take advantage of LESS to set up the media queries:
Set up an iteration mixin like this: (You can paste this code into http://less2css.org)
@item-width:100px;
@item-height:100px;
@margin: 5px;
@min-cols:2;
@max-cols:12; //set an upper limit of how may columns you want to write the media queries for
.loopingClass (@index-width) when (@index-width <= @item-width * @max-cols) {
@media (min-width:@index-width) {
#content{
width: @index-width;
}
}
.loopingClass(@index-width + @item-width);
}
.loopingClass (@item-width * @min-cols);
The above mixin will spit out a series of media queries in the form:
@media (min-width: 200px) {
#content {
width: 200px;
}
}
@media (min-width: 300px) {
#content {
width: 300px;
}
}
@media (min-width: 400px) {
#content {
width: 400px;
}
}
...
@media (min-width: 1200px) {
#content {
width: 1200px;
}
}
So with a simple markup like:
<ul id="content">
<li class="box"></li>
<li class="box"></li>
...
<li class="box"></li>
</ul>
With remaining CSS (LESS):
#content {
margin:0 auto;
overflow: auto;
min-width: @min-cols * @item-width;
max-width: @max-cols * @item-width;
display: block;
list-style:none;
background: aqua;
}
.box {
float: left;
height: @item-height - 2 *@margin;
width: @item-width - 2*@margin;
margin:@margin;
background-color:blue;
}
... you get the desired result.
...and it's super easy to customize the layout:
All I need to do is change the variables that I used in the LESS mixin according to my needs - I get the exact layout that I'm after.
So let's say I have items 300px X 100px with a minimum of 2 columns and max 6 columns and a margin of 15px - I just modify the variables like so:
@item-width:300px;
@item-height:100px;
@margin: 15px;
@min-cols:2;
@max-cols:6;
...and voila, I get this CODEPEN
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…