Joshc
Joshc

Reputation: 3853

Floating divs - variable height and variable columns - with no gaps

I HAVE UPDATED WITH FIDDLES, SEE BOTTOM

I am developing a wordpress theme to work on iphone and ipads and other webkit devices.

I am using media queries to change the width of divs depending on the size and orientation of the device.

These divs however float left, to fill the device screen.

My problem is that the floated div's height are variable. And the div's which are higher than some, are causing gap issues on the floated elements.

I need possible advice on a fix so there are never any gaps, and elements always float, even if there is a higher div in its path.

Is there a possible way of equalizing the div heights to the highest div, the only problem with this is that it need to work with orientation changes on iPad. On iPhone it's not so bad because there is only one column. But on iPad, portrait has 2 columns and landscape has 3 columns.

Please see diagram below explaining my issue.



Diagram



CURRENT CSS

/* GLOBAL STYLE ( which iPhone uses first - 1 column ) ----------- */

.module {
    display: block;
    overflow: hidden;
    width: 100%;
    float: left;
}

/* IPADS (PORTRAIT - 2 column ) ----------- */
@media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px)
and (orientation : portrait) {

    .module {
        width: 50%;
    }

}

/* IPADS (LANDSCAPE - 3 Column ) ----------- */
@media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px)
and (orientation : landscape) {

    .module {
        width: 33.33%;
    }

}

BASIC MARKUP

<div>

    <div class="module"></div>
    <div class="module"></div>
    <div class="module"></div>
    <div class="module"></div>
    <div class="module"></div>
    <div class="module"></div>
    <div class="module"></div>
    <div class="module"></div>
    <div class="module"></div>
    <div class="module"></div>

</div>





UPDATE - I HAVE CREATED PURE CSS FIDDLES TO SIMULATE MY PROBLEM


The fiddle below simulates SMARTPHONES (PORTRAIT AND LANDSCAPE) - ONE COLUMN

See style .module - width: 100% which simulates the appearance of this @media query

@media only screen
and (min-device-width : 320px)
and (max-device-width : 480px)

http://jsfiddle.net/motocomdigital/kdgnP/1/


The fiddle below simulates IPADS (PORTRAIT) - TWO COLUMN

See style .module - width: 50% which simulates the appearance of this @media query

@media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px)
and (orientation : portrait) {

http://jsfiddle.net/motocomdigital/kdgnP/2/


The fiddle below simulates IPADS (LANDSCAPE) - THREE COLUMN

See style .module - width: 33.33% which simulates the appearance of this @media query

@media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px)
and (orientation : landscape) {

http://jsfiddle.net/motocomdigital/kdgnP/3/


Upvotes: 0

Views: 1884

Answers (3)

Esailija
Esailija

Reputation: 140220

Like I said in a comment, you need to calculate this in javascript and use absolute positioning. Here is an example:

http://jsfiddle.net/rJxtm/4/

//Generate random height for each module, normally this doesn't need to be done because
//they have various amounts of contents in a real app.
$(".module").each(function(i) {
    var height = (150 + (Math.random() * 100 | 0));
    this.style.height = height + "px";
});


$(window).bind("orientationchange resize", function(e) {
    var modules = $(".module"),
        columnWidth = modules[0].offsetWidth,
        margin = 10,
        parentWidth = $(".modules").width(),
        fits = Math.floor(parentWidth / (columnWidth + margin * 2)),
        columnHeights = {},
        i;

    for (i = 0; i < fits; ++i) {
        columnHeights[i] = 0;
    }

    function getTop(i) {
        var nColumn = i % fits;
        return columnHeights[nColumn];
    }

    modules.each(function(i) {
        var height = this.offsetHeight, //Now I am just retrieving the height
            nColumn = i % fits;

        this.style.left = ((columnWidth + margin) * nColumn) + "px";
        this.style.top = getTop(i) + "px";
        columnHeights[nColumn] += (height + margin);
    });

}).trigger("resize");

Upvotes: 1

You can use JavaScript to set equal height to all of them.

This is the minified jQuery plugin:

(function(a){a.fn.equalHeight=function(){var b=0;this.each(function(){var c=a(this).height();c>b&&(b=c)});this.each(function(){a(this).height(b)})}})($);

And you can use like that:

$('#modules').children().equalHeight();

Another good solution would be CSS display table. Take a look at this post: http://css-tricks.com/fluid-width-equal-height-columns/

Upvotes: 0

SergeS
SergeS

Reputation: 11779

This cannot be sloved simply by float - only option is to make all this modules same sized ( or add some margin for smaller ones )

Upvotes: 0

Related Questions