ReallyMadeMeThink
ReallyMadeMeThink

Reputation: 1071

Left aligned divs with equal horizontal margins

I have a number of inline-block elements I wish to house inside a container div. As the container div is resized the number of in-line block elements appearing across/up/down change. I wish to keep these divs left-aligned such that they appear like:

XXXXXXX
XXXXXXX
XXX

and not like:

XXXXXXX
XXXXXXX
  XXX 

But need to maintain equal margins left and right. So the left and right most divs are equidistant from the edges of the container at all times:

|<-XXXXXXX->|
|<-XXXXXXX->|
|<-XXX      |

How can I do this in pure CSS?

http://jsfiddle.net/e818rfum/

Upvotes: 3

Views: 119

Answers (3)

Patrick Rudolph
Patrick Rudolph

Reputation: 2241

If you really want to go for a CSS only solution, I'd suggest you to use a centered container for the individual items + media queries to to adjust the width of this container during resizing.

body {
    margin: 0;
}

.container {
    margin: 0 auto;
    background: #ddd;
}

@media (min-width: 110px) { .container { width: 110px; } }
@media (min-width: 220px) { .container { width: 220px; } }
@media (min-width: 330px) { .container { width: 330px; } }
@media (min-width: 440px) { .container { width: 440px; } }
@media (min-width: 550px) { .container { width: 550px; } }
@media (min-width: 660px) { .container { width: 660px; } }
@media (min-width: 770px) { .container { width: 770px; } }
@media (min-width: 880px) { .container { width: 880px; } }
@media (min-width: 990px) { .container { width: 990px; } }

.item {
    float: left;
    width: 100px;
    height: 100px;
    background: red;
    margin: 5px;
}

.container:after {
    content: '';
    display: block;
    clear: left;
}
<div class="container">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>

You can also access this demo on JSFiddle.

Instead of resizing the container width, which results in varying left/right margins, you could also have percentage values for the items margin or width. Its basically a question of what you want to be your dynamic value in here:

  • variable container margin (see demo)
  • variable item margins
  • variable item widths

Its all possible via CSS only.

Upvotes: 1

ReallyMadeMeThink
ReallyMadeMeThink

Reputation: 1071

After giving up on the CSS I've thrown together this really ugly piece of jQuery to do what I want. Posting it here if only to clarify the desired behavior.

function doLayout(){
        var canFitAcross = Math.floor($(".container").innerWidth()/$(".block").outerWidth(true));
        var reals = $(".container .block:not(.fake)").length;
        var fakes = $(".container .fake").length;
        if((reals+fakes)%canFitAcross!=0){
            $(".fake").remove();
            var neededFakes = canFitAcross-(reals%canFitAcross);
            if(neededFakes!=canFitAcross){
                for(var i=0;i<neededFakes;i++){
                    $(".container").append("<div class='block fake'></div>");
                }
            }

        }
    }

Here I've done away with .left entirely. In its place "fake" (visibility:hidden, opacity:0.5 for demonstration purposes) .block elements are used to get the desired left-alignment.

Demo here: http://jsfiddle.net/mgx37q5m/

Still hoping for some kind of CSS solution...

Upvotes: 0

maryisdead
maryisdead

Reputation: 1810

Not sure if this is what you want. Downside here is obviously the reliance on pixel values. Also switched from display: inline to float: left for the sake of not having to troll myself with gaps and line-height.

.block{
    float:left;
    margin: 0 5px 5px 0;
    width:50px;
    height:50px;
    background-color: red;
}
.container{
    text-align:center;
    border: 1px solid blue;
    padding:5px;
}
.left{
    text-align:left;
    border: 1px solid green;
    margin: 0 auto;
    max-width: 220px; /* Max. four items per row, margins included */
    overflow: hidden; /* Cheap-skate clearfix */
    padding: 5px 0 0 5px;
}
<div class="container">
    <div class="left">
        <div class="block"></div>
        <div class="block"></div>
        <div class="block"></div>
        <div class="block"></div>
        <div class="block"></div>
        <div class="block"></div>
        <div class="block"></div>
        <div class="block"></div>
        <div class="block"></div>
        <div class="block"></div>
    </div>
</div>

(JSFiddle)

Upvotes: 0

Related Questions