cssgridmasonrymosaic

mozaic grid with css


Trying to make a responsive mozaic grid, which has to look like this. target grid mosaic

<div class="masonry grid clearfix">
        <div class="grid-item dbl-height"></div>
        <div class="grid-item mrg-on-left"></div>
        <div class="grid-item mrg-on-left dbl-width"></div>
        <div class="grid-item mrg-on-left mrg-on-top dbl-width middle-one"></div>
        <div class="grid-item mrg-on-left mrg-on-top dbl-height"></div>
        <div class="grid-item dbl-width pull-up-one bot-one"></div>
        <div class="grid-item mrg-on-left pull-up-one bot-one"></div>
</div>

and this is scss for this

    .grid {
    padding: 1px 0px;
}
.grid-item {
    padding-bottom: calc(((100% - 2px)/4));
    width: calc(((100% - 2px)/4));
    float: left;
    background: violet;
    &.dbl-height {
        padding-bottom: calc(((100% - 2px)/4)*2);
        &.right-one {
            padding-bottom: calc((((100% - 2px)/4)*2) - 1px);
        }
    }
    &.dbl-width {
        width: calc(((100% - 2px)/4)*2);
    }

    &.mrg-on-left {
        margin-left: 1px;
    }
    &.mrg-on-top {
        margin-top: 1px;
    }
    &.middle-one {
        padding-bottom: calc(((100% - 2px)/4) - 1px);
    }
    &.pull-up-one {
        margin-top: calc(((100% - 2px)/(-4)));
    }
    &.bot-one {
        padding-bottom: calc(((100% - 2px)/4) - 1px);
    }
}

If you look, the last two grid items have class 'bot-one'. I have made this floating and using 'padding-bottom' trick, to reach blocks with aspect ratio.

However can't reach the effect.... last 2 block are not stacking in right place... what is wrong here ?


Solution

  • First, see your last three block:

        <div class="grid-item mrg-on-left mrg-on-top dbl-height"></div>
        <div class="grid-item dbl-width pull-up-one bot-one"></div>
        <div class="grid-item mrg-on-left pull-up-one bot-one"></div>
    

    According to spec, see rule 2(https://www.w3.org/TR/CSS21/visuren.html#float-rules):

    If the current box is left-floating, and there are any left-floating boxes generated by elements earlier in the source document, then for each such earlier box, either the left outer edge of the current box must be to the right of the right outer edge of the earlier box, or its top must be lower than the bottom of the earlier box. Analogous rules hold for right-floating boxes.

    Now, see the last three divs, your third-last block will let the element which behind it to place in the forth row.

    The second-last div use margin-top to have a negative number which is same as its height(padding-bottom) and this cause it to out of flow(the forth row).

    The last div can't get the right outer edge of second-last div so it use third-last and this cause it overlap the second-last div.

    overlap (black part is the last div)

    A quick fix(add a margin bottom to the second-last element): https://jsfiddle.net/L0kove74/1/

    Reference: Negative margin breaks float