// // 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!";
}

}