a simple flexible layout-grid, very easy to use and extend (not CSS grid, it’s flex)
this is the markup you need to build a three-column layout
.co-* column sizes The underlying unit here is 1/25 of the viewport width. 12 columns and identical gaps between and to the left and right = 25. They don't have to stay identical, though. For standard layout-grid purposes we have set up the twelve, eight, six, five, four, three, two and one-column widths.
In order to allow for basic asymmetries, two-thirds and three-fourths are there, and as long as 12/12 is not exceeded you can combine widths as you like. If the columns add up to more than twelve they wrap to the next line. Keep in mind that the fivers don‘t play well with others, they should be kept seperate.
The examples here use the .card class just to be visible.
To avoid confusion:
Three is shorthand for one third, four one fourth and so on. CSS-classnames with a "/" wouldn‘t work.
We can decide not to use the grid by filling each row with the maximum number of identical columns. And we don‘t have to fill empty columns in to allow for asymmetrical layouts. We can omit any column and decide what to do with the empty space later. For each row seperately, if that‘s what we need.
Of course you can throw in empty co-* columns if you want to nudge elements. Just don‘t tell the developer.
2 row-right
6
4 row-apart
2
3/4 row-center
8
2 table-style
8
8
8
3 row (or nothing, it‘s the default)
2/3
If you need to combine a grid of boxes with a taller vertical block of text or an image, you can nest a group of smaller co-* boxes in a wrapper column. This one is called colwrap. Container size and column-size should match, though. Like two 1/4 columns in a 1/2 column wrapper.
This is an example of nested columns where the outer section is divided into two columns and the left one is subdivided into another two columns – which in absolute terms is a 1/4 column.
This is an example of nested columns where the outer section is divided into two columns and the left one is subdivided into another two columns – which in absolute terms is a 1/4 column.
This is an example of nested columns where the outer section is divided into two columns and the left one is subdivided into another two columns – which in absolute terms is a 1/4 column.
<section>
<div class="co-2 colwrap">
<div class="co-4">
</div>
<div class="co-4">
</div>
…
</div>
<div class="co-3">
</div>
</section>
This is an example of nested columns where the outer section is divided into two columns and the left one is subdivided into another two columns – which in absolute terms are 1/4 columns.
This column here is a conventional first-level column inside a section; for testing it‘s not the same div.co-2 which wraps around the two sub-columns on the left, but a div.co-3. Just to make sure that the wrapping doesn‘t behave weird and breaks the column calculations. Luckily it doesn‘t.
This is an example of nested columns where the outer wrapper column has the same size as the columns wrapped inside it.
This is an example of nested columns where the outer wrapper column has the same size as the columns wrapped inside it. This is an example of nested columns where the outer wrapper column has the same size as the columns wrapped inside it.
This is an example of nested columns where the outer wrapper column has the same size as the columns wrapped inside it.
This is an example of nested columns where the outer wrapper column has the same size as the columns wrapped inside it. This is an example of nested columns where the outer wrapper column has the same size as the columns wrapped inside it. This is an example of nested columns where the outer wrapper column has the same size as the columns wrapped inside it.
This is an example of nested columns where the outer wrapper column has the same size as the columns wrapped inside it.
This is an example of nested columns where the outer wrapper column has the same size as the columns wrapped inside it.
This is an example of nested columns where the outer wrapper column has the same size as the columns wrapped inside it.
This is an example of nested columns where the outer wrapper column has the same size as the columns wrapped inside it. This is an example of nested columns where the outer wrapper column has the same size as the columns wrapped inside it.
This is an example of nested columns where the outer wrapper column has the same size as the columns wrapped inside it.
this is what makes a div a third of a three-column layout grid
Adjustable: Our grid is fluid/dynamic on the one hand — and totally configurable on the other. This grid system depends on four variables. Three of them are our own rules, which are in turn defined by a global variable: the viewport-width. In CSS that is vw.
var(--g) (for gutter or grid) is the main horizontal measure and is — because of our 12/25-concept — one twenty fifth of the viewport width – thus 4vw.
The idea behind the calc() calculation above is that we only substract the width of all horizontal gaps from the available width and divide the rest by the number of columns we need. We have 4 gaps around 3 columns, 5 around 4 and so on.
var(--v) is the vertical sibling of var(--g), and as long as we want the grid to look horizontally and vertically symmetrical, it stays at 4vw like var(--g). If we want to mix and match transparent columns with background-colored ones symmetry is good.
If we feel there ist too much vertical spacing: just reduce var(--v) maybe on the desktop end, and increase it for mobile (portrait) viewports.
var(--in) is the amount of padding insinde a column or container, when these happen to have a background color like .card or via inline styles.
As a default --in is half of --g, but that's just taste. It may be a good idea to increase these values towards mobile and decrease them beyond small desktops. Keep in mind that the wider the viewport, the larger everything gets.
var(--fwdth) is the variable that controls at which point to stop fluid columns – 1500px is the default, but anything between 1200 and 1800 would be reasonable.
gap In order not to reverse engineer flex‘ main/secondary-axis logic css gap ist used to have flex control and float wrap-behaviour at the same time.
var(--rad) is the outlier here, it‘s sole purpose is to round corners of .co-* blocks. Like for cards
var(--size-s), var(--size-m) and var(--size-l) are there to keep button and form element sizes consistent. Please don‘t use them on anything other than <button> or <input>.
That just depends on how you adjust the proportions of the grid by changing the aforementioned variables. That being said, the standard and symmetrical resolution of 4vw/4vw is a bit coarse, but allows you to combine padded and plain columns. But be careful when using .card or background-colored columns (with that much padding) smaller than 1/4. Vice versa, thin gutters don‘t work with plain columns without padding…
Proportions of the examples are not to scale, the grey background shows the viewport.
Horizontal and vertical gaps and padding are the same size (4vw)
Horizontal gaps and padding same size (2vw), vertical gap 1.5 times horizontal (3vw)
Gaps pixel-sized, padding 3vw. Columns without padding not recommended in this scenario
Disclaimer: Everything here is free to use, but no responsibility is taken for any outcome. Questions & Suggestions: ak at alexkoch dot net (you‘re not a robot, I know). And I don‘t use cookies. Version history