My maths is shocking & I cannot, for the life of me get this calculation to work. I am creating a CSS grid system that allows users to specify any number of grid columns (there are 12 by default), the gutter in between these columns, the maximum width around the columns & the margin inside that total width. The hopeful outcome is a percentage width for each column width & a percentage for the left margin of all columns.
If I use the defaults below, the max width will be 1200px, the inner margin on the left & right will be 20 giving an inner width of 1160 for the maximum allowed space for the grid. Does that make sense?
I’m using is SASS by the way. Look at the comments in the code to see what is currently working & not working.
Here is the code on jsFiddle: http://jsfiddle.net/mrmartineau/fMeBk/
$gridColumnCount : 12; // Total column count
$gridGutterWidth : 40; // [in pixels]
$gridColumnPadding : 30; // [in pixels]
$gridMaxWidth : 1200; // [in pixels]
$gridMargin : 20; // [in pixels] Space outside the grid
@function gridColumnWidth() {
@return $gridMaxWidth / $gridColumnCount;
}
// Grid calculations
@function gridColumnWidthCalc($colNumber) {
// Is correct
@if $gridGutterWidth == 0 {
@return percentage($colNumber / $gridColumnCount);
}
// Is incorrect
@else $gridMargin > 0 {
@return percentage( (($colNumber / $gridColumnCount) - gutterCalc(false) ) );
}
}
@mixin columns($columnSpan: 1) {
width: gridColumnWidthCalc($columnSpan);
}
@function gutterCalc($showUnit: true) {
@if $showUnit == true {
@return percentage( $gridGutterWidth / ( $gridMaxWidth - ($gridMargin * 2) ) );
} @else {
@return $gridGutterWidth / ( $gridMaxWidth - ($gridMargin * 2) ) * 100;
}
}
@mixin gridColumn() {
@if $gridGutterWidth > 0 {
margin-left: gutterCalc();
}
@if $gridColumnPadding > 0 {
padding: $gridColumnPadding + px;
}
float: left;
min-height: 30px;
position: relative;
clear: none;
&:first-child {
margin-left: 0;
}
background-color: pink;
border: 1px solid red;
}
@for $i from 1 to $gridColumnCount + 1 {
.span#{$i} { @include columns($i); }
}
.container {
padding-left: $gridMargin + px;
padding-right: $gridMargin + px;
max-width: $gridMaxWidth + px;
}
.col {
@include gridColumn();
}
Okay, i spent an hour to comprehend your commentless code.
First of all, there’s ambiguity between “columns” as grid units and “columns” as actual elements. Below i’m calling the latter “blocks”.
You are correctly overriding gutter of the first block in a row. Thus, the total number of gutters is one less than the number of blocks in a row.
But when you’re calculating block widths, you’re subtracting gutter from every column without taking into consideration that there are less gutters than blocks.
So you should proportionally reduce the width of a block.
Working solution:
Now your wheel is rolling! See it in action: http://jsfiddle.net/fMeBk/46/ Keep in mind that browsers round up percentage values with a slight error, so grid positioning might be not pixel-perfect. BTW, right-aligning the last block in a row is necessary to minimize the visual effect of this rounding error.
Dude, your code architecture is so wrong, and your approach has a number of drawbacks. I can name them if you want.
You really should give Susy another try. It is a brilliant piece of SASS and also a great source to learn SASS techniques from. Its source code is well commented and available on GitHub.
According to you, what features of your grid framework does Susy lack?
I assure you, Susy can do what you want. Just explain a task and i’ll try to come up with an elegant solution leveraging Susy.
PS I’m not trying to dissuade you from experimenting. Practice makes perfect! Experimenting is necessary, and you’re doing a great job. What i’m trying to tell is that you should follow a good example and adopt good practices so that you don’t end up in the wrong place.
PPS Please give me back my rating. I devoted a lot of my personal time trying to help you, and you minused my answer. 🙁