How to offset div columns in CSS grid system

ONYX picture ONYX · Mar 7, 2014 · Viewed 11.4k times · Source

Does anyone know to offset the first two divs that are in side row that have the class col-3-12 to have an offset of offset-6-12 and offset-9-12 to be on the right side of my grid system jsFiddle

CSS:

body {
    font:20px/1.2 Verdana, Arial; padding:0px; margin:0px;
}
*, *:after, *:before {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing:border-box;
}
.container {
    padding: 20px 20px 0 20px; background-color: red
}
.row {
    padding: 0;
    *zoom: 1;
}
.row:after, .row:before {
    content: ' ';
    display: table;
}
.row:after {
    clear: both;
}
.row > [class*='col-']:first-child {
    margin-left: 0;
}
.row > [class*='col-']:last-child {
    margin-right: 0;
}
.row > [class*='col-'] {
    /* edit here*/
    margin:0px 10px 20px 10px 
}
[class*="col-"] {
    float:left; 
    height:300px;
    background-color: #dedede;
    border: 1px solid #000;

}
[class*=col-]:last-of-type {

}
.col-1-12 {
    width: calc((100% - (12/1 - 1) * 20px) / 12 * 1);

}
.col-2-12 {
    width: calc((100% - (12/2 - 1) * 20px) / 12 * 2);
}
.col-3-12 {
    width:  calc((100% - (12/3 - 1) * 20px) / 12 * 3);  
}
.col-4-12 {
    width: calc((100% - (12/4 - 1) * 20px) / 12 * 4);
}

HTML:

<div class="container">
    <div class="row">

        <div class="col-3-12 offset-6-12">
            Duis aute irure dolor in reprehenderit in voluptate velit esse
            cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
        </div>  
        <div class="col-3-12 offse-9-12">
            Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
        </div>
    </div>
    <div class="row">
        <div class="col-3-12">
            Duis aute irure dolor in reprehenderit in voluptate velit esse
            cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
        </div>  
        <div class="col-3-12">
            Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
        </div>
        <div class="col-4-12">
            Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
        </div>
        <div class="col-2-12">
            Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
        </div>      
    </div>

</div>

Answer

Hashem Qolami picture Hashem Qolami · Mar 7, 2014

Well, for the offset, you need to apply a left margin to floated columns to push them to the right side.

The value of the margin-left is equal to:

  • for the first column which doesn't have a left margin itself: the width of previous columns + the gutter width.

  • for the second column (the other columns):

    • If the column has a left/right margin (which creates the gutter):
      The width of previous columns + the gutter width + 1/2 gutter width. (As the columns have a left/right margin of 1/2 of the gutter width) CSS grid system: columns having left and right margins

    • If the column doesn't have margin-left (i.e. the gutter is created only by margin-right):
      The width of previous columns + the gutter width. CSS grid system: columns having right margin

For instance:

  • for the first column we calculate the left margin for .offest-6 as follows:
.row [class*="col-"]:first-child.offest-6-12 {
    margin-left: calc(((100% - (12/6 - 1) * 20px) / 12 * 6 ) + 20px);
    /*                |          width of col-6-12         | + gutter width */
}

WORKING DEMO.

Note: I used multiple selectors here in order to have a higher specificity value.

Also note that as the columns are floated next to each other, you only need to use the .offset-* class for the first column to push them both to the right side.

  • And for the second column (The other columns) which has left (and right) margin(s):

Since the column has a left (and right) margin (equals 1/2 of the gutter = 10px)

.row [class*="col-"].offest-6-12 {
    margin-left: calc(((100% - (12/6 - 1) * 20px) / 12 * 6 ) + 20px + 10px);
    /*                |          width of col-6-12         | + (1   + 1/2) gutter width */
}

UPDATED DEMO. (The Sassy way: Sass version)

Note

For the second column, you should use offset-6 because there is another col-3 column before the current column.

I.e. You should count the columns' numbers including the offsets.
For instance: col-3 + col-3 including offset-6 = 12 columns. If you add more columns, it'll break the flow as it exceeds the limit of 12 columns in a row.


How can we change the code in my CSS to compensate for that 30px on the end of the calc() function, can there be something in the CSS that's in there to make it work without the 30px. so it can calculate by the 20px gutter instead of that 30px

Now the columns have a left and right margin of 10px which creates the 20px gutter. That's the reason of adding an extra 10px to the gutter width for offsets.

We could use margin-right: 20px for the columns instead of two margin for left and right side (and no margin for the last column). In this case, we wouldn't need to add the extra 10px.

WORKING DEMO.