css: float блоки, чтобы занять все свободное пространство

Я пытаюсь сделать "мозаику изображений", которая состоит в основном из изображений одинакового размера, а некоторые из них двойной высоты.

все они должны выровнять аккуратно такой:

goal

чтобы сделать автоматическую генерацию этих мозаик как можно проще, я думал, что плавающий их будет лучшим вариантом. К сожалению, большой блок вызывает следующиепотока за, но не раньше:

current floats

что я могу сделать-помимо ручного позиционирования - чтобы получить изображения в нужное место,и все еще легко автоматически создавать макеты?


код, который я сейчас использую:

скрипка

HTML-код :

<div class="frame">
    <div id="p11" class="img">1.1</div>
    <div id="p12" class="img h2">1.2</div>
    <div id="p13" class="img">1.3</div>
    <div id="p21" class="img">2.1</div>
    <div id="p22" class="img">2.2</div>
</div>

CSS:

.frame {
    background-color: blue;
    border: 5px solid black;
    width: 670px;
}
.img {
    width: 200px;
    height: 125px;
    background-color: white;
    border: 1px solid black;
    float: left;
    margin: 10px;
}
.h2 {
    height: 272px;
}

4 ответов


вам нужно использовать Javascript для достижения этого эффекта, я должен был сделать это один раз, и я использовал http://masonry.desandro.com/ -- работал хорошо!


чистое решение CSS

протестировано в Firefox, IE8+ (IE7 похоже, что он должен быть нацелен на добавление верхнего поля, добавленного в 2.1, потому что он перекрывает 1.1). см. fiddle. Это предполагает .h2 - средний div (как ваш пример). Если осталось самое div он не должен нуждаться в каких-либо изменениях. Если правильно Большинство, вам нужно будет расширить отрицательную маржу, чтобы также включить третий div следующий.

.h2 + div {
    float: right;
    margin: 10px 14px 10px 0; /*14px I believe also has to do with borders */
}

.h2 + div + div {
    margin-left: -434px; /*need to account for borders*/
    clear: right;
}

вы можете использовать колонки, как это: http://jsfiddle.net/KKUZL/

Я не знаю, будет ли это противоречить вашему процессу автоматизации....


Я понимаю, что это не только CSS-решение, но и то, что оно стоит (JSFiddle):

HTML:

<div id='container'></div>

CSS:

html, body {
    margin:0px;
    padding:0px;
    height:100%;
}
body {
    background-color:#def;
}
#container {
    margin:0px auto;
    width:635px;
    min-height:100%;
    background-color:#fff;
    box-shadow:0px 0px 5px #888;
    box-sizing:border-box;
    overflow:auto;
}
.widget {
    float:left;
    box-sizing:border-box;
    padding:10px 10px 0px 0px;
}
.widget > div{
    height:100%;
    box-sizing:border-box;
    color:#fff;
    font-size:3em;
    text-align:center;
    padding:.5em;
    overflow:hidden;
}
.widget > div:hover {
    background-color:purple !important;
}

JS:

////////////////////////////////////////
//  ASSUMPTIONS
//    
var TWO_COLUMN_WIDGET_COUNT = 1;
var ONE_COLUMN_WIDGET_COUNT = 15;

var NUMBER_OF_COLUMNS = 2;

////////////////////////////////////////
function rand(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}
var colorFactory = (function () {
    var colors = [
        '#CC9A17',
        '#9B2C16',
        '#1A8B41',
        '#D97114',
        '#3B9EE6'];
    var index = 0;
    return function () {
        if (index > 4) {
            index = 0;
        }
        return colors[index++];
    }
})();
function widgetFactory(columnSpan) {
    return {
        'height': rand(10, 30) * 10,
            'width': 100 * columnSpan / NUMBER_OF_COLUMNS,
            'columnSpan': columnSpan,
            'color': colorFactory()
    }
}
function getWidgets() {
    var widgets = [];
    for (var i = 0; i < TWO_COLUMN_WIDGET_COUNT; i++) {
        widgets.push(widgetFactory(2));
    }
    for (var i = 0; i < ONE_COLUMN_WIDGET_COUNT; i++) {
        widgets.push(widgetFactory(1));
    }
    return widgets;
}
function getHighestOffset(offsets){

}
function getHighestSlot(offsets, numOfColumns){

}
$(document).ready(function () {
    var container = $('#container');
    var widgets = getWidgets();
    var col1 = Math.floor(container[0].offsetLeft);
    var col2 = Math.floor(container[0].clientWidth / 2 + container[0].offsetLeft);
    var offsets = {};
    offsets[col1] = 0;
    offsets[col2] = 0;
    var newLine = true;

    for (var i = 0; i < widgets.length; i++) {
        var w = widgets[i];
        var marginTop = 0;
        if (offsets[col1] < offsets[col2]) {
            marginTop = (offsets[col2] - offsets[col1]) * -1;
        }
        if(offsets[col1] <= offsets[col2] || w.columnSpan == 2){
            newLine = true;
        }
        var margin = 'margin-top:' + marginTop + 'px;';
        var height = 'height:' + w.height + 'px;';
        var color = 'background-color:' + colorFactory() + ';';
        var width = 'width:' + w.width + '%;';
        var padding = newLine ? "padding-left:10px;" : "";
        var component = $('<div class="widget" style="' + padding + margin + height + width + '"><div style="' + color + '">' + i + '</div></div>');
        component.appendTo(container);
        var c = component[0];

        var index = 0;
        var minOffset = null;
        for(var p in offsets){
            if(minOffset == null || offsets[p] < minOffset){
                minOffset = offsets[p];
            }
            if(p == Math.floor(c.offsetLeft)){
                index = 1;
            }
            if(index > 0 && index <= w.columnSpan){
                offsets[p] = c.offsetTop + c.offsetHeight;
                index++;
            }
        }
        newLine = minOffset >= offsets[col1];
    }
});