Last active
October 16, 2018 10:19
-
-
Save niklasravnsborg/bb3411cc4007fea7c055 to your computer and use it in GitHub Desktop.
Foundation Grid - without Foundation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// RANGES | |
// We use these functions to define ranges for various things, like media queries. | |
@function lower-bound($range){ | |
@if length($range) <= 0 { | |
@return 0; | |
} | |
@return nth($range,1); | |
} | |
@function upper-bound($range) { | |
@if length($range) < 2 { | |
@return 999999999999; | |
} | |
@return nth($range, 2); | |
} | |
// STRIP UNIT | |
// It strips the unit of measure and returns it | |
@function strip-unit($num) { | |
@return $num / ($num * 0 + 1); | |
} | |
// This is the default html and body font-size for the base rem value. | |
$rem-base: 16px !default; | |
// CONVERT TO REM | |
@function convert-to-rem($value, $base-value: $rem-base) { | |
$value: strip-unit($value) / strip-unit($base-value) * 1rem; | |
@if ($value == 0rem) { $value: 0; } // Turn 0rem into 0 | |
@return $value; | |
} | |
@function data($attr) { | |
@if $namespace { | |
@return '[data-' + $namespace + '-' + $attr + ']'; | |
} | |
@return '[data-' + $attr + ']'; | |
} | |
// REM CALC | |
// New Syntax, allows to optionally calculate on a different base value to counter compounding effect of rem's. | |
// Call with 1, 2, 3 or 4 parameters, 'px' is not required but supported: | |
// | |
// rem-calc(10 20 30px 40); | |
// | |
// Space delimited, if you want to delimit using comma's, wrap it in another pair of brackets | |
// | |
// rem-calc((10, 20, 30, 40px)); | |
// | |
// Optionally call with a different base (eg: 8px) to calculate rem. | |
// | |
// rem-calc(16px 32px 48px, 8px); | |
// | |
// If you require to comma separate your list | |
// | |
// rem-calc((16px, 32px, 48), 8px); | |
@function rem-calc($values, $base-value: $rem-base) { | |
$max: length($values); | |
@if $max == 1 { @return convert-to-rem(nth($values, 1), $base-value); } | |
$remValues: (); | |
@for $i from 1 through $max { | |
$remValues: append($remValues, convert-to-rem(nth($values, $i), $base-value)); | |
} | |
@return $remValues; | |
} | |
// | |
// @variables | |
// | |
$include-html-grid-classes: true !default; | |
$include-xl-html-grid-classes: false !default; | |
$row-width: rem-calc(1000) !default; | |
$total-columns: 12 !default; | |
$last-child-float: right !default; | |
$default-float: left !default; | |
$opposite-direction: right !default; | |
$column-gutter: rem-calc(30) !default; | |
// Media Query Ranges | |
$small-range: (0, 40em) !default; | |
$medium-range: (40.063em, 64em) !default; | |
$large-range: (64.063em, 90em) !default; | |
$xlarge-range: (90.063em, 120em) !default; | |
$xxlarge-range: (120.063em, 99999999em) !default; | |
$screen: "only screen" !default; | |
$landscape: "#{$screen} and (orientation: landscape)" !default; | |
$portrait: "#{$screen} and (orientation: portrait)" !default; | |
$small-up: $screen !default; | |
$small-only: "#{$screen} and (max-width: #{upper-bound($small-range)})" !default; | |
$medium-up: "#{$screen} and (min-width:#{lower-bound($medium-range)})" !default; | |
$medium-only: "#{$screen} and (min-width:#{lower-bound($medium-range)}) and (max-width:#{upper-bound($medium-range)})" !default; | |
$large-up: "#{$screen} and (min-width:#{lower-bound($large-range)})" !default; | |
$large-only: "#{$screen} and (min-width:#{lower-bound($large-range)}) and (max-width:#{upper-bound($large-range)})" !default; | |
$xlarge-up: "#{$screen} and (min-width:#{lower-bound($xlarge-range)})" !default; | |
$xlarge-only: "#{$screen} and (min-width:#{lower-bound($xlarge-range)}) and (max-width:#{upper-bound($xlarge-range)})" !default; | |
$xxlarge-up: "#{$screen} and (min-width:#{lower-bound($xxlarge-range)})" !default; | |
$xxlarge-only: "#{$screen} and (min-width:#{lower-bound($xxlarge-range)}) and (max-width:#{upper-bound($xxlarge-range)})" !default; | |
// We use this to do clear floats | |
@mixin clearfix { | |
&:before, &:after { content: " "; display: table; } | |
&:after { clear: both; } | |
} | |
// IMPORT ONCE | |
// We use this to prevent styles from being loaded multiple times for components that rely on other components. | |
$modules: () !default; | |
@mixin exports($name) { | |
// Import from global scope | |
$modules: $modules !global; | |
// Check if a module is already on the list | |
$module_index: index($modules, $name); | |
@if (($module_index == null) or ($module_index == false)) { | |
$modules: append($modules, $name) !global; | |
@content; | |
} | |
} | |
// | |
// Grid Functions | |
// | |
// @FUNCTION | |
// $colNumber - Found in settings file | |
// $totalColumns - Found in settings file | |
@function grid-calc($colNumber, $totalColumns) { | |
@return percentage(($colNumber / $totalColumns)); | |
} | |
// | |
// @mixins | |
// | |
// For creating container, nested, and collapsed rows. | |
// | |
// | |
// $behavior - Any special behavior for this row? Default: false. Options: nest, collapse, nest-collapse, false. | |
@mixin grid-row($behavior: false) { | |
// use @include grid-row(nest); to include a nested row | |
@if $behavior == nest { | |
width: auto; | |
margin-#{$default-float}: -($column-gutter/2); | |
margin-#{$opposite-direction}: -($column-gutter/2); | |
margin-top: 0; | |
margin-bottom: 0; | |
max-width: none; | |
} | |
// use @include grid-row(collapse); to collapsed a container row margins | |
@else if $behavior == collapse { | |
width: 100%; | |
margin: 0; | |
max-width: $row-width; | |
} | |
// use @include grid-row(nest-collapse); to collapse outer margins on a nested row | |
@else if $behavior == nest-collapse { | |
width: auto; | |
margin: 0; | |
max-width: none; | |
} | |
// use @include grid-row; to use a container row | |
@else { | |
width: 100%; | |
margin-#{$default-float}: auto; | |
margin-#{$opposite-direction}: auto; | |
margin-top: 0; | |
margin-bottom: 0; | |
max-width: $row-width; | |
} | |
// Clearfix for all rows | |
@include clearfix(); | |
} | |
// Creates a column, should be used inside of a media query to control layouts | |
// | |
// $columns - The number of columns this should be | |
// $last-column - Is this the last column? Default: false. | |
// $center - Center these columns? Default: false. | |
// $offset - # of columns to offset. Default: false. | |
// $push - # of columns to push. Default: false. | |
// $pull - # of columns to pull. Default: false. | |
// $collapse - Get rid of gutter padding on column? Default: false. | |
// $float - Should this float? Default: true. Options: true, false, left, right. | |
@mixin grid-column( | |
$columns:false, | |
$last-column:false, | |
$center:false, | |
$offset:false, | |
$push:false, | |
$pull:false, | |
$collapse:false, | |
$float:true, | |
$position:false) { | |
// If positioned for default .column, include relative position | |
// push and pull require position set | |
@if $position or $push or $pull { | |
position: relative; | |
} | |
// If collapsed, get rid of gutter padding | |
@if $collapse { | |
padding-left: 0; | |
padding-right: 0; | |
} | |
// Gutter padding whenever a column isn't set to collapse | |
// (use $collapse:null to do nothing) | |
@else if $collapse == false { | |
padding-left: ($column-gutter / 2); | |
padding-right: ($column-gutter / 2); | |
} | |
// If a column number is given, calculate width | |
@if $columns { | |
width: grid-calc($columns, $total-columns); | |
// If last column, float naturally instead of to the right | |
@if $last-column { float: $opposite-direction; } | |
} | |
// Source Ordering, adds left/right depending on which you use. | |
@if $push { #{$default-float}: grid-calc($push, $total-columns); #{$opposite-direction}: auto; } | |
@if $pull { #{$opposite-direction}: grid-calc($pull, $total-columns); #{$default-float}: auto; } | |
@if $float { | |
@if $float == left or $float == true { float: $default-float; } | |
@else if $float == right { float: $opposite-direction; } | |
@else { float: none; } | |
} | |
// If centered, get rid of float and add appropriate margins | |
@if $center { | |
margin-#{$default-float}: auto; | |
margin-#{$opposite-direction}: auto; | |
float: none; | |
} | |
// If offset, calculate appropriate margins | |
@if $offset { margin-#{$default-float}: grid-calc($offset, $total-columns) !important; } | |
} | |
// Create presentational classes for grid | |
// | |
// $size - Name of class to use, i.e. "large" will generate .large-1, .large-2, etc. | |
@mixin grid-html-classes($size) { | |
@for $i from 0 through $total-columns - 1 { | |
.#{$size}-push-#{$i} { | |
@include grid-column($push:$i, $collapse:null, $float:false); | |
} | |
.#{$size}-pull-#{$i} { | |
@include grid-column($pull:$i, $collapse:null, $float:false); | |
} | |
} | |
.column, | |
.columns { @include grid-column($columns:false, $position:true); } | |
@for $i from 1 through $total-columns { | |
.#{$size}-#{$i} { @include grid-column($columns:$i,$collapse:null,$float:false); } | |
} | |
@for $i from 0 through $total-columns - 1 { | |
.#{$size}-offset-#{$i} { @include grid-column($offset:$i, $collapse:null,$float:false); } | |
} | |
.#{$size}-reset-order { | |
margin-#{$default-float}: 0; | |
margin-#{$opposite-direction}: 0; | |
left: auto; | |
right: auto; | |
float: $default-float; | |
} | |
.column.#{$size}-centered, | |
.columns.#{$size}-centered { @include grid-column($center:true, $collapse:null, $float:false); } | |
.column.#{$size}-uncentered, | |
.columns.#{$size}-uncentered { | |
margin-#{$default-float}: 0; | |
margin-#{$opposite-direction}: 0; | |
float: $default-float; | |
} | |
// Fighting [class*="column"] + [class*="column"]:last-child | |
.column.#{$size}-centered:last-child, | |
.columns.#{$size}-centered:last-child{ | |
float: none; | |
} | |
// Fighting .column.<previous-size>-centered:last-child | |
.column.#{$size}-uncentered:last-child, | |
.columns.#{$size}-uncentered:last-child { | |
float: $default-float; | |
} | |
.column.#{$size}-uncentered.opposite, | |
.columns.#{$size}-uncentered.opposite { | |
float: $opposite-direction; | |
} | |
.row { | |
&.#{$size}-collapse { | |
> .column, | |
> .columns { @include grid-column($collapse:true, $float:false); } | |
.row {margin-left:0; margin-right:0;} | |
} | |
&.#{$size}-uncollapse { | |
> .column, | |
> .columns { | |
@include grid-column; | |
} | |
} | |
} | |
} | |
@include exports("grid") { | |
@if $include-html-grid-classes { | |
.row { | |
@include grid-row; | |
&.collapse { | |
> .column, | |
> .columns { @include grid-column($collapse:true, $float:false); } | |
.row {margin-left:0; margin-right:0;} | |
} | |
.row { @include grid-row($behavior:nest); | |
&.collapse { @include grid-row($behavior:nest-collapse); } | |
} | |
} | |
.column, | |
.columns { @include grid-column($columns:$total-columns); } | |
[class*="column"] + [class*="column"]:last-child { float: $last-child-float; } | |
[class*="column"] + [class*="column"].end { float: $default-float; } | |
@media #{$small-up} { | |
@include grid-html-classes($size:small); | |
} | |
@media #{$medium-up} { | |
@include grid-html-classes($size:medium); | |
// Old push and pull classes | |
@for $i from 0 through $total-columns - 1 { | |
.push-#{$i} { | |
@include grid-column($push:$i, $collapse:null, $float:false); | |
} | |
.pull-#{$i} { | |
@include grid-column($pull:$i, $collapse:null, $float:false); | |
} | |
} | |
} | |
@media #{$large-up} { | |
@include grid-html-classes($size:large); | |
@for $i from 0 through $total-columns - 1 { | |
.push-#{$i} { | |
@include grid-column($push:$i, $collapse:null, $float:false); | |
} | |
.pull-#{$i} { | |
@include grid-column($pull:$i, $collapse:null, $float:false); | |
} | |
} | |
} | |
} | |
@if $include-xl-html-grid-classes { | |
@media #{$xlarge-up} { | |
@include grid-html-classes($size:xlarge); | |
} | |
@media #{$xxlarge-up} { | |
@include grid-html-classes($size:xxlarge); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment