Simple SCSS + Flexbox Grid
by Scott Kaye
HTML
<div class="row">
<div class="col-1">col-1</div>
<div class="col-1">col-1</div>
<div class="col-1">col-1</div>
<div class="col-1">col-1</div>
<div class="col-1">col-1</div>
<div class="col-1">col-1</div>
<div class="col-1">col-1</div>
<div class="col-1">col-1</div>
<div class="col-1">col-1</div>
<div class="col-1">col-1</div>
<div class="col-1">col-1</div>
<div class="col-1">col-1</div>
</div>
<div class="row">
<div class="col-2">col-2</div>
<div class="offset-4">offset-4</div>
<div class="col-6">col-6</div>
</div>
<div class="row">
<div class="col-2">col-2</div>
<div class="col-fill">col-fill (as big as possible)</div>
<div class="col-4">col-4</div>
</div>
<div class="row">
<div class="col-7">
<p>Heights are equal across sibling rows, thanks to flexbox.</p>
<p>Apply the <code>grid-helper</code> class to visualize the grid.</p>
<div class="row grid-helper">
<div class="col-4">col-4</div>
<div class="col-4">col-4</div>
<div class="col-4">col-4</div>
</div>
</div>
<div class="col-5">col-5</div>
</div>
<div class="row">
<div class="col-4">
<p>Apply the <code>col-square</code> class to a column to ensure its width and height are always equal. Try resizing the screen!</p>
</div>
<div class="col-2 col-square">
<div class="col-square-content">
col-2, col-square
</div>
</div>
<div class="col-6">
<p>To display content within the square, add it to a child with class <code>col-square-content</code>.</p>
</div>
</div>
SCSS
@function col($span, $total: 12, $gutter: 10px) {
@return calc(#{$span / $total * 100%} - (#{1 - $span / $total}) * #{$gutter});
}
$gutter: 10px;
$columns: 12;
.row {
display: flex;
margin-bottom: $gutter;
&:last-child {
margin-bottom: 0;
}
}
%col-base {
box-sizing: border-box;
overflow: hidden;
}
@for $i from 1 through $columns {
.offset-#{$i} {
flex-grow: 0;
flex-shrink: 0;
flex-basis: col($i, $columns);
margin-right: $gutter;
}
.col-#{$i} {
@extend %col-base;
@extend .offset-#{$i};
&:last-child {
margin-right: 0;
}
}
}
.col-fill {
@extend %col-base;
flex: 0 1 100%;
margin-right: $gutter;
}
.col-square {
position: relative;
&::after {
content: "";
display: block;
padding-bottom: 100%;
}
> .col-square-content {
@extend %col-base;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
}
// Grid helper
.grid-helper {
$helper-color: rgba(#188, 0.5);
@function generateGradient() {
$out: "";
@for $i from 1 through $columns {
$out: $out + $helper-color + col($i, $columns) + ",";
$out: $out + "transparent " + col($i, $columns) + ",";
$out: $out + "transparent calc(" + col($i, $columns) + " + " + $gutter + "),";
$out: $out + $helper-color + "calc(" + col($i, $columns) + " + " + $gutter + ")";
@if $i != $columns {
$out: $out + ",";
}
}
@return $out;
}
background: linear-gradient(90deg, $helper-color, #{generateGradient()});
}
// Presentation
@font-face {
font-family: system;
font-style: normal;
font-weight: 300;
src: local(".SFNSText-Light"), local(".HelveticaNeueDeskInterface-Light"), local(".LucidaGrandeUI"), local("Ubuntu Light"), local("Segoe UI"), local("Roboto"), local("DroidSans"), local("Tahoma");
}
body {
font-family: system;
}
p {
margin-top: 0;
}
%col-base {
outline: 1px solid #ccc;
box-shadow: 2px 2px 4px #ddd;
padding: 10px;
}
.col-square {
background: radial-gradient(#ddd 30%, #fff 31%);
}
code...