I am looking for opinions on this code. I have been experimenting with SASS the last few days and have come up with the following code. The idea was to enable the creation of a fluid grid without having non-semantic markup in the HTML.
$columns: 12; //total number of columns to use
$gutter: 3%; // gutter width can be any unit
$column_width: 5.3333%; // column width can be any unit
// calculated total width
$total_width: $columns * ($gutter + $column_width);
// Sub-pixel fix for IE http://tylertate.com/blog/2012/01/05/subpixel-rounding.html
// min width in pixels, do not append px to the number.
$min_width: 480;
$ie_correction: (.5 / $min_width) * 100 * 1%;
// calculate width of a column based on it's span.
@function width( $span ) {
@return ( $span * $column_width ) + ( $gutter * ( $span - 1 ) );
}
// micro clearfix hack
// http://nicolasgallagher.com/micro-clearfix-hack/
@mixin clearfix {
&:before,
&:after {
content: "";
display: table;
}
&:after {
clear: both;
}
*zoom:1;
}
// Sets up a container for individual columns
@mixin row() {
display: block;
width: $total_width*(($gutter + width($columns))/width($columns));
margin: 0 $total_width*((($gutter*.5)/width($columns))*-1);
*width: $total_width*(($gutter + width($columns))/width($columns)) - $ie_correction;
*margin: 0 ($total_width*((($gutter*.5)/width($columns))*-1)) - $ie_correction;
@include clearfix;
}
// Sets single column and determins the offset distance and direction.
//
// $span: default 1; Determins the width of the column;
// $type: default none; has three available options
// push: pushes column to the right by the specified amount of columns
// pull: pulls a column to the left by a specified amount of columns
// center: centers a column of the desired size in the container
//
// $offset: default 0; determines the amount by which push and pull offset the column
// $last: default false; if true the column will be floated to the right;
@mixin column( $span: 1, $type: none, $offset: 0, $last:false ) {
@if $last == true {
float: right;
} @else {
float: left;
}
width: width( $span );
*width: width($span) - $ie_correction;
@if $type == none {
margin: 0 $gutter / 2;
*margin: 0 (( $gutter / 2 ) - $ie_correction );
} @else if $type == push {
margin: 0 ( $gutter / 2 ) 0 ( width( $offset ) + ( $gutter * 1.5 ) );
*margin: 0 ( ( $gutter / 2 ) - $ie_correction ) 0 ( width( $offset ) + ( $gutter * 1.5 ) - $ie_correction );
} @else if $type == pull {
margin: 0 ( width( $offset ) + ( $gutter * 1.5 ) ) 0 ( $gutter / 2 );
*margin: 0 ( width( $offset ) + ( $gutter * 1.5 ) - $ie_correction ) 0 ( ( $gutter / 2 ) - $ie_correction );
} @else if $type == center {
diplay: block;
width: width( $span );
margin: 0 auto;
float: none !important;
}
}
// Used to order columns right-to-left. Sets single column and determins the offset distance and direction.
//
// $span: default 1; Determins the width of the column;
// $type: default none; has three available options
// push: pushes column to the right by the specified amount of columns
// pull: pulls a column to the left by a specified amount of columns
// center: centers a column of the desired size in the container
//
// $offset: default 0; determines the amount by which push and pull offset the column
// $last: default false; if true the column will be floated to the right;
@mixin column_right( $span: 1, $type: none, $offset: 0, $last:false ) {
@if $last == true {
float: left;
} @else {
float: right;
}
width: width( $span );
*width: width($span) - $ie_correction;
@if $type == none {
margin: 0 $gutter / 2;
*margin: 0 (( $gutter / 2 ) - $ie_correction ) 0 (( $gutter / 2 ) - $ie_correction );
} @else if $type == push {
margin: 0 ( width( $offset ) + ( $gutter * 1.5 ) ) 0 ( $gutter / 2 ) ;
*margin: 0 ( width( $offset ) + ( $gutter * 1.5 ) - $ie_correction ) 0 ( $gutter / 2 );
} @else if $type == pull {
margin: 0 ( $gutter / 2 ) 0 ( width( $offset ) + ( $gutter * 1.5 ) );
*margin: 0 ( ( $gutter / 2 ) - $ie_correction ) 0 ( width( $offset ) + ( $gutter * 1.5 ) - $ie_correction );
} @else if $type == center {
diplay: block;
width: width( $span );
margin: 0 auto;
float: none !important;
}
}
// Creates a grid from an elements children. By default it is designed to work
// on a unordered list, but it can work with any element type chosed by the
// $element variable.
//
// $width: default 4; defines with amount of elemeents per row
// $margin: default $gutter variable; sets margin between each item
// $element: default li; defines the type element to target
@mixin grid( $width:4, $margin:$gutter, $element:li ) {
@include clearfix;
overflow: hidden;
margin-left: -#{$margin};
clear: both;
& > #{$element} {
float: left;
display: block;
width: ( $total_width / $width ) - $margin;
margin: 0 0 $margin $margin;
*width: ( $total_width / $width ) - $margin - $ie_correction;
*margin: 0 0 ( $margin - $ie_correction ) ( $margin - $ie_correction );
&:nth-child( #{$width}n + #{$width}) {
float: right;
}
}
}
Implementation is pretty straight forward.
column(5); // 5 column width ordered left to right
column(3, push, 3); //3 column width, pushing 3 columns from left
column(3, pull, 3); // 3 column width, pulling 3 columns from right
column(3, push, 2, true); // 3 columns, pushing 2 from left, and floated right as last column in row
column_right(5); // 5 columns ordered right to left
column_right(4, push, 3); //5 columns, right-to-left, pushing 3column widths from right
grid(4); // creates for a four up grid when applied to a ul, applies default margin
grid(5, 1%, div) // creates a five up grid with a 1% margin, which is applied to all child div elements.
I'm looking for opinions on what I can do better, and whether you think I'm overcomplicating the whole thing.