João Gomes
João Gomes

Reputation: 332

Stack divs in columns

I have the following markup which I can't change. I can only add <div>s to the wrapping container.

<div class="container">
   <div class="box" id="box1">1</div>
   <div class="box" id="box2">2</div>
   <div class="box" id="box3">3</div>
   <div class="box" id="box4">4</div>
   <div class="box" id="box5">5</div>
   <div class="box" id="box6">6</div>
</div>

It is possible to stack <div>s like in the following picture?

+------+--------+--------+
|   1  |    3   |    5   |
+------+--------+--------+
|      |        |        |
|   2  |    4   |    6   |
|      |        |        |
+------+--------+--------+

Upvotes: 3

Views: 874

Answers (3)

totymedli
totymedli

Reputation: 31201

Individual positioning

If you need to create this layout only for this six columns than you could just position them individually, because you have id's you could just position all <div>'s with the # id selector.

Non expandable solution [Demo]

This solution will work for your six column layout, but if you want to expand it and add more columns, then you need to add extra code to your CSS, like .box:nth-child(8) {left: 150px;}.

.container {
   position: relative;
}
.box {
   width: 50px;
   height: 50px;
   float: left;
}
.box:nth-child(2n) {
   position: absolute;
   top: 50px;
}
.box:nth-child(2) {left: 0px;}
.box:nth-child(4) {left: 50px;}
.box:nth-child(6) {left: 100px;}

Improvement for flexibility [Demo]

As Itay mentioned, this solution can be improved if you use the transform property, so you could modify the CSS with this:

.box:nth-child(4) {transform: translate(100%);}
.box:nth-child(6) {transform: translate(200%);}

You still need to change the top property manually. Also don't forget to use vendor prefixes like -webkit- or -ms- if you need them.

Expandable solution [Demo]

This solution also uses the CSS3 nth-child(n) selector, but here we use relative positioning and a trick with the margin-left property. The source code of this solution is much compact/readable and it is expandable so you don't have to add more CSS selectors if you add more boxes to your container, just simply add a new line to your HTML and it will work as a charm.

.box {
   width: 50px;
   height: 50px;
   float: left;
   position: relative;
}
.box:nth-child(2n) {
   top: 50px;
   margin-left: -50px;
}

Improvement for flexibility [Demo]

Don't forget that you can improve this solution too with the transform property:

.box:nth-child(2n) {
   transform: translate(0, 100%);
   margin-left: -50px;
}

However you still need to set the margin-left property by hand. If you do not find a dynamic way to change it by CSS you can use JavaScript/jQuery.

CSS3 columns

CSS3 have this as a new feature, so you can easily create custom columns. Look at this article for more, and also take a look at Itay's answer.

Upvotes: 3

Itay
Itay

Reputation: 16785

Alternative #1 - CSS columns

The simplest solution is using CSS3 columns.

jsFiddle Demo

.container { 
   -webkit-columns: 3;
      -moz-columns: 3;
           columns: 3;
}

Alternative #2 - CSS transforms

Using CSS transforms is still very flexible but supports more browsers than CSS columns.

jsFiddle Demo

.box:nth-child(n+2) {
    position: absolute;
    left: 0;
}
.box:nth-child(2n) {
    top: 100%;
}
.box:nth-child(3), .box:nth-child(4) {
    -webkit-transform: translateX(100%);
        -ms-transform: translateX(100%);
            transform: translateX(100%);
}
.box:nth-child(5), .box:nth-child(6) {
    -webkit-transform: translateX(200%);
        -ms-transform: translateX(200%);
            transform: translateX(200%);
}

Upvotes: 2

marek_lani
marek_lani

Reputation: 4133

If I understand right, try to wrap box1 and box2 to one div, then do the same for box3 and box4 and same for box5 and box6 a then set float left to those wrapping divs, something like:

<div class="container">
  <div style="float:left">
    <div class="box" id="box1">1</div>
    <div class="box" id="box2">2</div>
  <div>
  <div style="float:left">
    <div class="box" id="box3">3</div>
    <div class="box" id="box4">4</div>
  </div>
  <div style="float:left">
    <div class="box" id="box5">5</div>
    <div class="box" id="box6">6</div>
  </div>
</div>

Upvotes: 0

Related Questions