CSS: creating grids with table values

CSS: creating grids with table values

CSS table values can be used to create grid layouts. But how?

Grid-based layouts can be built with the CSS display table values, but with some restraints. A table, either used as a markup element or displayed as such using CSS, creates a new formatting context which differs significantly from a normal block/inline-level context. Tables are actually blocks, but their internal algorithms are different from other CSS algorithms. In this article I'd like to discuss some of the aspects related to grid layouts built with CSS table values.

Creating a table layout

First, we need that the outermost container of our blocks be a table:

#grid, #grid2 {
    width: 100%;
    display: table;
}

Now we have an element that behaves like a table. Its default table-layout value is auto, which means that the table will adapt its dimensions to host its contents. We can change this behavior as follows:

#grid2 {
    table-layout: fixed;
}

By default all cell blocks are displayed without any spacing between each cell. In a table display context we cannot use margins to add spacing, so we need to use the border-spacing property. Bear in mind that this property works only if the border-collapse property is set to separate:

#grid, #grid2 {
    width: 100%;
    display: table;
    border-spacing: 10px;
    border-collapse: separate;
}

#grid2 {
    table-layout: fixed;
    border-spacing: 10px 20px;
}

Then we need to create an outer wrapper on our blocks which basically represents a traditional table row:

div.grid-row {
    display: table-row;
    
}

You can set a background on a table row, but not an height. Dimensions, in a table context, depend on the explicit on implicit dimensions of table cells or table columns.

Finally, our table cells:

div.grid-box {
    width: 30%;
    padding: 10px;
    display: table-cell;
    background: #ccc;
}

Cell's dimensions determine the overall dimensions of the table or of the single row. For example, if you have a child element with the following styles:

#grid2 div.grid-box div {
    width: 140px;
    height: 80px;
    line-height: 80px;
    text-align: center;
    background: #fff;
    margin: 0 auto;
    float: left;
    position: relative;
    left: 30px;
}

your table row will be as tall as it's required to display the child's contents in their entirety. Some things to note here:

  1. Floating works.
  2. Relative positioning works.

What about absolute positioning? It doesn't work directly on cell's children elements, but only on children descendants:

#grid2 div.grid-row div span {
    position: absolute;
    top: 0;
    right: 0;
    background: #ccc;
    padding: 4px;
    line-height: normal;
}

That's it. Below you can find all the code and examples.

Demo

Live demo (on jsFiddle)