This grid system features 5 breakpoints: xlarge, large, medium, small, and xsmall, allowing for responsive mobile-first design across various devices.
// These are based off Foundation defaults.
$breakpoint-phone: 0; // xsmall
$breakpoint-tablet: 640px; // small
$breakpoint-laptop: 1024px; // medium
$breakpoint-desktop: 1200px; // large
$breakpoint-tv: 1440px; // xlarge
It supports flexible and constrained grids with adjustable gaps, dynamic row and column management, and customizable column and row spans.
The system includes utility classes for gap adjustments and ensures content stays within bounds to prevent overflow.
Additionally, there is a playground for real-time visualization.
To use it, add a single SCSS file to your project. All breakpoints are controlled by variables within this file, and those can be moved to _settings.scss as long as _grid.scss is imported afterwards.
Download the SCSS file by clicking the button below, or click the "View Code" button and copy and paste it into your project as _grid.scss, reference it from your main.scss file and you're ready to build your first grid.
// Foundation Grid Values: https://get.foundation/sites/docs/media-queries.html#changing-the-breakpoints
$breakpoint-phone: 0;
$breakpoint-tablet: 640px;
$breakpoint-laptop: 1024px;
$breakpoint-desktop: 1200px;
$breakpoint-tv: 1440px;
$default-gap: 32px;
$available-gaps: (4px, 8px, 16px, 30px, 32px, 64px, 128px);
// Mixin to create fixed grid columns with adjustable gap
@mixin create-grid($columns, $gap) {
display: grid;
grid-template-columns: repeat($columns, minmax(0, 1fr));
gap: $gap;
width: 100%;
}
// Mixin to create flexible grid columns with adjustable gap
@mixin create-flex-grid($gap) {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
gap: $gap;
width: 100%;
}
// Base grid class for flexible responsive layout
.grid {
@include create-flex-grid($default-gap); // Default to a flexible grid with default gap
}
// Map for grid container settings
$grid-container-settings: (
phone: (16px, 95%, $breakpoint-phone), // xsmall
tablet: (24px, 100%, $breakpoint-tablet), // small
laptop: (32px, 100%, $breakpoint-laptop), // medium
desktop: (48px, 100%, $breakpoint-desktop), // large
tv: (64px, 100%, $breakpoint-tv) // xlarge
);
// Grid container with responsive padding and width
.grid-container {
margin: 0 auto;
@each $breakpoint, $settings in $grid-container-settings {
$padding: nth($settings, 1);
$width: nth($settings, 2);
$max-width: nth($settings, 3);
@media (min-width: #{$max-width}) {
padding-left: $padding;
padding-right: $padding;
width: calc(#{$width} - #{$padding} * 2);
// No max width on small breakpoint for container.
@if $breakpoint != phone {
max-width: calc(#{$max-width} - #{$padding} * 2);
}
}
}
}
// Generate grid column classes for different breakpoints
@each $breakpoint, $prefix in (
$breakpoint-phone: "-xsmall-",
$breakpoint-tablet: "-small-",
$breakpoint-laptop: "-medium-",
$breakpoint-desktop: "-large-",
$breakpoint-tv: "-xlarge-"
) {
@for $i from 1 through 12 {
@media (min-width: #{$breakpoint}) {
.grid-cols#{$prefix}#{$i} {
@include create-grid($i, $default-gap);
}
}
}
}
// Generate gap classes
@each $gap in $available-gaps {
.grid-gap-#{$gap} {
gap: $gap;
}
}
// Generate column span classes for different breakpoints
@each $breakpoint, $prefix in (
$breakpoint-phone: "-xsmall-",
$breakpoint-tablet: "-small-",
$breakpoint-laptop: "-medium-",
$breakpoint-desktop: "-large-",
$breakpoint-tv: "-xlarge-"
) {
@for $i from 1 through 12 {
@media (min-width: #{$breakpoint}) {
.grid-col-span#{$prefix}#{$i} {
grid-column: span #{$i};
}
.grid-col#{$prefix}#{$i} {
grid-column: span #{$i};
}
.grid-row-span#{$prefix}#{$i} {
grid-row: span #{$i};
}
.grid-row#{$prefix}#{$i} {
grid-row: span #{$i};
}
}
}
}
Your first grid can be as simple as the below:
<div class="grid-container">
<div class="grid">
<div>Grid Item</div>
<div>Grid Item</div>
</div>
</div>
Copy and paste the above into the playground to see a flexible two column automatically responsive grid.
If you add more div's as children of the main grid div (the <div class="grid">), it will automatically add a new grid item and make your grid a three column grid. Try it out in the playground.
Any block level element that is a child of the main grid div becomes a grid item. No special classes needed.
The above grid was what we call a flexible grid. It has no constraints, so it does not care how many children it has, it will always try to fill the space by making the children equal distance and widths from each other.
To make your first constrained grid, we'll need some additional classnames. An example of a 6 column grid is below.
<div class="grid-container">
<div class="grid grid-cols-large-6">
<div>Grid Item 1</div>
<div>Grid Item 2</div>
<div>Grid Item 3</div>
<div>Grid Item 4</div>
<div>Grid Item 5</div>
<div>Grid Item 6</div>
<div>Grid Item 7</div>
<div>Grid Item 8</div>
<div>Grid Item 9</div>
<div>Grid Item 10</div>
<div>Grid Item 11</div>
<div>Grid Item 12</div>
</div>
</div>
Copy and paste the above into the playground to see your 6 column grid, it has 12 items, but they're on two rows with six columns per row.
This is achieved by the grid-cols-large-6 class. To break this down, it starts with grid-cols, then the breakpoint, then the number of cols. Note, we'll cover breakpoints in the next section.
So if you wanted to show a 12 col grid for large screens, you'd use the class name of grid-cols-large-12
Now it's time to make a grid that is constrained and responsive.
The breakpoints we have available are: xlarge, large, medium, small and xsmall.
You do not need to use all of them on every grid, if you only used large and small, the grid would still be responsive. The other breakpoints are for finer grained control.
Let's make a grid that will show 12 columns on the large breakpoint, 6 columns on the medium breakpoint, and 1 column on the small breakpoint:
<div class="grid-container">
<div class="grid grid-cols-large-12 grid-cols-medium-6 grid-cols-small-1">
<div>Grid Item 1</div>
<div>Grid Item 2</div>
<div>Grid Item 3</div>
<div>Grid Item 4</div>
<div>Grid Item 5</div>
<div>Grid Item 6</div>
<div>Grid Item 7</div>
<div>Grid Item 8</div>
<div>Grid Item 9</div>
<div>Grid Item 10</div>
<div>Grid Item 11</div>
<div>Grid Item 12</div>
</div>
</div>
Copy and paste the above into the playground to see the result. You will have to resize your browser to see the responsive changes. The current breakpoint is always displayed at the top of your screen.
This works because we have specified the number of cols we want after every breakpoint in our classnames. As an example, grid-cols-small-1 means "only show one column on small breakpoints".
Below are some more detailed examples of all sorts of different types of grid, along with code you can paste into the playground to modify.
View Code
<div class="grid-container">
<div class="grid grid-cols-xsmall-2 grid-cols-small-4 grid-cols-medium-6 grid-cols-large-12">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
<div>Item 11</div>
<div>Item 12</div>
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
<div>Item 11</div>
<div>Item 12</div>
</div>
</div>
View Code
<div class="grid-container">
<div class="grid grid-cols-xsmall-1 grid-cols-small-2 grid-cols-medium-4 grid-cols-large-8">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
<div>Item 11</div>
<div>Item 12</div>
<div>Item 13</div>
<div>Item 14</div>
<div>Item 15</div>
<div>Item 16</div>
</div>
</div>
View Code
<div class="grid-container">
<div class="grid grid-cols-xsmall-1 grid-cols-small-2 grid-cols-medium-3 grid-cols-large-6">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
<div>Item 11</div>
<div>Item 12</div>
</div>
</div>
View Code
<div class="grid-container">
<div class="grid grid-cols-xsmall-1 grid-cols-small-1 grid-cols-medium-2 grid-cols-large-4">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
<div>Item 11</div>
<div>Item 12</div>
</div>
</div>
View Code
<div class="grid-container">
<div class="grid grid-cols-xsmall-1 grid-cols-small-1 grid-cols-medium-2 grid-cols-large-3">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
<div>Item 11</div>
<div>Item 12</div>
</div>
</div>
View Code
<div class="grid-container">
<div class="grid grid-cols-xsmall-1 grid-cols-small-1 grid-cols-medium-2 grid-cols-large-2">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
<div>Item 11</div>
<div>Item 12</div>
</div>
</div>
View Code
<div class="grid-container">
<div class="grid">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
<div>Item 11</div>
<div>Item 12</div>
</div>
</div>
View Code
<div class="grid-container-full-width">
<div class="grid grid-cols-xsmall-2 grid-cols-small-4 grid-cols-medium-6 grid-cols-large-12">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
<div>Item 11</div>
<div>Item 12</div>
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
<div>Item 11</div>
<div>Item 12</div>
</div>
</div>
Grid items can also span multiple columns or rows, with responsive classes. For example, an item can span 4 columns on the xlarge breakpoint and 3 columns on the large breakpoint.
This is done using the classes .grid-col-BREAKPOINT-AMOUNT and .grid-row-BREAKPOINT-AMOUNT
Note: Alternative classes exist if you prefer to be verbose: .grid-col-span-BREAKPOINT-AMOUNT and .grid-row-span-BREAKPOINT-AMOUNT
Please see the below example:
<div class="grid-container">
<div class="grid gap-16px grid-cols-large-4">
<div class="grid-row-medium-1 grid-row-large-2">Spans Two Rows</div>
<div class="grid-row-medium-1 grid-col-large-2">Spans Two Columns</div>
<div class="grid-col-large-1">Spans One Column</div>
<div class="grid-row-medium-1 grid-col-large-2">Spans Two Columns</div>
<div class="grid-col-large-1">Spans One Column</div>
</div>
</div>
Copy and paste the above into the playground to see the result.
More detailed examples are below.
View Code
<div class="grid-container">
<div class="grid grid-cols-xsmall-1 grid-cols-small-3 grid-cols-medium-6 grid-cols-large-8">
<div class="grid-col-large-4">Item 1 .grid-col-large-4</div>
<div class="grid-col-large-8">Item 2 .grid-col-large-8</div>
<div class="grid-col-large-2">Item 3 .grid-col-large-2</div>
<div class="grid-col-large-10">Item 4 .grid-col-large-10</div>
<div class="grid-col-large-6">Item 5 .grid-col-large-6</div>
<div class="grid-col-large-4">Item 6 .grid-col-large-4</div>
<div class="grid-col-large-2">Item 7 .grid-col-large-2</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
<div class="grid-col-large-9">Item 11 .grid-col-large-9</div>
<div class="grid-col-large-12">Item 12</div>
</div>
</div>
View Code
<div class="grid-container">
<div class="grid grid-cols-xsmall-1 grid-cols-small-3 grid-cols-medium-6 grid-cols-large-6">
<div class="grid-row-large-3">Item 1 .grid-row-large-3</div>
<div>Item 2</div>
<div>Item 3</div>
<div class="grid-row-large-3">Item 4 .grid-row-large-3</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div class="grid-row-large-2">Item 8 .grid-row-large-2</div>
<div>Item 9</div>
<div class="grid-row-large-2">Item 10 .grid-row-large-2</div>
<div>Item 11</div>
<div>Item 12</div>
</div>
</div>
View Code
<div class="grid-container">
<div class="grid grid-cols-xsmall-1 grid-cols-small-3 grid-cols-medium-4 grid-cols-large-4">
<div class="grid-row-large-4">Item 1 .grid-row-large-4</div>
<div class="grid-col-large-2">Item 2 .grid-col-large-2</div>
<div class="grid-col-large-1">Item 3</div>
<div class="grid-row-large-3">Item 4 .grid-row-large-3</div>
<div class="grid-row-large-2 grid-col-large-1">Item 5 .grid-row-large-2</div>
<div class="grid-row-large-2 grid-col-large-1">Item 6 .grid-row-large-2</div>
<div class="grid-col-large-2">Item 7 .grid-col-large-2</div>
<div class="grid-row-large-2">Item 8 .grid-row-large-2</div>
<div class="grid-col-large-1">Item 9</div>
<div class="grid-row-large-2 grid-col-large-2">Item 10 .grid-row-large-2 .grid-col-large-2</div>
<div class="grid-col-large-1">Item 11</div>
</div>
</div>
The gap between grid items is globally controlled by the $default-gap variable within _grid.scss, but you can also set it using grid-gap classes:
<div class="grid grid-gap-4px">...</div>
<div class="grid grid-gap-8px">...</div>
<div class="grid grid-gap-16px">...</div>
<div class="grid grid-gap-30px">...</div>
<div class="grid grid-gap-32px">...</div>
<div class="grid grid-gap-64px">...</div>
<div class="grid grid-gap-128px">...</div>
Note: The grid above uses a custom gap of 16px, while the default gap for this page is 32px.
The grid-gap-{number}px classes are defined within _grid.scss and can be changed.
Consider "tightening up" a previous example using the grid-gap css class:
<div class="grid-container">
<div class="grid grid-gap-4px grid-cols-xsmall-1 grid-cols-small-3 grid-cols-medium-4 grid-cols-large-4">
<div class="grid-row-large-4">Item 1 .grid-row-large-4</div>
<div class="grid-col-large-2">Item 2 .grid-col-large-2</div>
<div class="grid-col-large-1">Item 3</div>
<div class="grid-row-large-3">Item 4 .grid-row-large-3</div>
<div class="grid-row-large-2 grid-col-large-1">Item 5 .grid-row-large-2</div>
<div class="grid-row-large-2 grid-col-large-1">Item 6 .grid-row-large-2</div>
<div class="grid-col-large-2">Item 7 .grid-col-large-2</div>
<div class="grid-row-large-2">Item 8 .grid-row-large-2</div>
<div class="grid-col-large-1">Item 9</div>
<div class="grid-row-large-2 grid-col-large-2">Item 10 .grid-row-large-2 .grid-col-large-2</div>
<div class="grid-col-large-1">Item 11</div>
</div>
</div>
Copy and paste the above into the playground to see the result.