Skip to content

Instantly share code, notes, and snippets.

@makenosound
Last active December 14, 2015 11:38
Show Gist options
  • Save makenosound/5080205 to your computer and use it in GitHub Desktop.
Save makenosound/5080205 to your computer and use it in GitHub Desktop.
A flexible grid structure using SASS and placeholder classes
// Configurables
$flexibleGridColumns: 24 !default;
$flexibleGridColumnWidth: 30px !default;
$flexibleGridGutterWidth: 18px !default;
// Full width of a row
$flexibleGridRowWidth: ($flexibleGridColumns * $flexibleGridColumnWidth) + ($flexibleGridGutterWidth * ($flexibleGridColumns - 1));
// The width of a column
$flexibleGridGridWidth: percentage($flexibleGridColumnWidth / $flexibleGridRowWidth);
// The amount of margin between columns
$flexibleGridGridMargin: percentage($flexibleGridGutterWidth / $flexibleGridRowWidth);
@mixin flexible-grid-wrapper {
@extend %clearfix; // Assumes a %clearfix placeholder exists
margin: 0 auto;
max-width: $flexibleGridRowWidth;
width: 100%;
}
@mixin flexible-grid-row {
padding-left: 20px;
padding-right: 20px;
}
//
// Main mixin, set the width of `$columns` columns
// Can be changed based on the width of the parent column. I.e., to create a 4Column
// <div> inside a 10Column <div> you would do the following:
//
// @include flexible-grid-column(4, false, 10);
//
//
@mixin flexible-grid-column($columns, $last: false, $parent: $flexibleGridColumns) {
width: flexiSpan($columns, $parent);
@if $last {
margin-right: 0; }
@else {
margin-right: flexiMargin($flexibleGridGridMargin, $parent); }
}
@mixin flexible-grid-push($columns, $parent: $flexibleGridColumns) {
margin-left: flexiPushMargin($columns, $parent);
}
// Function to calculate width in context
@function flexiSpan($columns, $parent: $flexibleGridColumns) {
@return ($flexibleGridGridWidth * $columns + $flexibleGridGridMargin * ($columns - 1)) / ($flexibleGridGridWidth * $parent + $flexibleGridGridMargin * ($parent - 1)) * 100%;
}
// Function to calculate margins in context
@function flexiMargin($margin, $parent: $flexibleGridColumns) {
@return $margin / flexiSpan($parent) * 100%;
}
// Function to calculate push in context
@function flexiPushMargin($columns, $parent: $flexibleGridColumns) {
@return ($flexibleGridGridWidth * $columns + $flexibleGridGridMargin * $columns) / ($flexibleGridGridWidth * $parent + $flexibleGridGridMargin * ($parent - 1)) * 100%;
}
// Output as classes for use
@mixin flexible-grid-classes($gridClass: "grid", $rowClass: "row", $wrapperClass: "wrapper", $lastClass: "last", $silent: true) {
// Shared properties for all grid objects
%#{$gridClass} {
display: inline;
float: left;
}
// Create two levels of nested %placeholders
@for $i from 1 through $flexibleGridColumns {
// %grid-n { ... }
%#{$gridClass}-#{$i} {
@if $silent == true { @extend %#{$gridClass}; } // Don’t extend if outputting classes
@include flexible-grid-column($i);
%#{$lastClass} {
margin-right: 0;
}
}
// Generate unnested %placeholders for where structure
// is not implicit:
//
// %grid-parent-child { ... }
//
@for $c from 1 through $i - 1 {
%#{$gridClass}-#{$i}-#{$c} {
@if $silent == true { @extend %#{$gridClass}; } // Don’t extend if outputting classes
@include flexible-grid-column($c, false, $i);
}
}
// Output two levels of nested .classes
@if $silent == false {
// .grid-n { ... }
.#{$gridClass}-#{$i} {
@extend %#{$gridClass}-#{$i};
// .grid-n .grid-n { ... }
@for $c from 1 through $i - 1 {
.#{$gridClass}-#{$c} {
@extend %#{$gridClass}-#{$i}-#{$c};
}
}
}
}
}
%#{$rowClass} {
@include flexible-grid-row;
}
%#{$wrapperClass} {
@include flexible-grid-wrapper;
}
%#{$lastClass} {
margin-right: 0;
}
// Output proper .classes for top level objects
@if $silent == false {
.#{$gridClass},
[class^="#{$gridClass}-"],
[class*=" #{$gridClass}-"] {
@extend %#{$gridClass};
}
.#{$rowClass} {
@extend %#{$rowClass};
}
.#{$wrapperClass} {
@extend %#{$wrapperClass};
}
.#{$lastClass} {
@extend %#{$lastClass};
}
}
}
// Usage:
//
// @include flexible-grid-classes($silent: false);
// @include flexible-grid-classes();
//
// Unfortunately you have to be explicit about the nesting you want
// as SASS isn’t capable of understanding nested placeholders properly.
//
// @include flexible-grid-classes;
//
// article {
// @extend %grid-12;
//
// aside {
// @extend %grid-12-6;
// }
// }
//
// If you’re using placeholder with `$silent: true;` set you’ll also need to
// `@extend` the `%grid` placeholder. It’s excluded to avoid bloat when
// including the proper `.grid` classes.
//
// @include flexible-grid-classes($silent: false);
//
// article {
// @extend %grid;
// @extend %grid-12;
//
// aside {
// @extend %grid;
// @extend %grid-12-6;
// }
// }
//
// Only two levels of nesting is supported to stop things getting out of control.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment