Lately, I've been experimenting with the idea of building a lightweight grid system based on CSS Grid.
We do have a grid system in CodyFrame, and it's based on Flexbox. However, CSS Grid has so many powerful features not available in Flexbox, so I ended up creating Flash Grid.
I'm going to share the whole process behind creating Flash Grid. If you'd like to learn more about CSS Grid, this is a great place to start, since we'll touch the main CSS Grid properties, and we'll share some practical tricks to get the most out of this powerful layout system.
In case you'd rather skip the tutorial and just grab the code:
Let's start! 🙌
The first step is creating the .grid
class:
$grid-columns: 12 !default;
.grid {
--grid-cols: #{$grid-columns};
display: grid;
grid-gap: var(--grid-gap, 0); // default grid-gap = 0
grid-template-columns: repeat(var(--grid-cols), 1fr); // grid of 12 flexible columns
> * {
grid-column-end: span var(--grid-cols); // each grid item takes full-width by default
}
}
In defining the number of grid columns, we use the !default
SCSS flag in case the grid system is imported as a module, and we want this value to be customizable.
The grid-template-columns
is the property where we define the grid layout: we want 12 responsive columns. The width of each column is 1fr. Fr (fraction unit) is a smart unit, equal to 1 part of the available space. Because our grid is composed of 12x 1fr columns, each flexible column takes 1/12 of the available width.
The repeat() function allows us to pass a single width value (1fr). Another way to define the same grid would be:
.grid {
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr; // 🙈
}
...but, you know...not so elegant!
Here's a quick overview of the grid we've just created:
In the screenshot above, notice the numbers in between columns (for now, focus only on the positive numbers on top). These line numbers can be used to place grid items.
In the .grid
snippet, we're also targeting all the grid children, and setting their grid-column-end
value equal to span 12
.
By default, we want each child to take the whole available width. grid-column-end
is used to specify the grid item's end position. You can use this property to set an end line (e.g., grid-column-end: 3;
). But if you use the "span" magic word, you define how many columns should be occupied by the grid item. For example, grid-column-end: span 12;
means "span this element across 12 columns".
Why setting a default 12 columns span for the grid items? We're working mobile-first. We can assume, in most cases, our grid items will occupy the full-width (12 columns) at first, and then a smaller amount of columns on bigger screens. Our default value prevents us from having to specify on each grid item .col-12
(span 12) manually.
The number of columns is set as a CSS custom property, in case you want to change it on a component level (or by creating other utility classes). For example:
.grid--2 {
--grid-cols: 2;
}
Next, we can define utility classes for the grid-gap
property:
.grid-gap-xxxxs { --grid-gap: var(--space-xxxxs, 0.125rem); }
.grid-gap-xxxs { --grid-gap: var(--space-xxxs, 0.25rem); }
.grid-gap-xxs { --grid-gap: var(--space-xxs, 0.375rem); }
.grid-gap-xs { --grid-gap: var(--space-xs, 0.5rem); }
.grid-gap-sm { --grid-gap: var(--space-sm, 0.75rem); }
.grid-gap-md { --grid-gap: var(--space-md, 1.25rem); }
.grid-gap-lg { --grid-gap: var(--space-lg, 2rem); }
.grid-gap-xl { --grid-gap: var(--space-xl, 3.25rem); }
.grid-gap-xxl { --grid-gap: var(--space-xxl, 5.25rem); }
.grid-gap-xxxl { --grid-gap: var(--space-xxxl, 8.5rem); }
.grid-gap-xxxxl { --grid-gap: var(--space-xxxxl, 13.75rem); }
The spacing variables are part of CodyFrame. You can replace them with your own spacing scale or use the fallbacks specified in each variable (the value after the comma is applied if the variable is undefined).
The grid-gap
property is used to define the space between grid items.
To complete the basic grid system, we should define the .col
classes:
@for $i from 1 through $grid-columns {
.col-#{$i} { grid-column-end: span #{$i}; }
}
We use the SASS @for loop to generate the .col
classes according to the number of columns specified in the $grid-columns
variable.
The compiled CSS is:
.col-1 { grid-column-end: span 1; }
.col-2 { grid-column-end: span 2; }
.col-3 { grid-column-end: span 3; }
.col-4 { grid-column-end: span 4; }
.col-5 { grid-column-end: span 5; }
.col-6 { grid-column-end: span 6; }
.col-7 { grid-column-end: span 7; }
.col-8 { grid-column-end: span 8; }
.col-9 { grid-column-end: span 9; }
.col-10 { grid-column-end: span 10; }
.col-11 { grid-column-end: span 11; }
.col-12 { grid-column-end: span 12; }
The col classes specify the number of columns occupied by a grid item. Remember that the "span" word means "span the element across x columns", where x is the number specified after span.
Add some CSS Grid spice
To recap, the barebone version of Flash Grid includes the definition of the grid, the grid-gap, and the col utility classes:
Now it's time to add some spice! 💃
Here's the .grid-auto-cols
utility class:
.grid-auto-cols { // cols = same size
display: grid;
grid-gap: var(--grid-gap, 0);
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}
This class is similar to the .grid
class, except we don't set a number of columns. auto-fit
replaces the 12 in the .grid
class. It means letting CSS Grid decide the number of columns based on the width value of the columns (the second value of the repeat() function).
But wait! The width value (1fr in the .grid
class) is now replaced by a minmax() function. It literally means the minimum width of a column is 0, while the max value is 1fr. We're setting a range of values for the column width.
The result: you get a grid where all columns have the same width, regardless of their content or the number of grid items.
Using a similar approach, we create the .grid-auto-{size}
utility classes:
.grid-auto-xs, .grid-auto-sm, .grid-auto-md, .grid-auto-lg, .grid-auto-xl { // auto-sized grid
display: grid;
grid-gap: var(--grid-gap, 0);
grid-template-columns: repeat(auto-fit, minmax(var(--col-min-width), 1fr));
}
.grid-auto-xs { --col-min-width: 8rem; }
.grid-auto-sm { --col-min-width: 10rem; }
.grid-auto-md { --col-min-width: 15rem; }
.grid-auto-lg { --col-min-width: 20rem; }
.grid-auto-xl { --col-min-width: 25rem; }
Unlike .grid-auto-cols
, these new classes have a minimum width value equal to --col-min-width
. The result is a responsive grid where a new column is added when there's enough space for it (the minimum width specified in the minmax() function).
🔥 With the .grid-auto utility classes (.grid-auto-cols
and .grid-auto-{size}
) you can create responsive layouts with no need to use .col
classes on the grid items. Actually, you shouldn't use .col
classes at all if you want the .grid-auto classes to work properly.
Finally, to take advantage of the grid line numbers, we can create a new set of utility classes: col-start-{line-number}
and .col-end-{line-number}
.
@for $i from 1 through $grid-columns {
.col-start-#{$i} { grid-column-start: #{$i}; }
.col-end-#{$i+1} { grid-column-end: #{$i+1}; }
}
The .col-start classes go from .col-start-1
to col-start-12
, while the .col-end classes go from .col-end-2
to .col-end-13
.
Use them if you want a grid item to span between a specific start and end line.
Remember these are the line numbers:
The negative numbers at the bottom are an alternative way to target the same lines. Why they're useful: if you want to target the final line, regardless of the number of columns, you can do the following:
.col-end {
grid-column-end: -1;
}
The .col-start/end classes allow you to create advanced grids:
Class breakpoint modifiers
To make our grid editable at different breakpoints, we can add class modifiers. In CodyFrame, our convention is to add a @{breakpoint} suffix to the classes (e.g., col-4@sm
) to target breakpoints.
Here's an example of the class modifiers at the x-small breakpoint:
$breakpoints: (
xs: 32rem,
sm: 48rem,
md: 64rem,
lg: 80rem,
xl: 90rem
) !default;
@mixin breakpoint($breakpoint) {
@media (min-width: map-get($map: $breakpoints, $key: $breakpoint)) { @content; }
}
@include breakpoint(xs) {
.grid-auto-xs\@xs { --col-min-width: 8rem; }
.grid-auto-sm\@xs { --col-min-width: 10rem; }
.grid-auto-md\@xs { --col-min-width: 15rem; }
.grid-auto-lg\@xs { --col-min-width: 20rem; }
.grid-auto-xl\@xs { --col-min-width: 25rem; }
.grid-auto-cols\@xs { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); }
@for $i from 1 through $grid-columns {
.col-#{$i}\@xs { grid-column-end: span #{$i}; }
.col-start-#{$i}\@xs { grid-column-start: #{$i}; }
.col-end-#{$i+1}\@xs { grid-column-end: #{$i+1}; }
}
.col-start-auto\@xs { grid-column-start: auto; }
.col-end-auto\@xs { grid-column-end: auto; }
}
Beta version of ⚡️ Flash Grid
The beta of Flash Grid is good to go!
Take it for a spin on Codepen:
Final SCSS code:
// ⚡️ Flash Grid
$grid-columns: 12 !default;
.grid, [class*="grid-auto-"] {
display: grid;
grid-gap: var(--grid-gap, 0);
}
.grid {
--grid-cols: #{$grid-columns};
grid-template-columns: repeat(var(--grid-cols), 1fr);
> * {
grid-column-end: span var(--grid-cols);
}
}
.grid-auto-xs, .grid-auto-sm, .grid-auto-md, .grid-auto-lg, .grid-auto-xl { // auto-sized grid
grid-template-columns: repeat(auto-fit, minmax(var(--col-min-width), 1fr));
}
.grid-auto-xs { --col-min-width: 8rem; }
.grid-auto-sm { --col-min-width: 10rem; }
.grid-auto-md { --col-min-width: 15rem; }
.grid-auto-lg { --col-min-width: 20rem; }
.grid-auto-xl { --col-min-width: 25rem; }
.grid-auto-cols { // cols = same size
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}
.grid-gap-xxxxs { --grid-gap: var(--space-xxxxs, 0.125rem); }
.grid-gap-xxxs { --grid-gap: var(--space-xxxs, 0.25rem); }
.grid-gap-xxs { --grid-gap: var(--space-xxs, 0.375rem); }
.grid-gap-xs { --grid-gap: var(--space-xs, 0.5rem); }
.grid-gap-sm { --grid-gap: var(--space-sm, 0.75rem); }
.grid-gap-md { --grid-gap: var(--space-md, 1.25rem); }
.grid-gap-lg { --grid-gap: var(--space-lg, 2rem); }
.grid-gap-xl { --grid-gap: var(--space-xl, 3.25rem); }
.grid-gap-xxl { --grid-gap: var(--space-xxl, 5.25rem); }
.grid-gap-xxxl { --grid-gap: var(--space-xxxl, 8.5rem); }
.grid-gap-xxxxl { --grid-gap: var(--space-xxxxl, 13.75rem); }
@for $i from 1 through $grid-columns {
.col-#{$i} { grid-column-end: span #{$i}; }
.col-start-#{$i} { grid-column-start: #{$i}; }
.col-end-#{$i+1} { grid-column-end: #{$i+1}; }
}
.col-start { grid-column-start: 1; }
.col-end { grid-column-end: -1; }
// breakpoints
$breakpoints: (
xs: 32rem,
sm: 48rem,
md: 64rem,
lg: 80rem,
xl: 90rem
) !default;
@mixin breakpoint($breakpoint) {
@media (min-width: map-get($map: $breakpoints, $key: $breakpoint)) { @content; }
}
@include breakpoint(xs) {
.grid-auto-xs\@xs { --col-min-width: 8rem; }
.grid-auto-sm\@xs { --col-min-width: 10rem; }
.grid-auto-md\@xs { --col-min-width: 15rem; }
.grid-auto-lg\@xs { --col-min-width: 20rem; }
.grid-auto-xl\@xs { --col-min-width: 25rem; }
.grid-auto-cols\@xs { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); }
@for $i from 1 through $grid-columns {
.col-#{$i}\@xs { grid-column-end: span #{$i}; }
.col-start-#{$i}\@xs { grid-column-start: #{$i}; }
.col-end-#{$i+1}\@xs { grid-column-end: #{$i+1}; }
}
.col-start-auto\@xs { grid-column-start: auto; }
.col-end-auto\@xs { grid-column-end: auto; }
}
@include breakpoint(sm) {
.grid-auto-xs\@sm { --col-min-width: 8rem; }
.grid-auto-sm\@sm { --col-min-width: 10rem; }
.grid-auto-md\@sm { --col-min-width: 15rem; }
.grid-auto-lg\@sm { --col-min-width: 20rem; }
.grid-auto-xl\@sm { --col-min-width: 25rem; }
.grid-auto-cols\@sm { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); }
@for $i from 1 through $grid-columns {
.col-#{$i}\@sm { grid-column-end: span #{$i}; }
.col-start-#{$i}\@sm { grid-column-start: #{$i}; }
.col-end-#{$i+1}\@sm { grid-column-end: #{$i+1}; }
}
.col-start-auto\@sm { grid-column-start: auto; }
.col-end-auto\@sm { grid-column-end: auto; }
}
@include breakpoint(md) {
.grid-auto-xs\@md { --col-min-width: 8rem; }
.grid-auto-sm\@md { --col-min-width: 10rem; }
.grid-auto-md\@md { --col-min-width: 15rem; }
.grid-auto-lg\@md { --col-min-width: 20rem; }
.grid-auto-xl\@md { --col-min-width: 25rem; }
.grid-auto-cols\@md { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); }
@for $i from 1 through $grid-columns {
.col-#{$i}\@md { grid-column-end: span #{$i}; }
.col-start-#{$i}\@md { grid-column-start: #{$i}; }
.col-end-#{$i+1}\@md { grid-column-end: #{$i+1}; }
}
.col-start-auto\@md { grid-column-start: auto; }
.col-end-auto\@md { grid-column-end: auto; }
}
@include breakpoint(lg) {
.grid-auto-xs\@lg { --col-min-width: 8rem; }
.grid-auto-sm\@lg { --col-min-width: 10rem; }
.grid-auto-md\@lg { --col-min-width: 15rem; }
.grid-auto-lg\@lg { --col-min-width: 20rem; }
.grid-auto-xl\@lg { --col-min-width: 25rem; }
.grid-auto-cols\@lg { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); }
@for $i from 1 through $grid-columns {
.col-#{$i}\@lg { grid-column-end: span #{$i}; }
.col-start-#{$i}\@lg { grid-column-start: #{$i}; }
.col-end-#{$i+1}\@lg { grid-column-end: #{$i+1}; }
}
.col-start-auto\@lg { grid-column-start: auto; }
.col-end-auto\@lg { grid-column-end: auto; }
}
@include breakpoint(xl) {
.grid-auto-xs\@xl { --col-min-width: 8rem; }
.grid-auto-sm\@xl { --col-min-width: 10rem; }
.grid-auto-md\@xl { --col-min-width: 15rem; }
.grid-auto-lg\@xl { --col-min-width: 20rem; }
.grid-auto-xl\@xl { --col-min-width: 25rem; }
.grid-auto-cols\@xl { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); }
@for $i from 1 through $grid-columns {
.col-#{$i}\@xl { grid-column-end: span #{$i}; }
.col-start-#{$i}\@xl { grid-column-start: #{$i}; }
.col-end-#{$i+1}\@xl { grid-column-end: #{$i+1}; }
}
.col-start-auto\@xl { grid-column-start: auto; }
.col-end-auto\@xl { grid-column-end: auto; }
}
Top comments (18)
@CodeWebHouse / @guerriero_se
Its really post and I was looking for the same since.
It could be good if u added the CSS prefix for the IE11 browsers as well.
Hi Raghavendra! Vendor prefixes are important indeed! However, I prefer to add them using Autoprefixer (or a Post CSS plugin). Cheers!
Yep, you are right.
I used the postcss for the autoprefix
But It not working in IE 11 browser.
Is there any solutions for IE 11 support...!!
Here the CSS generated by postcss
body {
font-family: "helvetica";
padding: 1rem;
}
.child {
background-color: violet;
min-height: 3rem;
padding: var(--grid-gap, 0);
}
.grid, [class*=grid-auto-] {
display: -ms-grid;
display: grid;
grid-gap: var(--grid-gap, 0);
}
.grid {
--grid-cols: 12;
-ms-grid-columns: (1fr)[var(--grid-cols)];
grid-template-columns: repeat(var(--grid-cols), 1fr);
}
.grid > * {
-ms-grid-column-span: var(--grid-cols);
grid-column-end: span var(--grid-cols);
}
.grid-auto-xs, .grid-auto-sm, .grid-auto-md, .grid-auto-lg, .grid-auto-xl {
grid-template-columns: repeat(auto-fit, minmax(var(--col-min-width), 1fr));
}
.grid-auto-xs {
--col-min-width: 8rem;
}
.grid-auto-sm {
--col-min-width: 10rem;
}
.grid-auto-md {
--col-min-width: 15rem;
}
.grid-auto-lg {
--col-min-width: 20rem;
}
.grid-auto-xl {
--col-min-width: 25rem;
}
.grid-auto-cols {
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}
.grid-gap-xxxxs {
--grid-gap: var(--space-xxxxs, 0.125rem);
}
.grid-gap-xxxs {
--grid-gap: var(--space-xxxs, 0.25rem);
}
.grid-gap-xxs {
--grid-gap: var(--space-xxs, 0.375rem);
}
.grid-gap-xs {
--grid-gap: var(--space-xs, 0.5rem);
}
.grid-gap-sm {
--grid-gap: var(--space-sm, 0.75rem);
}
.grid-gap-md {
--grid-gap: var(--space-md, 1.25rem);
}
.grid-gap-lg {
--grid-gap: var(--space-lg, 2rem);
}
.grid-gap-xl {
--grid-gap: var(--space-xl, 3.25rem);
}
.grid-gap-xxl {
--grid-gap: var(--space-xxl, 5.25rem);
}
.grid-gap-xxxl {
--grid-gap: var(--space-xxxl, 8.5rem);
}
.grid-gap-xxxxl {
--grid-gap: var(--space-xxxxl, 13.75rem);
}
.col-1 {
-ms-grid-column-span: 1;
grid-column-end: span 1;
}
.col-start-1 {
-ms-grid-column: 1;
grid-column-start: 1;
}
.col-end-2 {
-ms-grid-column-span: 2;
grid-column-end: 2;
}
.col-2 {
-ms-grid-column-span: 2;
grid-column-end: span 2;
}
.col-start-2 {
-ms-grid-column: 2;
grid-column-start: 2;
}
.col-end-3 {
-ms-grid-column-span: 3;
grid-column-end: 3;
}
.col-3 {
-ms-grid-column-span: 3;
grid-column-end: span 3;
}
.col-start-3 {
-ms-grid-column: 3;
grid-column-start: 3;
}
.col-end-4 {
-ms-grid-column-span: 4;
grid-column-end: 4;
}
.col-4 {
-ms-grid-column-span: 4;
grid-column-end: span 4;
}
.col-start-4 {
-ms-grid-column: 4;
grid-column-start: 4;
}
.col-end-5 {
-ms-grid-column-span: 5;
grid-column-end: 5;
}
.col-5 {
-ms-grid-column-span: 5;
grid-column-end: span 5;
}
.col-start-5 {
-ms-grid-column: 5;
grid-column-start: 5;
}
.col-end-6 {
-ms-grid-column-span: 6;
grid-column-end: 6;
}
.col-6 {
-ms-grid-column-span: 6;
grid-column-end: span 6;
}
.col-start-6 {
-ms-grid-column: 6;
grid-column-start: 6;
}
.col-end-7 {
-ms-grid-column-span: 7;
grid-column-end: 7;
}
.col-7 {
-ms-grid-column-span: 7;
grid-column-end: span 7;
}
.col-start-7 {
-ms-grid-column: 7;
grid-column-start: 7;
}
.col-end-8 {
-ms-grid-column-span: 8;
grid-column-end: 8;
}
.col-8 {
-ms-grid-column-span: 8;
grid-column-end: span 8;
}
.col-start-8 {
-ms-grid-column: 8;
grid-column-start: 8;
}
.col-end-9 {
-ms-grid-column-span: 9;
grid-column-end: 9;
}
.col-9 {
-ms-grid-column-span: 9;
grid-column-end: span 9;
}
.col-start-9 {
-ms-grid-column: 9;
grid-column-start: 9;
}
.col-end-10 {
-ms-grid-column-span: 10;
grid-column-end: 10;
}
.col-10 {
-ms-grid-column-span: 10;
grid-column-end: span 10;
}
.col-start-10 {
-ms-grid-column: 10;
grid-column-start: 10;
}
.col-end-11 {
-ms-grid-column-span: 11;
grid-column-end: 11;
}
.col-11 {
-ms-grid-column-span: 11;
grid-column-end: span 11;
}
.col-start-11 {
-ms-grid-column: 11;
grid-column-start: 11;
}
.col-end-12 {
-ms-grid-column-span: 12;
grid-column-end: 12;
}
.col-12 {
-ms-grid-column-span: 12;
grid-column-end: span 12;
}
.col-start-12 {
-ms-grid-column: 12;
grid-column-start: 12;
}
.col-end-13 {
-ms-grid-column-span: 13;
grid-column-end: 13;
}
.col-start {
-ms-grid-column: 1;
grid-column-start: 1;
}
.col-end {
-ms-grid-column-span: -1;
grid-column-end: -1;
}
@media (min-width: 32rem) {
.grid-auto-xs\@xs {
--col-min-width: 8rem;
}
.grid-auto-sm\@xs {
--col-min-width: 10rem;
}
.grid-auto-md\@xs {
--col-min-width: 15rem;
}
.grid-auto-lg\@xs {
--col-min-width: 20rem;
}
.grid-auto-xl\@xs {
--col-min-width: 25rem;
}
.grid-auto-cols\@xs {
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}
.col-1\@xs {
-ms-grid-column-span: 1;
grid-column-end: span 1;
}
.col-start-1\@xs {
-ms-grid-column: 1;
grid-column-start: 1;
}
.col-end-2\@xs {
-ms-grid-column-span: 2;
grid-column-end: 2;
}
.col-2\@xs {
-ms-grid-column-span: 2;
grid-column-end: span 2;
}
.col-start-2\@xs {
-ms-grid-column: 2;
grid-column-start: 2;
}
.col-end-3\@xs {
-ms-grid-column-span: 3;
grid-column-end: 3;
}
.col-3\@xs {
-ms-grid-column-span: 3;
grid-column-end: span 3;
}
.col-start-3\@xs {
-ms-grid-column: 3;
grid-column-start: 3;
}
.col-end-4\@xs {
-ms-grid-column-span: 4;
grid-column-end: 4;
}
.col-4\@xs {
-ms-grid-column-span: 4;
grid-column-end: span 4;
}
.col-start-4\@xs {
-ms-grid-column: 4;
grid-column-start: 4;
}
.col-end-5\@xs {
-ms-grid-column-span: 5;
grid-column-end: 5;
}
.col-5\@xs {
-ms-grid-column-span: 5;
grid-column-end: span 5;
}
.col-start-5\@xs {
-ms-grid-column: 5;
grid-column-start: 5;
}
.col-end-6\@xs {
-ms-grid-column-span: 6;
grid-column-end: 6;
}
.col-6\@xs {
-ms-grid-column-span: 6;
grid-column-end: span 6;
}
.col-start-6\@xs {
-ms-grid-column: 6;
grid-column-start: 6;
}
.col-end-7\@xs {
-ms-grid-column-span: 7;
grid-column-end: 7;
}
.col-7\@xs {
-ms-grid-column-span: 7;
grid-column-end: span 7;
}
.col-start-7\@xs {
-ms-grid-column: 7;
grid-column-start: 7;
}
.col-end-8\@xs {
-ms-grid-column-span: 8;
grid-column-end: 8;
}
.col-8\@xs {
-ms-grid-column-span: 8;
grid-column-end: span 8;
}
.col-start-8\@xs {
-ms-grid-column: 8;
grid-column-start: 8;
}
.col-end-9\@xs {
-ms-grid-column-span: 9;
grid-column-end: 9;
}
.col-9\@xs {
-ms-grid-column-span: 9;
grid-column-end: span 9;
}
.col-start-9\@xs {
-ms-grid-column: 9;
grid-column-start: 9;
}
.col-end-10\@xs {
-ms-grid-column-span: 10;
grid-column-end: 10;
}
.col-10\@xs {
-ms-grid-column-span: 10;
grid-column-end: span 10;
}
.col-start-10\@xs {
-ms-grid-column: 10;
grid-column-start: 10;
}
.col-end-11\@xs {
-ms-grid-column-span: 11;
grid-column-end: 11;
}
.col-11\@xs {
-ms-grid-column-span: 11;
grid-column-end: span 11;
}
.col-start-11\@xs {
-ms-grid-column: 11;
grid-column-start: 11;
}
.col-end-12\@xs {
-ms-grid-column-span: 12;
grid-column-end: 12;
}
.col-12\@xs {
-ms-grid-column-span: 12;
grid-column-end: span 12;
}
.col-start-12\@xs {
-ms-grid-column: 12;
grid-column-start: 12;
}
.col-end-13\@xs {
-ms-grid-column-span: 13;
grid-column-end: 13;
}
.col-start-auto\@xs {
-ms-grid-column: auto;
grid-column-start: auto;
}
.col-end-auto\@xs {
-ms-grid-column-span: auto;
grid-column-end: auto;
}
}
@media (min-width: 48rem) {
.grid-auto-xs\@sm {
--col-min-width: 8rem;
}
.grid-auto-sm\@sm {
--col-min-width: 10rem;
}
.grid-auto-md\@sm {
--col-min-width: 15rem;
}
.grid-auto-lg\@sm {
--col-min-width: 20rem;
}
.grid-auto-xl\@sm {
--col-min-width: 25rem;
}
.grid-auto-cols\@sm {
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}
.col-1\@sm {
-ms-grid-column-span: 1;
grid-column-end: span 1;
}
.col-start-1\@sm {
-ms-grid-column: 1;
grid-column-start: 1;
}
.col-end-2\@sm {
-ms-grid-column-span: 2;
grid-column-end: 2;
}
.col-2\@sm {
-ms-grid-column-span: 2;
grid-column-end: span 2;
}
.col-start-2\@sm {
-ms-grid-column: 2;
grid-column-start: 2;
}
.col-end-3\@sm {
-ms-grid-column-span: 3;
grid-column-end: 3;
}
.col-3\@sm {
-ms-grid-column-span: 3;
grid-column-end: span 3;
}
.col-start-3\@sm {
-ms-grid-column: 3;
grid-column-start: 3;
}
.col-end-4\@sm {
-ms-grid-column-span: 4;
grid-column-end: 4;
}
.col-4\@sm {
-ms-grid-column-span: 4;
grid-column-end: span 4;
}
.col-start-4\@sm {
-ms-grid-column: 4;
grid-column-start: 4;
}
.col-end-5\@sm {
-ms-grid-column-span: 5;
grid-column-end: 5;
}
.col-5\@sm {
-ms-grid-column-span: 5;
grid-column-end: span 5;
}
.col-start-5\@sm {
-ms-grid-column: 5;
grid-column-start: 5;
}
.col-end-6\@sm {
-ms-grid-column-span: 6;
grid-column-end: 6;
}
.col-6\@sm {
-ms-grid-column-span: 6;
grid-column-end: span 6;
}
.col-start-6\@sm {
-ms-grid-column: 6;
grid-column-start: 6;
}
.col-end-7\@sm {
-ms-grid-column-span: 7;
grid-column-end: 7;
}
.col-7\@sm {
-ms-grid-column-span: 7;
grid-column-end: span 7;
}
.col-start-7\@sm {
-ms-grid-column: 7;
grid-column-start: 7;
}
.col-end-8\@sm {
-ms-grid-column-span: 8;
grid-column-end: 8;
}
.col-8\@sm {
-ms-grid-column-span: 8;
grid-column-end: span 8;
}
.col-start-8\@sm {
-ms-grid-column: 8;
grid-column-start: 8;
}
.col-end-9\@sm {
-ms-grid-column-span: 9;
grid-column-end: 9;
}
.col-9\@sm {
-ms-grid-column-span: 9;
grid-column-end: span 9;
}
.col-start-9\@sm {
-ms-grid-column: 9;
grid-column-start: 9;
}
.col-end-10\@sm {
-ms-grid-column-span: 10;
grid-column-end: 10;
}
.col-10\@sm {
-ms-grid-column-span: 10;
grid-column-end: span 10;
}
.col-start-10\@sm {
-ms-grid-column: 10;
grid-column-start: 10;
}
.col-end-11\@sm {
-ms-grid-column-span: 11;
grid-column-end: 11;
}
.col-11\@sm {
-ms-grid-column-span: 11;
grid-column-end: span 11;
}
.col-start-11\@sm {
-ms-grid-column: 11;
grid-column-start: 11;
}
.col-end-12\@sm {
-ms-grid-column-span: 12;
grid-column-end: 12;
}
.col-12\@sm {
-ms-grid-column-span: 12;
grid-column-end: span 12;
}
.col-start-12\@sm {
-ms-grid-column: 12;
grid-column-start: 12;
}
.col-end-13\@sm {
-ms-grid-column-span: 13;
grid-column-end: 13;
}
.col-start-auto\@sm {
-ms-grid-column: auto;
grid-column-start: auto;
}
.col-end-auto\@sm {
-ms-grid-column-span: auto;
grid-column-end: auto;
}
}
@media (min-width: 64rem) {
.grid-auto-xs\@md {
--col-min-width: 8rem;
}
.grid-auto-sm\@md {
--col-min-width: 10rem;
}
.grid-auto-md\@md {
--col-min-width: 15rem;
}
.grid-auto-lg\@md {
--col-min-width: 20rem;
}
.grid-auto-xl\@md {
--col-min-width: 25rem;
}
.grid-auto-cols\@md {
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}
.col-1\@md {
-ms-grid-column-span: 1;
grid-column-end: span 1;
}
.col-start-1\@md {
-ms-grid-column: 1;
grid-column-start: 1;
}
.col-end-2\@md {
-ms-grid-column-span: 2;
grid-column-end: 2;
}
.col-2\@md {
-ms-grid-column-span: 2;
grid-column-end: span 2;
}
.col-start-2\@md {
-ms-grid-column: 2;
grid-column-start: 2;
}
.col-end-3\@md {
-ms-grid-column-span: 3;
grid-column-end: 3;
}
.col-3\@md {
-ms-grid-column-span: 3;
grid-column-end: span 3;
}
.col-start-3\@md {
-ms-grid-column: 3;
grid-column-start: 3;
}
.col-end-4\@md {
-ms-grid-column-span: 4;
grid-column-end: 4;
}
.col-4\@md {
-ms-grid-column-span: 4;
grid-column-end: span 4;
}
.col-start-4\@md {
-ms-grid-column: 4;
grid-column-start: 4;
}
.col-end-5\@md {
-ms-grid-column-span: 5;
grid-column-end: 5;
}
.col-5\@md {
-ms-grid-column-span: 5;
grid-column-end: span 5;
}
.col-start-5\@md {
-ms-grid-column: 5;
grid-column-start: 5;
}
.col-end-6\@md {
-ms-grid-column-span: 6;
grid-column-end: 6;
}
.col-6\@md {
-ms-grid-column-span: 6;
grid-column-end: span 6;
}
.col-start-6\@md {
-ms-grid-column: 6;
grid-column-start: 6;
}
.col-end-7\@md {
-ms-grid-column-span: 7;
grid-column-end: 7;
}
.col-7\@md {
-ms-grid-column-span: 7;
grid-column-end: span 7;
}
.col-start-7\@md {
-ms-grid-column: 7;
grid-column-start: 7;
}
.col-end-8\@md {
-ms-grid-column-span: 8;
grid-column-end: 8;
}
.col-8\@md {
-ms-grid-column-span: 8;
grid-column-end: span 8;
}
.col-start-8\@md {
-ms-grid-column: 8;
grid-column-start: 8;
}
.col-end-9\@md {
-ms-grid-column-span: 9;
grid-column-end: 9;
}
.col-9\@md {
-ms-grid-column-span: 9;
grid-column-end: span 9;
}
.col-start-9\@md {
-ms-grid-column: 9;
grid-column-start: 9;
}
.col-end-10\@md {
-ms-grid-column-span: 10;
grid-column-end: 10;
}
.col-10\@md {
-ms-grid-column-span: 10;
grid-column-end: span 10;
}
.col-start-10\@md {
-ms-grid-column: 10;
grid-column-start: 10;
}
.col-end-11\@md {
-ms-grid-column-span: 11;
grid-column-end: 11;
}
.col-11\@md {
-ms-grid-column-span: 11;
grid-column-end: span 11;
}
.col-start-11\@md {
-ms-grid-column: 11;
grid-column-start: 11;
}
.col-end-12\@md {
-ms-grid-column-span: 12;
grid-column-end: 12;
}
.col-12\@md {
-ms-grid-column-span: 12;
grid-column-end: span 12;
}
.col-start-12\@md {
-ms-grid-column: 12;
grid-column-start: 12;
}
.col-end-13\@md {
-ms-grid-column-span: 13;
grid-column-end: 13;
}
.col-start-auto\@md {
-ms-grid-column: auto;
grid-column-start: auto;
}
.col-end-auto\@md {
-ms-grid-column-span: auto;
grid-column-end: auto;
}
}
@media (min-width: 80rem) {
.grid-auto-xs\@lg {
--col-min-width: 8rem;
}
.grid-auto-sm\@lg {
--col-min-width: 10rem;
}
.grid-auto-md\@lg {
--col-min-width: 15rem;
}
.grid-auto-lg\@lg {
--col-min-width: 20rem;
}
.grid-auto-xl\@lg {
--col-min-width: 25rem;
}
.grid-auto-cols\@lg {
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}
.col-1\@lg {
-ms-grid-column-span: 1;
grid-column-end: span 1;
}
.col-start-1\@lg {
-ms-grid-column: 1;
grid-column-start: 1;
}
.col-end-2\@lg {
-ms-grid-column-span: 2;
grid-column-end: 2;
}
.col-2\@lg {
-ms-grid-column-span: 2;
grid-column-end: span 2;
}
.col-start-2\@lg {
-ms-grid-column: 2;
grid-column-start: 2;
}
.col-end-3\@lg {
-ms-grid-column-span: 3;
grid-column-end: 3;
}
.col-3\@lg {
-ms-grid-column-span: 3;
grid-column-end: span 3;
}
.col-start-3\@lg {
-ms-grid-column: 3;
grid-column-start: 3;
}
.col-end-4\@lg {
-ms-grid-column-span: 4;
grid-column-end: 4;
}
.col-4\@lg {
-ms-grid-column-span: 4;
grid-column-end: span 4;
}
.col-start-4\@lg {
-ms-grid-column: 4;
grid-column-start: 4;
}
.col-end-5\@lg {
-ms-grid-column-span: 5;
grid-column-end: 5;
}
.col-5\@lg {
-ms-grid-column-span: 5;
grid-column-end: span 5;
}
.col-start-5\@lg {
-ms-grid-column: 5;
grid-column-start: 5;
}
.col-end-6\@lg {
-ms-grid-column-span: 6;
grid-column-end: 6;
}
.col-6\@lg {
-ms-grid-column-span: 6;
grid-column-end: span 6;
}
.col-start-6\@lg {
-ms-grid-column: 6;
grid-column-start: 6;
}
.col-end-7\@lg {
-ms-grid-column-span: 7;
grid-column-end: 7;
}
.col-7\@lg {
-ms-grid-column-span: 7;
grid-column-end: span 7;
}
.col-start-7\@lg {
-ms-grid-column: 7;
grid-column-start: 7;
}
.col-end-8\@lg {
-ms-grid-column-span: 8;
grid-column-end: 8;
}
.col-8\@lg {
-ms-grid-column-span: 8;
grid-column-end: span 8;
}
.col-start-8\@lg {
-ms-grid-column: 8;
grid-column-start: 8;
}
.col-end-9\@lg {
-ms-grid-column-span: 9;
grid-column-end: 9;
}
.col-9\@lg {
-ms-grid-column-span: 9;
grid-column-end: span 9;
}
.col-start-9\@lg {
-ms-grid-column: 9;
grid-column-start: 9;
}
.col-end-10\@lg {
-ms-grid-column-span: 10;
grid-column-end: 10;
}
.col-10\@lg {
-ms-grid-column-span: 10;
grid-column-end: span 10;
}
.col-start-10\@lg {
-ms-grid-column: 10;
grid-column-start: 10;
}
.col-end-11\@lg {
-ms-grid-column-span: 11;
grid-column-end: 11;
}
.col-11\@lg {
-ms-grid-column-span: 11;
grid-column-end: span 11;
}
.col-start-11\@lg {
-ms-grid-column: 11;
grid-column-start: 11;
}
.col-end-12\@lg {
-ms-grid-column-span: 12;
grid-column-end: 12;
}
.col-12\@lg {
-ms-grid-column-span: 12;
grid-column-end: span 12;
}
.col-start-12\@lg {
-ms-grid-column: 12;
grid-column-start: 12;
}
.col-end-13\@lg {
-ms-grid-column-span: 13;
grid-column-end: 13;
}
.col-start-auto\@lg {
-ms-grid-column: auto;
grid-column-start: auto;
}
.col-end-auto\@lg {
-ms-grid-column-span: auto;
grid-column-end: auto;
}
}
@media (min-width: 90rem) {
.grid-auto-xs\@xl {
--col-min-width: 8rem;
}
.grid-auto-sm\@xl {
--col-min-width: 10rem;
}
.grid-auto-md\@xl {
--col-min-width: 15rem;
}
.grid-auto-lg\@xl {
--col-min-width: 20rem;
}
.grid-auto-xl\@xl {
--col-min-width: 25rem;
}
.grid-auto-cols\@xl {
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}
.col-1\@xl {
-ms-grid-column-span: 1;
grid-column-end: span 1;
}
.col-start-1\@xl {
-ms-grid-column: 1;
grid-column-start: 1;
}
.col-end-2\@xl {
-ms-grid-column-span: 2;
grid-column-end: 2;
}
.col-2\@xl {
-ms-grid-column-span: 2;
grid-column-end: span 2;
}
.col-start-2\@xl {
-ms-grid-column: 2;
grid-column-start: 2;
}
.col-end-3\@xl {
-ms-grid-column-span: 3;
grid-column-end: 3;
}
.col-3\@xl {
-ms-grid-column-span: 3;
grid-column-end: span 3;
}
.col-start-3\@xl {
-ms-grid-column: 3;
grid-column-start: 3;
}
.col-end-4\@xl {
-ms-grid-column-span: 4;
grid-column-end: 4;
}
.col-4\@xl {
-ms-grid-column-span: 4;
grid-column-end: span 4;
}
.col-start-4\@xl {
-ms-grid-column: 4;
grid-column-start: 4;
}
.col-end-5\@xl {
-ms-grid-column-span: 5;
grid-column-end: 5;
}
.col-5\@xl {
-ms-grid-column-span: 5;
grid-column-end: span 5;
}
.col-start-5\@xl {
-ms-grid-column: 5;
grid-column-start: 5;
}
.col-end-6\@xl {
-ms-grid-column-span: 6;
grid-column-end: 6;
}
.col-6\@xl {
-ms-grid-column-span: 6;
grid-column-end: span 6;
}
.col-start-6\@xl {
-ms-grid-column: 6;
grid-column-start: 6;
}
.col-end-7\@xl {
-ms-grid-column-span: 7;
grid-column-end: 7;
}
.col-7\@xl {
-ms-grid-column-span: 7;
grid-column-end: span 7;
}
.col-start-7\@xl {
-ms-grid-column: 7;
grid-column-start: 7;
}
.col-end-8\@xl {
-ms-grid-column-span: 8;
grid-column-end: 8;
}
.col-8\@xl {
-ms-grid-column-span: 8;
grid-column-end: span 8;
}
.col-start-8\@xl {
-ms-grid-column: 8;
grid-column-start: 8;
}
.col-end-9\@xl {
-ms-grid-column-span: 9;
grid-column-end: 9;
}
.col-9\@xl {
-ms-grid-column-span: 9;
grid-column-end: span 9;
}
.col-start-9\@xl {
-ms-grid-column: 9;
grid-column-start: 9;
}
.col-end-10\@xl {
-ms-grid-column-span: 10;
grid-column-end: 10;
}
.col-10\@xl {
-ms-grid-column-span: 10;
grid-column-end: span 10;
}
.col-start-10\@xl {
-ms-grid-column: 10;
grid-column-start: 10;
}
.col-end-11\@xl {
-ms-grid-column-span: 11;
grid-column-end: 11;
}
.col-11\@xl {
-ms-grid-column-span: 11;
grid-column-end: span 11;
}
.col-start-11\@xl {
-ms-grid-column: 11;
grid-column-start: 11;
}
.col-end-12\@xl {
-ms-grid-column-span: 12;
grid-column-end: 12;
}
.col-12\@xl {
-ms-grid-column-span: 12;
grid-column-end: span 12;
}
.col-start-12\@xl {
-ms-grid-column: 12;
grid-column-start: 12;
}
.col-end-13\@xl {
-ms-grid-column-span: 13;
grid-column-end: 13;
}
.col-start-auto\@xl {
-ms-grid-column: auto;
grid-column-start: auto;
}
.col-end-auto\@xl {
-ms-grid-column-span: auto;
grid-column-end: auto;
}
}
I'm afraid this system isn't compatible with IE (IE supports only a limited number of CSS Grid properties).
This is awesome!
Thanks! :)
Great post 👍
Thanks! 🙌
Hello, I just found your work and I must say, I love how light it is but still pumping lot of work.
I might have one small comment about breakpoints. I would not use them as rem but in px instead. The thing is, px will stay static but when you change by any change font-size on html tag, it will shift also your grid and whole layout. Not speaking about dynamic font-size set on html.
Otherwise I am definitly using this and thank you very much for showing it.
Thanks for this awesome post👍👍👍
Glad to hear you liked it! 😊
I always thought it was weird that the flexbox grid system in CodyFrame used the class
.grid
. Any thought to refactoring that so that this could be used in tandem?Hi Paul! While I understand that a .grid class used for flexbox properties may sound confusing (considering we have many utility classes), I think our whole grid system replaces the purpose of CSS Grid utility classes. At this point, I'm not sure we can have a "grid system" and CSS Grid utility classes that work together without creating redundancy. However, we do have plans to inject some CSS Grid magic into the grid system of CodyFrame :)
Super grid. Help me plz,
classes don't work, why ?
<div class="col-9@lg"></div>
WORK
Pretty advance. Awesome.
I have a question. Sometimes we need to accommodate rows, how we define rows?
Thanks.
Hi there! Rows are a bit more complicated. Not in CSS per se: you can define row templates just as you would define columns, with grid-template-rows and grid-row (or grid-row-start + grid-row-end). However, it is a bit more complicated to abstract utility classes, because the number of rows you need varies from layout to layout. Probably a good idea would be introducing .row-start and .row-end classes, then take advantage of CSS Grid implicit grids.
This seems to completely undo many of the benefits of CSS Grid, like smaller, simpler, more flexible code. Your code seems needlessly verbose and complicated.
Why would I use this?
Some comments may only be visible to logged-in visitors. Sign in to view all comments.