visit
While (re)learning CSS, specifically CSS layouts, I came to a topic I haven’t heard before: . And while checking all the material available, I was referred by a friend to this video of a conference given by Morten Rand-Hendriksen: where he said, around 43:40, something that would resonate later in my head: “You in this room can build a new better framework based on CSS grid.”
Later on, in my journey learning CSS, I came to a project where I was supposed to build a grid framework mimicking the behavior of Bootstrap. Here’s when those words came back to my head and I decided I would make one of the unwritten objectives of this framework to give the user a simpler and nicer way to deal with grids using HTML & CSS.Very early I learned that, instead of using the Bootstrap notation of col-{media breakpoint}-{column number} it would be easier and more natural for a CSS grid to use an extended version like col-{media breakpoint}-{start column number}-{end column number} because that’s exactly how grid columns work, and this had the advantage (compared to Bootstrap) that I would have to create neither an nor an because that would be implicit in the notation.
Instead of using:<div class="row">
<div class="col-md-4">Leftmost four columns</div>
<div class="col-md-4 offset-md-4">Rightmost four columns</div>
</div>
<div class="row">
<div class="col-md-1-4">Leftmost four columns</div>
<div class="col-md-9-12">Rightmost four columns</div>
</div>
<div class="row">
<div class="col-md-1-4 col-lg-9-12">Leftmost four columns</div>
<div class="col-md-9-12 col-lg-1-4">Rightmost four columns</div>
</div>
<div class="grid">
<div class="range-md-A1-A4">Header</div>
<div class="range-md-B1-B2">Main</div>
<div class="range-md-B4-C4">Sidebar</div>
<div class="range-md-C1-C3">Footer</div>
</div>
<div class="grid">
<div class="range-md-A1-A4 range-lg-A1-A4">Header</div>
<div class="range-md-B1-B2 range-lg-B3-B4">Main</div>
<div class="range-md-B4-C4 range-lg-B1-C1">Sidebar</div>
<div class="range-md-C1-C3 range-lg-C2-C4">Footer</div>
</div>
That means we need 78 classes to describe a single row with 12 columns in the style col-{media breakpoint}-{start column number}-{end column number}.
But when we increase the vertical dimension, this calculation turns a little bit more complex since we will omit duplicated references (the range a1-b2 is the same as b2-a1), but a simple table should suffice:
We can see how the number of classes increases dramatically with the addition of a row or a column above 4x4; but for practical purposes, a 4x4 table won’t be of much use. I decided to go for a 6x4 grid for two reasons:
First, this gives me some nice equilibrium when dividing the columns (I can have symmetric columns with 1,2,3 and 6, and asymmetric with 4 and 5) and the rows (I can split vertically in half or fourths, keeping a header and footer zone).Second, these containers can be nested, so any of these cells can, in turn, behave like a grid, and in that way my design can grow indefinitely. @each $name, $dimension-min, $dimension-max in $MEDIA-BREAKPOINTS {
@media only screen and (min-width: $dimension-min) {
@for $top from 1 through length($ROWS) {
@for $left from 1 through $COLS {
@for $bottom from $top through length($ROWS) {
@for $right from $left through $COLS {
$top-name: nth($ROWS,$top);
$bottom-name: nth($ROWS,$bottom);
.range-#{$name}-#{$top-name}#{$left}#{$bottom-name}#{$right} {
grid-column: #{$left}/#{$right + 1};
grid-row: #{$top}/#{$bottom + 1};
}
}
}
}
}
}
}
$COLS: 6;
$ROWS: (A,B,C,D);
$MEDIA-BREAKPOINTS: (
(sm, 576px, 767px),
(md, 768px, 991px),
(lg, 992px, 1199px),
(xl, 1200px, 99999px),
);
<div class="excel-grid">
<div class="grid">
<div class="range-md-A1B1"></div>
<div class="range-md-A2A3"></div>
<div class="range-md-A4A5"></div>
<div class="range-md-A6A6"></div>
<div class="range-md-B2B2"></div>
<div class="range-md-B3B4"></div>
<div class="range-md-B5B5"></div>
<div class="range-md-B6B6"></div>
<div class="range-md-C1D1"></div>
<div class="range-md-C2D2"></div>
<div class="range-md-C3C4"></div>
<div class="range-md-D3D4"></div>
<div class="range-md-C5D5"></div>
<div class="range-md-C6D6"></div>
</div>
</div>
By the way, after creating the 14 inner div’s, it took me about 5 to 10 minutes to place each panel in its corresponding position in the window (and I’m a slow typist 😄). Also, using Brackets Live Preview, the feedback is instantaneous.