// // Flexbones Grid System // // Version 0.1.1 // Author: Rory Ashford //
// Set variable defaults
$column_name: “span–” !default; $push_name: “push–” !default; $debug_display: false !default;
// Clearfix mixin // // Used to clear the floats within each grid @mixin clearfix() {
*zoom:1; &:before, &:after { content:""; display:table; flex-basis: 0; // flexbox clear fix order: 1; // flexbox clear fix } &:after { clear:both; }
}
// Column Width // // Works out the percent width of columns (gutters can be // any unit but columns are always percent bases) @function column-width($number_of_columns,$total_columns) {
$single_col_width: 100 / $total_columns * 1%; @return $single_col_width * $number_of_columns;
}
// At Breakpoint // // A mixin for outputting inline media queries // Just supply a Sass list as an argument with a min/max // If there are no min and max values supplied then it // doesnt ouput a media query @mixin at-breakpoint($min,$max:null){
@if($max == null and $min != null){ @media (min-width: $min){ @content; } } @elseif($min == null and $max == null) { @content; } @else{ @media (min-width: $min) and (max-width: $max){ @content; } }
}
// Span Columns // // Used to set grids semantically from within // the stylesheet with no additional HTML markup @mixin span-columns($columns, $total_columns){
width: column-width($columns,$total_columns); padding-left: $gutter-width;
}
// Grid // // Called once per breakpoint as the gutters may be different // Float all direct children of the grid. // Adds negative padding to each row // Display flex and flex-wrap are used here to prevent content from // floating into above elements @mixin grid($gutter){
.grid{ margin-left: -$gutter; @include clearfix(); } // Float children .grid > * { float: left; position: relative; padding-left: $gutter; }
}
// Equal height Grid items // // Uses flexbox so no IE support but there is a polyfill: // osvaldas.info/flexbox-based-responsive-equal-height-blocks-with-javascript-fallback // // EXPERIMENTAL (Disabled in current build) // feels extremely hacky, doesnt scale particularly well // should it be called per media query? @mixin grid-equal-height($gutter,$column_name){
.grid--equal-height{ display: flex; flex-wrap: wrap; > * { display: flex; // ugly ass fix for block level elements 100% children of adisplay: flex container. > * { width: 100%; } } }
}
// Grid with no gutters @mixin grid-no-gutter($column_class,$suffix: null){
.grid--no-gutter#{$suffix}{ margin-left: 0; > * { padding-left: 0; } }
}
// Equivalent Fractions // // This function will add additional classes // to make the grid system more expressive. // Instead of writing 3/12 you can also write 1/4 // with this function @function equivalent-fractions($numerator,$denominator){
$fractions: (); @for $i from -$numerator through -1{ @if($numerator % abs($i) == 0 and $denominator % abs($i) == 0){ $fraction: (abs($i): #{$numerator/abs($i)}-#{$denominator/abs($i)}); $fractions: map-merge($fractions, $fraction); } } // return map of all fractions @return $fractions;
}
// Grid Columns // // Set the grid column widths based on the number of // columns divided by the total number of columns. @mixin grid-columns($prefix: null, $suffix: null, $columns: null, $fifths: false, $sevenths: false){
@for $i from 1 through $columns{ $css_classes: equivalent-fractions($i,$columns); $column_class: null; @each $key, $css_class in $css_classes{ $full_css_class: #{$prefix}#{$css-class}#{$suffix}; $column_class: $column_class, $full_css_class; } #{$column_class}{ width: column-width($i,$columns); } } // Add fifths where total columns // dont divide into fifths. @if($fifths == true){ @for $i from 1 through 5{ $fifth_class: #{$prefix}#{$i}-5#{$suffix}; #{$fifth_class}{ width: column-width($i,5); } } } // Add sevenths where total columns // dont divide into sevenths. @if($sevenths == true){ @for $i from 1 through 7{ $seventh_class: #{$prefix}#{$i}-7#{$suffix}; #{$seventh_class}{ width: column-width($i,7); } } }
}
// Push Class // // Set the push classes that will incrementally indent // the column by a maximum number of total-columns -1 @mixin grid-push($prefix: null, $suffix: null, $columns: null){
@for $i from 1 through $columns - 1{ $css_classes: equivalent-fractions($i,$columns); $push_class: null; @each $key, $css_class in $css_classes{ $full_css_class: #{$prefix}#{$css_class}#{$suffix}; $push_class: $push_class, $full_css_class; } #{$push_class}{ margin-left: column-width($i,$columns); } }
}
// Omega class // // An omega declaration that is breakpoint specific // Basically it floats an element to the right taking // it out of order potentially. @mixin grid-omega($prefix: null, $suffix: null){
#{$prefix}omega#{$suffix} { float: right; }
}
// Debug // // Outputs the current breakpoint name to quickly debug // each breakpoint. @mixin grid-debug($breakpoint_name,$debug_bg: #000){
body:after{ position: fixed; display: block; bottom: 10px; right: 10px; padding: 5px 20px; font-size: 14px; font-weight: bold; color: white; background: $debug-bg; content: "#{$breakpoint-name}"; }
}
// Grid Generate // // Pulls the whole thing together ready for output // kept seperate from grid-generate as it is DRYer // this way. @mixin grid-generate($grid_args){
// If config has been defined in grid args use those settings // // Falls back to defaults at the top of this document @if( map-has-key($grid_args, config )){ // If columnclass has been defined @if( map-has-key(map-get($grid_args, config), columnclass) ){ $column_name: map-get(map-get($grid_args, config), columnclass); } // If pushclass has been defined @if( map-has-key(map-get($grid_args, config), pushclass) ){ $push_name: #{'.' + map-get(map-get($grid_args, config), pushclass)}; } // If debug has been defined @if( map-has-key(map-get($grid_args, config), debug) ){ $debug_display: map-get(map-get($grid_args, config), debug); } } // Check that there are defined grids @if( map-has-key($grid_args, grids )) { $grids: map-get($grid_args, grids); $column_prefix: #{'.' + $column_name}; $push_prefix: #{'.' + $push_name}; @each $grid_name, $grid_map in $grids{ // Set defaults // // If args are not defined the grid falls back to these values $columns: 12 !default; $suffix: null !default; $breakpoint: null !default; $gutter: 24px !default; $debug-bg: #000 !default; $debug-name: $grid_name !default; // If column class has been defined @if( map-has-key($grid_map, columns) ){ $columns: map-get($grid_map,columns); } // If column class has been defined @if( map-has-key($grid_map, suffix) ){ $suffix: map-get($grid_map,suffix); } // If column class has been defined @if( map-has-key($grid_map, breakpoint) ){ $breakpoint: map-get($grid_map,breakpoint); } // If column class has been defined @if( map-has-key($grid_map, gutter) ){ $gutter: map-get($grid_map,gutter); } // Debug info @if( map-has-key($grid_map, debug)) { // If debug background is defined @if( map-has-key(map-get($grid_map, debug), background) ){ $debug-bg: map-get(map-get($grid_map, debug), background); } // If debug name is defined @if( map-has-key(map-get($grid_map, debug), name) ){ $debug-name: map-get(map-get($grid_map, debug), name); } } // Include the necessary mixins to generate the grids @include at-breakpoint($breakpoint){ @include grid($gutter); @include grid-no-gutter($column_name,$suffix); @include grid-columns($column_prefix,$suffix,$columns,true, true); @include grid-push($push_prefix, $suffix, $columns); @include grid-omega($column_prefix, $suffix); // Display debugging info @if( $debug_display == true ){ @include grid-debug($debug_name,$debug_bg) } } } } @else{ @warn "No grids defined!"; }
}