Gut grid mixins and replace with Susy for greater flexibility

This commit is contained in:
Michael Rose 2016-03-15 12:34:14 -04:00
parent 72661942cf
commit 6c6546c1ea
68 changed files with 4177 additions and 273 deletions

View file

@ -3,21 +3,16 @@
========================================================================== */
.archive {
@include container;
@include grid(12,10);
@include prefix(12,1);
@include suffix(12,1);
margin-bottom: 2em;
@include breakpoint($small) {
@include grid(12,8);
@include prefix(12,0);
@include suffix(12,0);
@include breakpoint($medium) {
@include span(10 last);
}
}
.archive__item {
// keep content from going to wide when toc is disabled
@include breakpoint($large) {
@include grid(12,6);
}
@include breakpoint($x-large) {
@include grid(12,5);
max-width: span(7 of 10);
}
}

View file

@ -2,6 +2,8 @@
BASE ELEMENTS
========================================================================== */
@include border-box-sizing;
body {
margin: 0;
padding: 0;

View file

@ -6,37 +6,28 @@
@include container;
@include clearfix;
margin-top: 3em;
padding-bottom: 3em;
padding: 0 2em 3em;
a {
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
footer {
@include grid(12,10);
@include prefix(12,1);
@include suffix(12,1);
@include breakpoint($small) {
@include grid(12,6);
@include prefix(12,3);
@include suffix(12,3);
}
@include breakpoint($x-large) {
@include grid(12,4.5);
@include prefix(12,4);
@include suffix(12,3.5);
}
}
}
.page__footer-copyright {
@include breakpoint($medium) {
@include span(10 of 12);
@include pre(2);
}
font-size: 14px;
}
.page__footer-follow {
@include breakpoint($medium) {
@include span(10 of 12);
@include pre(2);
}
ul {
margin: 0;
padding: 0;

View file

@ -1,77 +0,0 @@
/* ==========================================================================
Grid mixins
========================================================================== */
$unit: 1em;
@mixin container() {
margin: 0 auto;
width: $width;
}
/*
Works out the width of elements based on total number of columns and width
number of columns being displayed. Removes 20px for margins.
========================================================================== */
@mixin grid($grid:$def_grid, $cols:'', $float:left, $display:inline) {
display: $display;
float: $float;
width: (100%/$grid * $cols) - ($margin * 2);
}
/*
Add x amount of column padding before an element
Example: @include prefix(1,12);
========================================================================== */
@mixin prefix($grid:$def_grid, $cols:'') {
margin-left: (100%/$grid * $cols);
}
/*
Add x amount of column padding after an element
Example: @include suffix(2,12);
========================================================================== */
@mixin suffix($grid:$def_grid, $cols:'') {
margin-right: (100%/$grid * $cols);
}
/*
Remove left margin
Example: @include first;
========================================================================== */
@mixin first() {
margin-left: 0;
}
/*
Remove right margin
Example: @include last;
========================================================================== */
@mixin last() {
margin-right: 0;
}
/*
Push an element x amount of column(s) to the right
Example: @include push(2,12);
========================================================================== */
@mixin push($grid:$def_grid, $move:'') {
position: relative;
left: (100%/$grid * $move);
}
/*
Pull an element x amount of column(s) to the left
Example: @include pull(1,12);
========================================================================== */
@mixin pull($grid:$def_grid,$move:'') {
position: relative;
left: (100%/$grid * $move) * -1;
}

View file

@ -4,11 +4,11 @@
.masthead {
@include container;
padding: 2em 0 1em;
@include clearfix;
padding: 2em 2em 1em;
font-family: $sans-serif-narrow;
font-weight: 700;
text-transform: uppercase;
@include clearfix;
a {
text-decoration: none;
}
@ -16,40 +16,19 @@
/* Site name */
.site-name {
@include grid(12,10);
@include prefix(12,1);
@include suffix(12,1);
margin-bottom: 1em;
float: none;
display: block;
@include breakpoint($medium) {
@include span(10 of 12);
@include pre(2);
}
font-size: 24px;
@include breakpoint($small) {
@include grid(12,2);
@include prefix(12,0.5);
@include suffix(12,0.5);
font-size: 16px;
}
@include breakpoint($x-large) {
@include grid(12,1.5);
@include prefix(12,2);
}
}
.masthead__menu {
@include grid(12,10);
@include prefix(12,1);
@include suffix(12,1);
@include breakpoint($medium) {
@include span(10 of 12);
@include pre(2);
}
margin-bottom: 1em;
float: none;
display: block;
@include breakpoint($small) {
@include grid(12,9);
@include prefix(12,0);
@include suffix(12,0);
}
@include breakpoint($x-large) {
@include grid(12,8);
}
ul {
margin: 0;
padding: 0;

View file

@ -46,67 +46,4 @@
content: "";
display: table;
}
}
/*
Grid
========================================================================== */
@mixin container() {
margin: 0 auto;
width: $width;
}
// Works out the width of elements based on total number of columns and width
// number of columns being displayed. Removes 20px for margins.
@mixin grid($grid:$def_grid,$cols:'',$float:left,$display:inline) {
display: $display;
float: $float;
width: (100%/$grid * $cols) - ($margin * 2);
}
// Add x amount of column padding before an element
// Example: @include prefix(1,12);
@mixin prefix($grid:$def_grid,$cols:'') {
margin-left: (100%/$grid * $cols);
}
// Add x amount of column padding after an element
// Example: @include suffix(2,12);
@mixin suffix($grid:$def_grid,$cols:'') {
margin-right: (100%/$grid * $cols);
}
// Remove left margin
// Example: @include first;
@mixin first() {
margin-left: 0;
}
// Remove right margin
// Example: @include last;
@mixin last() {
margin-right: 0;
}
// Push an element x amount of column(s) to the right
// Example: @include push(2,12);
@mixin push($grid:$def_grid,$move:'') {
position: relative;
left: (100%/$grid * $move);
}
// Pull an element x amount of column(s) to the left
// Example: @include pull(1,12);
@mixin pull($grid:$def_grid,$move:'') {
position: relative;
left: (100%/$grid * $move) * -1;
}
}

View file

@ -7,25 +7,20 @@
========================================================================== */
.breadcrumbs {
@include grid(12,10);
@include prefix(12,1);
@include suffix(12,1);
@include container;
@include clearfix;
margin-bottom: 1em;
padding-left: 2em;
padding-right: 2em;
font-family: $sans-serif;
font-size: 14px;
@include breakpoint($small) {
@include grid(12,11);
@include prefix(12,0.5);
@include suffix(12,0.5);
}
@include breakpoint($x-large) {
@include grid(12,8);
@include prefix(12,2);
@include suffix(12,2)
}
ol {
padding: 0;
list-style: none;
font-size: 14px;
@include breakpoint($medium) {
@include span(10 of 12);
@include pre(2);
}
}
li {
display: inline;

View file

@ -6,26 +6,13 @@
@include container;
@include clearfix;
margin-top: 2em;
padding-left: 2em;
padding-right: 2em;
}
.page {
@include container;
@include grid(12,10);
@include prefix(12,1);
@include suffix(12,1);
@include breakpoint($small) {
@include grid(12,8);
@include prefix(12,0);
@include suffix(12,0);
}
@include breakpoint($large) {
@include grid(12,6);
}
@include breakpoint($x-large) {
@include grid(12,5);
@include breakpoint($medium) {
@include span(10 last);
}
}
@ -38,6 +25,14 @@
p, li {
font-size: 16px;
}
// keep content from going to wide when toc is disabled
@include breakpoint($large) {
> h1, > h2, > h3, > h4, > h5, > h6, > hr,
> p, > ul, > ol, > blockquote, > table, > figure,
> div, > section, > img, > video, > form {
max-width: span(7 of 10);
}
}
}
.page__hero {
@ -143,21 +138,12 @@
========================================================================== */
.page__related {
@include grid(12,10);
@include prefix(12,1);
@include suffix(12,1);
margin-top: 2em;
padding-top: 1em;
border-top: 1px solid $border-color;
@include breakpoint($small) {
@include grid(12,6);
@include prefix(12,3);
@include suffix(12,3);
}
@include breakpoint($x-large) {
@include grid(12,4.5);
@include prefix(12,4);
@include suffix(12,3.5);
@include breakpoint($medium) {
@include span(10);
@include pre(2);
}
li {
margin-bottom: 0;

View file

@ -3,17 +3,18 @@
========================================================================== */
.sidebar {
display: none;
@include breakpoint($small) {
@include breakpoint($medium) {
display: block;
margin-bottom: 1em;
@include grid(12,2);
@include prefix(12,0.5);
@include suffix(12,0.5);
@include span(2);
@include suffix(0.5);
// @include grid(12,2);
// @include prefix(12,0.5);
// @include suffix(12,0.5);
}
@include breakpoint($x-large) {
@include grid(12,1.5);
@include prefix(12,2);
// @include grid(12,1.5);
// @include prefix(12,2);
}
h2, h3, h4, h5, h6 {
font-family: $sans-serif-narrow;

View file

@ -10,11 +10,12 @@
letter-spacing: 1px;
background-color: #fff;
@include breakpoint($large) {
display: block;
@include grid(12,2);
position: absolute;
top: 0;
right: 6.250005%;
@include span(3 of 10 last);
@include prefix(0.25);
// @include grid(12,2);
// position: absolute;
// top: 0;
// right: 6.250005%;
}
}
@ -41,10 +42,14 @@
a {
display: block;
padding: 10px 20px;
color: $gray;
font-size: 11px;
font-weight: bold;
line-height: 1.5;
border-bottom: 1px solid $border-color;
&:hover {
color: #000;
}
}
li ul > li a {
font-weight: normal;

View file

@ -64,23 +64,39 @@ $link-color-focus : darken($link-color-visited, 10);
$border-radius : 4px;
/*
Grid
========================================================================== */
$width : 100%;
$def_grid : 12; // define number of columns in the grid (eg. 12, 16...)
$margin : 0;
/*
Breakpoints
========================================================================== */
@include breakpoint-set("to ems", true);
$micro : 480px;
$small : 600px;
$medium : 768px;
$large : 992px;
$x-large : 1382px;
$small : 600px;
$medium : 768px;
$medium-wide : 900px;
$large : 1024px;
$x-large : 1440px;
/*
Grid
========================================================================== */
// $width : 100%;
// $def_grid : 12; // define number of columns in the grid (eg. 12, 16...)
// $margin : 0;
$susy: (
columns: 12,
gutters: 1/4,
math: fluid,
output: float,
gutter-position: inside,
container: $large,
global-box-sizing: border-box,
debug: (
image: show,
color: blue,
output: overlay,
toggle: top right,
),
);

View file

@ -10,6 +10,7 @@
@import "vendor/breakpoint/breakpoint"; // media query mixins
@import "variables";
@import "mixins";
@import "vendor/susy/susy";
@import "reset";
@import "base";

4
_assets/css/vendor/susy/_su.scss vendored Normal file
View file

@ -0,0 +1,4 @@
// Su
// ==
@import 'susy/su';

4
_assets/css/vendor/susy/_susy.scss vendored Normal file
View file

@ -0,0 +1,4 @@
// Susy
// ====
@import 'susy/language/susy';

4
_assets/css/vendor/susy/_susyone.scss vendored Normal file
View file

@ -0,0 +1,4 @@
// Susy
// ====
@import 'susy/language/susyone';

7
_assets/css/vendor/susy/susy/_su.scss vendored Normal file
View file

@ -0,0 +1,7 @@
// Su
// ==
@import "su/utilities";
@import "su/settings";
@import "su/validation";
@import "su/grid";

View file

@ -0,0 +1,24 @@
// Susy Next Syntax
// ================
$susy-version: 2.1;
@import "../su";
@import "../output/float";
@import "susy/settings";
@import "susy/validation";
@import "susy/grids";
@import "susy/box-sizing";
@import "susy/context";
@import "susy/background";
@import "susy/container";
@import "susy/span";
@import "susy/gutters";
@import "susy/isolate";
@import "susy/gallery";
@import "susy/rows";
@import "susy/margins";
@import "susy/padding";
@import "susy/bleed";
@import "susy/breakpoint-plugin";

View file

@ -0,0 +1,13 @@
// ---------------------------------------------------------------------------
// Partials
$susy-version: 1.5;
@import "susyone/settings";
@import "susyone/functions";
@import "susyone/grid";
@import "susyone/isolation";
@import "susyone/padding";
@import "susyone/margin";
@import "susyone/media";
@import "susyone/background";

View file

@ -0,0 +1,385 @@
// Background Grid Syntax
// ======================
$susy-overlay-grid-head-exists: false;
// Show Grid/s
// -----------
// Show grid on any element using either background or overlay.
// - [$grid] : <settings>
@mixin show-grid(
$grid: $susy
) {
$inspect: $grid;
$_output: debug-get(output, $grid);
@include susy-inspect(show-grid, $inspect);
@if $_output == overlay and susy-get(debug image, $grid) != hide {
@include overlay-grid($grid);
} @else {
@include background-grid($grid);
}
}
@mixin show-grids(
$grid: $susy
) {
@include show-grid($grid);
}
// Background Grid
// ---------------
// Show a grid background on any element.
// - [$grid] : <settings>
@mixin background-grid(
$grid: $susy
) {
$inspect : $grid;
$_output : get-background($grid);
@if length($_output) > 0 {
$_flow: susy-get(flow, $grid);
$_image: ();
@each $name, $layer in map-get($_output, image) {
$_direction: if($name == baseline, to bottom, to to($_flow));
$_image: append($_image, linear-gradient($_direction, $layer), comma);
}
$_output: map-merge($_output, (image: $_image));
@include background-grid-output($_output...);
@include susy-inspect(background-grid, $inspect);
}
}
// Overlay Grid
// ------------
// Generate an icon to trigger grid-overlays on any given elements.
// $grids... : <selector> [<settings>] [, <selector>]*
@mixin overlay-grid (
$grid: $susy
) {
@if not($susy-overlay-grid-head-exists) {
@at-root head { @include overlay-head($grid); }
@at-root head:before { @include overlay-trigger; }
@at-root head:hover { @include overlay-trigger-hover; }
$susy-overlay-grid-head-exists: true !global;
}
head:hover ~ &,
head:hover ~ body & {
position: relative;
&:before {
@include grid-overlay-base;
@include background-grid($grid);
}
}
}
// [Private] Overlay Trigger
// -------------------------
@mixin overlay-trigger {
content: "|||";
display: block;
padding: 5px 10px;
font: {
family: sans-serif;
size: 16px;
weight: bold;
}
}
// [Private] Overlay Trigger Hover
// -------------------------------
@mixin overlay-trigger-hover {
background: rgba(white, .5);
color: red;
}
// [Private] Overlay Head
// ----------------------
// <head> styles to create grid overlay toggle
@mixin overlay-head (
$grid: $susy
) {
$_toggle: debug-get(toggle, $grid);
$_horz: null;
$_vert: null;
@each $side in $_toggle {
$_horz: if($side == left or $side == right, $side, $_horz);
$_vert: if($side == top or $side == bottom, $side, $_vert);
}
display: block;
position: fixed;
#{$_horz}: 10px;
#{$_vert}: 10px;
z-index: 999;
color: #333;
background: rgba(white, .25);
}
// [Private] Grid Overlay Base
// ---------------------------
// Base styles for generating a grid overlay
@mixin grid-overlay-base() {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
content: " ";
z-index: 998;
}
// Get Symmetrical Background
// --------------------------
// - $grid: <map>
@function get-background-sym(
$grid
) {
$grid : parse-grid($grid);
$_gutters : susy-get(gutters, $grid);
$_column-width : susy-get(column-width, $grid);
$_math : susy-get(math, $grid);
$_color : debug-get(color);
$_trans : transparent;
$_light : lighten($_color, 15%);
$_end : 1 + $_gutters;
$_after : percentage(1/$_end);
$_stops : ();
$_size : span(1 $grid wide);
@if is-inside($grid) {
$_stops: $_color, $_light;
} @else if is-split($grid) {
$_split: $_gutters/2;
$_before: percentage($_split/$_end);
$_after: percentage((1 + $_split)/$_end);
$_stops: $_trans $_before, $_color $_before, $_light $_after, $_trans $_after;
} @else {
$_stops: $_color, $_light $_after, $_trans $_after;
}
@if $_math == static {
$_size: valid-column-math($_math, $_column-width) * $_end;
}
$_output: (
image: (columns: $_stops),
size: $_size,
);
@return $_output;
}
// Get Asymmetrical Inside
// -----------------------
// - $grid: <settings>
@function get-asym-inside(
$grid
) {
$grid : parse-grid($grid);
$_columns : susy-get(columns, $grid);
$_color : debug-get(color);
$_light : lighten($_color, 15%);
$_stops : ();
@for $location from 1 through susy-count($_columns) {
$this-stop: ();
@if $location == 1 {
$this-stop: append($this-stop, $_color, comma);
} @else {
$start: parse-span(1 at $location $grid);
$start: get-isolation($start);
$this-stop: append($this-stop, $_color $start, comma);
}
@if $location == susy-count($_columns) {
$this-stop: append($this-stop, $_light, comma);
} @else {
$_end: parse-span(1 at ($location + 1) $grid);
$_end: get-isolation($_end);
$this-stop: append($this-stop, $_light $_end, comma);
}
$_stops: join($_stops, $this-stop, comma);
}
@return $_stops;
}
// Get Asymmetrical Split
// ----------------------
// - $grid: <settings>
@function get-asym-split(
$grid
) {
$grid : parse-grid($grid);
$_columns : susy-get(columns, $grid);
$_color : debug-get(color);
$_light : lighten($_color, 15%);
$_stops : ();
@for $location from 1 through susy-count($_columns) {
$this-stop: ();
$start: parse-span(1 at $location $grid);
$start: get-isolation($start);
$this-stop: append($this-stop, transparent $start, comma);
$this-stop: append($this-stop, $_color $start, comma);
$_end: $start + span(1 at $location $grid);
$this-stop: append($this-stop, $_light $_end, comma);
$this-stop: append($this-stop, transparent $_end, comma);
$_stops: join($_stops, $this-stop, comma);
}
@return $_stops;
}
// Get Asymmetrical Outside
// ------------------------
// - $grid: <settings>
@function get-asym-outside(
$grid
) {
$grid : parse-grid($grid);
$_columns : susy-get(columns, $grid);
$_color : debug-get(color);
$_light : lighten($_color, 15%);
$_trans : transparent;
$_stops : ();
@for $location from 1 through susy-count($_columns) {
$this-stop: ();
@if $location == 1 {
$this-stop: append($this-stop, $_color, comma);
} @else {
$start: parse-span(1 at $location $grid);
$start: get-isolation($start);
$this-stop: append($this-stop, $_color $start, comma);
}
@if $location == susy-count($_columns) {
$this-stop: append($this-stop, $_light, comma);
} @else {
$gutter: get-span-width(first $location $grid);
$_end: parse-span(1 at ($location + 1) $grid);
$_end: get-isolation($_end);
$gutter: $_light $gutter, $_trans $gutter, $_trans $_end;
$this-stop: join($this-stop, $gutter, comma);
}
$_stops: join($_stops, $this-stop, comma);
}
@return $_stops;
}
// Get Asymmetrical Background
// ---------------------------
// - $grid: <settings>
@function get-background-asym(
$grid
) {
$_stops: ();
@if is-inside($grid) {
$_stops: get-asym-inside($grid);
} @else if is-split($grid) {
$_stops: get-asym-split($grid);
} @else {
$_stops: get-asym-outside($grid);
}
@return (image: (columns: $_stops));
}
// Get Background
// --------------
// - $grid: <settings>
@function get-background(
$grid
) {
$grid : parse-grid($grid);
$_show : susy-get(debug image, $grid);
$_return : ();
@if $_show and $_show != 'hide' {
$_columns: susy-get(columns, $grid);
@if $_show != 'show-baseline' {
$_sym: is-symmetrical($_columns);
$_return: if($_sym, get-background-sym($grid), get-background-asym($grid));
$_return: map-merge($_return, (clip: content-box));
}
@if $_show != 'show-columns'
and global-variable-exists(base-line-height)
and type-of($base-line-height) == 'number'
and not unitless($base-line-height) {
$_color: variable-exists('grid-background-baseline-color');
$_color: if($_color, $grid-background-baseline-color, #000);
$_image: map-get($_return, image);
$_size: map-get($_return, size);
$_baseline: (baseline: ($_color 1px, transparent 1px));
$_baseline-size: 100% $base-line-height;
$_return: map-merge($_return, (
image: if($_image, map-merge($_image, $_baseline), $_baseline),
size: if($_size, ($_size, $_baseline-size), $_baseline-size),
));
@if $_show == 'show' {
$_clip: map-get($_return, clip);
$_return: map-merge($_return, (clip: join($_clip, border-box, comma)));
}
} @else if $_show == 'show-baseline' {
@warn 'Please provide a $base-line-height with the desired height and units';
}
}
@if map-get($_return, image) {
$_return: map-merge($_return, (flow: susy-get(flow, $grid)));
}
@return $_return;
}
// Get Debug
// ---------
// Return the value of a debug setting
// - $key: <setting>
@function debug-get(
$key,
$grid: $susy
) {
$key: join(debug, $key, space);
@return susy-get($key, $grid);
}

View file

@ -0,0 +1,200 @@
// Bleed Syntax
// ============
// Bleed
// -----
// Add negative margins, and equal positive padding to create bleed.
// - $bleed : <span>
@mixin bleed(
$bleed: 0 gutter()
) {
$inspect : $bleed;
$output : get-bleed($bleed);
@if susy-get(global-box-sizing) != content-box {
$output: map-merge((box-sizing: content-box), $output);
}
@include susy-inspect(bleed, $inspect);
@include output($output);
}
// Bleed-x
// -------
// Shortcut for horizontal bleed.
// - $bleed : <span>
@mixin bleed-x(
$bleed: gutter()
) {
$bleed : parse-span($bleed);
$trbl : susy-get(span, $bleed);
@if length($trbl) == 1 {
$bleed: map-merge($bleed, (span: 0 nth($trbl, 1)));
} @else if length($trbl) == 2 {
$bleed: map-merge($bleed, (span: 0 nth($trbl, 2) 0 nth($trbl, 1)));
} @else {
@warn 'bleed-x only takes 2 lengths, but #{length($trbl)} were passed.';
}
@include bleed($bleed);
}
// Bleed-y
// -------
// Shortcut for vertical bleed.
// - $bleed : <span>
@mixin bleed-y(
$bleed: if(function-exists(rhythm), rhythm(1), 1em)
) {
$bleed : parse-span($bleed);
$trbl : susy-get(span, $bleed);
@if length($trbl) == 1 {
$bleed: map-merge($bleed, (span: nth($trbl, 1) 0));
} @else if length($trbl) == 2 {
$bleed: map-merge($bleed, (span: nth($trbl, 1) 0 nth($trbl, 2) 0));
} @else {
@warn 'bleed-y only takes 2 lengths, but #{length($trbl)} were passed.';
}
@include bleed($bleed);
}
// Get Bleed
// ---------
// Return bleed output values
// - $bleed: <span>
@function get-bleed(
$bleed
) {
$bleed : map-merge((spread: wide), parse-span($bleed));
$trbl : susy-get(span, $bleed);
$short : null;
$output : ();
@for $i from 1 through length($trbl) {
$this: nth($trbl, $i);
$new: ();
$margin: null;
$padding: null;
$padding-x: null;
@if $this > 0 {
$this: map-merge($bleed, (span: $this));
$margin: span($this);
$padding: $margin;
$padding-x: $padding;
}
@if $margin and $margin > 0 {
$margin: - $margin;
@if is-inside($this) {
$gutter: gutter($this);
$join: if($gutter and comparable($padding, $gutter), true, false);
$padding-x: if($join and $padding > 0, $padding + $gutter, $padding);
}
}
@if $i == 1 {
$new: (
margin-top: $margin,
padding-top: $padding,
margin-right: $margin,
padding-right: $padding-x,
margin-bottom: $margin,
padding-bottom: $padding,
margin-left: $margin,
padding-left: $padding-x,
);
} @else if $i == 2 {
$new: (
margin-right: $margin,
padding-right: $padding-x,
margin-left: $margin,
padding-left: $padding-x,
);
} @else if $i == 3 {
$new: (
margin-bottom: $margin,
padding-bottom: $padding,
);
} @else if $i == 4 {
$new: (
margin-left: $margin,
padding-left: $padding-x,
);
}
$output: map-merge($output, $new);
}
@each $prop, $value in $output {
$output: if($value == 0, map-merge($output, ($prop: null)), $output);
}
@return bleed-shorthand($output);
}
// Bleed Shorthand
// ---------------
// Convert bleed output into shorthand when possible.
// - $bleed: <output map>
@function bleed-shorthand(
$bleed
) {
$margin: ();
$padding: ();
$return: ();
@each $key, $value in $bleed {
@if str-index($key, margin) {
$margin: map-merge($margin, ($key: $value));
} @else if str-index($key, padding) > 0 {
$padding: map-merge($padding, ($key: $value));
}
}
$props: (
margin: $margin,
padding: $padding,
);
@each $name, $map in $props {
$four: if(length(map-keys($map)) == 4, true, false);
$null: if(index(map-values($map), null), true, false);
@if $four and not($null) {
$top: map-get($map, '#{$name}-top');
$right: map-get($map, '#{$name}-right');
$bottom: map-get($map, '#{$name}-bottom');
$left: map-get($map, '#{$name}-left');
$tb: if($top == $bottom, $top, null);
$rl: if($right == $left, $right, null);
$all: if($tb == $rl, $tb, null);
$new: if($all, $all, null);
@if not($new) {
@if $tb and $rl {
$new: $tb $rl;
} @else if $rl {
$new: $top $rl $bottom;
} @else {
$new: $top $right $bottom $left;
}
}
$return: map-merge($return, ($name: $new));
} @else {
$return: map-merge($return, $map);
}
}
@return $return;
}

View file

@ -0,0 +1,47 @@
// Susy Box Sizing
// =================
// Global Box Sizing
// -----------------
// Set a box model globally on all elements.
// - [$box]: border-box | content-box
// - [$inherit]: true | false
@mixin global-box-sizing(
$box: susy-get(global-box-sizing),
$inherit: false
) {
$inspect: $box;
@if $inherit {
@at-root {
html { @include output((box-sizing: $box)); }
*, *:before, *:after { box-sizing: inherit; }
}
} @else {
*, *:before, *:after { @include output((box-sizing: $box)); }
}
@include susy-inspect(global-box-sizing, $inspect);
@include update-box-model($box);
}
// Border Box Sizing
// -----------------
// A legacy shortcut...
// - [$inherit]: true | false
@mixin border-box-sizing(
$inherit: false
) {
@include global-box-sizing(border-box, $inherit);
}
// Update Box Model
// ----------------
// PRIVATE: Updates global box model setting
@mixin update-box-model(
$box
) {
@if $box != susy-get(global-box-sizing) {
@include susy-set(global-box-sizing, $box);
}
}

View file

@ -0,0 +1,185 @@
// Breakpoint Integration
// ======================
$susy-media: () !default;
$susy-media-fallback: false !default;
$_susy-media-context: ();
// Susy Breakpoint
// ---------------
// Change grids at different media query breakpoints.
// - $query : <min-width> [<max-width>] | <property> <value> | <map>
// - $layout : <settings>
// - $no-query : <boolean> | <selector>
@mixin susy-breakpoint(
$query,
$layout: false,
$no-query: $susy-media-fallback
) {
@include susy-media-router($query, $no-query) {
@if $layout {
@include with-layout($layout) {
@content;
}
} @else {
@content;
}
}
}
// Susy Media
// ----------
// - $query: <min-width> [<max-width>] | <property> <value>
// - $no-query: <boolean> | <selector>
@mixin susy-media(
$query,
$no-query: $susy-media-fallback
) {
$old-context: $_susy-media-context;
$name: if(map-has-key($susy-media, $query), $query, null);
$query: susy-get-media($query);
$query: susy-parse-media($query);
@include susy-media-context($query, $name);
@if $no-query and type-of($no-query) != string {
@content;
} @else {
@media #{susy-render-media($query)} {
@content;
}
@if type-of($no-query) == string {
#{$no-query} & {
@content;
}
}
}
@include susy-media-context($old-context, $clean: true);
}
// Media Router
// ------------
// Rout media arguments to the correct mixin.
@mixin susy-media-router(
$query,
$no-query: $susy-media-fallback
) {
@if susy-support(breakpoint, (mixin: breakpoint), $warn: false) {
@include breakpoint($query, $no-query) {
@content;
}
} @else {
@include susy-media($query, $no-query) {
@content;
}
}
}
// Update Context
// -------------
// Set the new media context
@mixin susy-media-context(
$query,
$name: null,
$clean: false
) {
$query: map-merge((name: $name), $query);
@if $clean {
$_susy-media-context: $query !global;
} @else {
$_susy-media-context: map-merge($_susy-media-context, $query) !global;
}
}
// Media Context
// -------------
// Return the full media context, or a single media property (e.g. min-width)
@function susy-media-context(
$property: false
) {
@if $property {
@return map-get($_susy-media-context, $property);
} @else {
@return $_susy-media-context;
}
}
// Get Media
// ---------
// Return a named media-query from $susy-media.
// - $name: <key>
@function susy-get-media(
$name
) {
@if map-has-key($susy-media, $name) {
$map-value: map-get($susy-media, $name);
@if ($name == $map-value) {
$name: $map-value;
} @else {
$name: susy-get-media($map-value);
}
}
@return $name;
}
// Render Media
// ------------
// Build a media-query string from various media settings
@function susy-render-media(
$query
) {
$output: null;
@each $property, $value in $query {
$string: null;
@if $property == media {
$string: $value;
} @else {
$string: '(#{$property}: #{$value})';
}
$output: if($output, '#{$output} and #{$string}', $string);
}
@return $output;
}
// Parse Media
// -----------
// Return parsed media-query settings based on shorthand
@function susy-parse-media(
$query
) {
$mq: null;
@if type-of($query) == map {
$mq: $query;
} @else if type-of($query) == number {
$mq: (min-width: $query);
} @else if type-of($query) == list and length($query) == 2 {
@if type-of(nth($query, 1)) == number {
$mq: (
min-width: min($query...),
max-width: max($query...),
);
} @else {
$mq: (nth($query, 1): nth($query, 2));
}
} @else {
$mq: (media: '#{$query}');
}
@return $mq;
}

View file

@ -0,0 +1,81 @@
// Container Syntax
// ================
// Container [mixin]
// -----------------
// Set a container element
// - [$layout] : <settings>
@mixin container(
$layout: $susy
) {
$inspect : $layout;
$layout : parse-grid($layout);
$_width : get-container-width($layout);
$_justify : parse-container-position(susy-get(container-position, $layout));
$_property : if(susy-get(math, $layout) == static, width, max-width);
$_box : susy-get(box-sizing, $layout);
@if $_box {
@include output((box-sizing: $_box));
}
@include susy-inspect(container, $inspect);
@include float-container($_width, $_justify, $_property);
@include show-grid($layout);
}
// Container [function]
// --------------------
// Return container width
// - [$layout] : <settings>
@function container(
$layout: $susy
) {
$layout: parse-grid($layout);
@return get-container-width($layout);
}
// Get Container Width
// -------------------
// Calculate the container width
// - [$layout]: <settings>
@function get-container-width(
$layout: $susy
) {
$layout : parse-grid($layout);
$_width : susy-get(container, $layout);
$_column-width : susy-get(column-width, $layout);
$_math : susy-get(math, $layout);
@if not($_width) or $_width == auto {
@if valid-column-math($_math, $_column-width) {
$_columns : susy-get(columns, $layout);
$_gutters : susy-get(gutters, $layout);
$_spread : if(is-split($layout), wide, narrow);
$_width : susy-sum($_columns, $_gutters, $_spread) * $_column-width;
} @else {
$_width: 100%;
}
}
@return $_width;
}
// Parse Container Position
// ------------------------
// Parse the $container-position into margin values.
// - [$justify] : left | center | right | <length> [<length>]
@function parse-container-position(
$justify: map-get($susy-defaults, container-position)
) {
$_return: if($justify == left, 0, auto) if($justify == right, 0, auto);
@if not(index(left right center, $justify)) {
$_return: nth($justify, 1);
$_return: $_return if(length($justify) > 1, nth($justify, 2), $_return);
}
@return $_return;
}

View file

@ -0,0 +1,36 @@
// Context Syntax
// ==============
// Nested [function]
// -----------------
// Return a subset grid for nested context.
// - $context : <span>
@function nested(
$context
) {
$context : parse-span($context);
$span : susy-get(span, $context);
$location : get-location($context);
$columns : susy-get(columns, $context);
@return susy-slice($span, $location, $columns);
}
// Nested [mixin]
// --------------
// Use a subset grid for a nested context
// - $context : <span>
// - @content : <content>
@mixin nested(
$context
) {
$inspect : $context;
$context : parse-span($context);
$old : susy-get(columns);
$susy : map-merge($susy, (columns: nested($context))) !global;
@include susy-inspect(nested, $inspect);
@content;
$susy : map-merge($susy, (columns: $old)) !global;
}

View file

@ -0,0 +1,94 @@
// Gallery Syntax
// ==============
// Gallery
// -------
// Create an isolated gallery
// - $span : <span>
// - [$selector] : child | of-type
@mixin gallery(
$span,
$selector: child
) {
$inspect : $span;
$span : parse-span($span);
$span : map-merge($span, (location: 1));
$n : susy-get(span, $span);
$columns : susy-get(columns, $span);
$context : susy-count($columns);
$flow : susy-get(flow, $span);
$inside : is-inside($span);
$from : from($flow);
$line : floor($context / $n);
$symmetrical : is-symmetrical($columns);
$output: (
width : null,
float : from,
margin-before : null,
margin-after : null,
padding-before : null,
padding-after : null,
flow : $flow,
);
@if $inside {
$gutters: get-gutters($span);
$output: map-merge($output, (
padding-before: map-get($gutters, before),
padding-after: map-get($gutters, after),
));
}
@if $symmetrical {
$output: map-merge($output, (width: get-span-width($span)));
}
$box : susy-get(box-sizing, $span);
$global-box : if(susy-get(global-box-sizing) == 'border-box', true, false);
@include susy-inspect(gallery, $inspect);
// Collective Output
@if $box == border-box or ($inside and not($box) and not($global-box)) {
@include output((box-sizing: border-box));
} @else if $box == content-box {
@include output((box-sizing: content-box));
}
@include float-span-output($output...);
// Individual Loop
@for $item from 1 through $line {
$nth: '#{$line}n + #{$item}';
&:nth-#{$selector}(#{$nth}) {
// Individual Prep
$output: (
width : if($symmetrical, null, get-span-width($span)),
float : null,
margin-before : get-isolation($span),
margin-after : -100%,
padding-before : null,
padding-after : null,
flow : $flow,
);
// Individual Output
@include float-span-output($output...);
@if get-edge($span) == first {
@include break;
@include first($span);
} @else {
@include nobreak;
}
// Individual Location Increment
$location: get-location($span) + $n;
$location: if($location > $context, 1, $location);
$span: map-merge($span, (location: $location));
}
}
}

View file

@ -0,0 +1,64 @@
// Grid Syntax
// ===========
// Layout
// ------
// Set a new layout using a shorthand
// - $layout: <settings>
// - $clean: boolean
@mixin layout(
$layout,
$clean: false
) {
$inspect : $layout;
$susy : _get-layout($layout, $clean) !global;
@include susy-inspect(layout, $inspect);
}
// Use Grid
// --------
// Use an arbitrary layout for a section of code
// - $layout: <settings>
// - $clean: boolean
@mixin with-layout(
$layout,
$clean: false
) {
$inspect : $layout;
$old : $susy;
$susy : _get-layout($layout, $clean) !global;
@include susy-inspect(with-layout, $inspect);
@content;
$susy: $old !global;
}
// Layout
// ------
// Return a parsed layout map based on shorthand syntax
// - $layout: <settings>
@function layout(
$layout: $susy
) {
@return parse-grid($layout);
}
// Get Layout
// ----------
// Return a new layout based on current and given settings
// - $layout: <settings>
// - $clean: boolean
@function _get-layout(
$layout,
$clean: false
) {
$layout: layout($layout);
@return if($clean, $layout, _susy-deep-merge($susy, $layout));
}

View file

@ -0,0 +1,154 @@
// Gutter Syntax
// =============
// Gutters
// -------
// Set gutters on an element.
// - [$span] : <settings>
@mixin gutters(
$span: $susy
) {
$inspect : $span;
$span : parse-gutters($span);
$_gutters : get-gutters($span);
$_output: (
before: map-get($_gutters, before),
after: map-get($_gutters, after),
flow: susy-get(flow, $span),
);
@include susy-inspect(gutters, $inspect);
@if is-inside($span) {
@include padding-output($_output...);
} @else {
@include margin-output($_output...);
}
}
@mixin gutter(
$span: $susy
) {
@include gutters($span);
}
// Gutter
// ------
// Return the width of a gutter.
// - [$span] : <settings>
@function gutter(
$span: $susy
) {
$span: parse-gutters($span);
$_gutters: get-gutters($span);
$_gutters: map-get($_gutters, before) or map-get($_gutters, after);
@return $_gutters;
}
@function gutters(
$span: $susy
) {
@return gutter($span);
}
// Get Gutter Width
// ----------------
// Return gutter width.
// - [$context]: <context>
@function get-gutter-width(
$context: $susy
) {
$context : parse-gutters($context);
$_gutters : susy-get(gutters, $context);
$_gutter : susy-get(gutter-override, $context);
@if $_gutters and ($_gutters > 0) and not($_gutter) {
$_column-width: susy-get(column-width, $context);
$_math: gutter-math($context);
@if $_math == static {
$_gutter: $_gutters * valid-column-math($_math, $_column-width);
} @else {
$_columns : susy-get(columns, $context);
$_spread : if(is-split($context), wide, susy-get(spread, $context));
$_gutter : percentage($_gutters / susy-sum($_columns, $_gutters, $_spread));
}
}
$_gutter: if($_gutter == 'no-gutters' or $_gutter == 'no-gutter', null, $_gutter);
@return $_gutter;
}
// Get Gutters
// -----------
// Return before and after gutter values.
// - [$context]: <context>
@function get-gutters(
$context: $susy
) {
$context : parse-gutters($context);
$_gutter-position : susy-get(gutter-position, $context);
$_gutter : get-gutter-width($context);
$_return : (before: null, after: null);
@if is-split($context) and $_gutter {
$_gutter: $_gutter / 2;
$_return: map-merge($_return, (before: $_gutter, after: $_gutter));
} @else {
$_return: map-merge($_return, ($_gutter-position: $_gutter));
}
@return $_return;
}
// Is Inside
// ---------
// Returns true if gutters are inside.
// $context: <context>
@function is-inside(
$context
) {
$_inside: inside inside-static;
$_gutter-position: susy-get(gutter-position, $context);
@return if(index($_inside, $_gutter-position), true, false);
}
// Is Split
// --------
// Returns true if gutters are split.
// $context: <context>
@function is-split(
$context
) {
$_split: split inside inside-static;
$_gutter-position: susy-get(gutter-position, $context);
@return if(index($_split, $_gutter-position), true, false);
}
// Gutter Math
// -----------
// Return the math to use for gutter calculations
// $context: <context>
@function gutter-math(
$context: $susy
) {
$_return : susy-get(math, $context);
$_return : if(susy-get(gutter-position, $context) == inside-static, static, $_return);
@return $_return;
}

View file

@ -0,0 +1,77 @@
// Isolation Syntax
// ================
// Isolate [Mixin]
// ---------------
// Set isolation as an override.
// - $location: <span>
@mixin isolate(
$isolate: 1
) {
$inspect: $isolate;
$output: (
push: isolate($isolate),
flow: susy-get(flow, $isolate),
);
@include susy-inspect(isolate, $inspect);
@include isolate-output($output...);
}
// Isolate [function]
// ------------------
// Return an isolation offset width.
// - $location: <span>
@function isolate(
$isolate: 1
) {
$isolate: parse-span($isolate);
$isolation: susy-get(span, $isolate);
@if $isolation and not(get-location($isolate)) {
$new: (
span: null,
location: $isolation,
);
$isolate: map-merge($isolate, $new);
}
@return get-isolation($isolate);
}
// Get Isolation
// -------------
// Return the isolation offset width
// - $input: <map>
@function get-isolation(
$input
) {
$location : get-location($input);
$columns : susy-get(columns, $input);
$width : null;
@if type-of($location) == number and not(unitless($location)) {
$width: $location;
} @else if $location {
$push: $location - 1;
@if $push > 0 {
$push: map-merge($input, (
span: $push,
location: 1,
spread: wide,
));
$width: get-span-width($push);
}
}
@if susy-get(gutter-position, $input) == split
and susy-get(gutters, $input) > 0 {
$width: if($width == null, gutters($input), $width + gutters($input));
}
@return $width or 0;
}

View file

@ -0,0 +1,94 @@
// Margin Syntax
// =============
// Pre
// ---
// Add spanning-margins before an element.
// - $span : <span>
@mixin pre(
$span
) {
$inspect: $span;
$span : map-merge((spread: wide), parse-span($span));
$flow : susy-get(flow, $span);
$split : if(susy-get(gutter-position, $span) == split, true, false);
$gutter : gutter($span);
$span : span($span);
$width : if($split and $gutter, $span + $gutter, $span);
@include susy-inspect(pre, $inspect);
@include margin-output($width, null, $flow);
}
// Post
// ----
// Add spanning-margins after an element.
// - $span : <span>
@mixin post(
$span
) {
$inspect : $span;
$span : map-merge((spread: wide), parse-span($span));
$flow : susy-get(flow, $span);
$split : if(susy-get(gutter-position, $span) == split, true, false);
$width : if($split, span($span) + gutter($span), span($span));
@include susy-inspect(post, $inspect);
@include margin-output(null, $width, $flow);
}
// Push
// ----
// Simple synonymn for pre.
// - $span : <span>
@mixin push(
$span
) {
@include pre($span);
}
// Pull
// ----
// Add negative spanning-margins before an element.
// - $span : <span>
@mixin pull(
$span
) {
$inspect : $span;
$span : map-merge((spread: wide), parse-span($span));
$flow : susy-get(flow, $span);
$split : if(susy-get(gutter-position, $span) == split, true, false);
$width : if($split, 0 - span($span) + gutter($span), 0 - span($span));
@include susy-inspect(pull, $inspect);
@include margin-output($width, null, $flow);
}
// Squish
// ------
// Add spanning-margins before and after an element.
// - $pre : <span>
// - [$post] : <span>
@mixin squish(
$pre,
$post: false
) {
$inspect : ($pre, $post);
$pre : map-merge((spread: wide), parse-span($pre));
@if $post {
$post: map-merge((spread: wide), parse-span($post));
} @else {
$span: susy-get(span, $pre);
@if length($span) > 1 {
$pre: map-merge($pre, (span: nth($span, 1)));
$post: map-merge($pre, (span: nth($span, 2)));
} @else {
$post: $pre;
}
}
@include susy-inspect(squish, $inspect);
@include pre($pre);
@include post($post);
}

View file

@ -0,0 +1,74 @@
// Padding Syntax
// ==============
// Prefix
// ------
// Add spanning-padding before an element.
// - $span : <span>
@mixin prefix(
$span
) {
$inspect : $span;
$span : map-merge((spread: wide), parse-span($span));
$flow : susy-get(flow, $span);
$width : span($span);
@if is-inside($span) {
$gutter: gutter($span);
$width: if($gutter and comparable($width, $gutter), $width + $gutter, $width);
}
@include susy-inspect(prefix, $inspect);
@include padding-output($width, null, $flow);
}
// Suffix
// ------
// Add spanning-padding after an element.
// - $span : <span>
@mixin suffix(
$span
) {
$inspect : $span;
$span : map-merge((spread: wide), parse-span($span));
$flow : susy-get(flow, $span);
$width : span($span);
@if is-inside($span) {
$gutter: gutter($span);
$width: if($gutter and comparable($width, $gutter), $width + $gutter, $width);
}
@include susy-inspect(suffix, $inspect);
@include padding-output(null, $width, $flow);
}
// Pad
// ---
// Add spanning-padding before and after an element.
// - $pre : <span>
// - [$post] : <span>
@mixin pad(
$pre,
$post: false
) {
$inspect : ($pre, $post);
$pre : map-merge((spread: wide), parse-span($pre));
@if $post {
$post: map-merge((spread: wide), parse-span($post));
} @else {
$span: susy-get(span, $pre);
@if length($span) > 1 {
$pre: map-merge($pre, (span: nth($span, 1)));
$post: map-merge($pre, (span: nth($span, 2)));
} @else {
$post: $pre;
}
}
@include susy-inspect(pad, $inspect);
@include prefix($pre);
@include suffix($post);
}

View file

@ -0,0 +1,138 @@
// Row Start & End
// ===============
// Break
// -----
// Apply to any element that should force a line break.
@mixin break {
@include output((clear: both));
}
// NoBreak
// -------
// Cancel the break() effect, e.g. when using media queries.
@mixin nobreak {
@include output((clear: none));
}
// Full
// ----
// - [$context]: <layout shorthand>
@mixin full(
$context: $susy
) {
$inspect : $context;
@include susy-inspect(full, $inspect);
@include span(full of parse-grid($context) break);
}
// First
// -----
// - [$context]: <settings>
@mixin first(
$context: $susy
) {
$inspect : $context;
$context : parse-grid($context);
$flow : susy-get(flow, $context);
@include susy-inspect(first, $inspect);
@if not(is-split($context)) {
@include float-first($flow);
}
}
@mixin alpha(
$context: $susy
) {
@include first($context);
}
// Last
// ----
// - [$context]: <settings>
@mixin last(
$context: $susy
) {
$inspect : $context;
$context : parse-grid($context);
@include susy-inspect(last, $inspect);
$output: (
flow: susy-get(flow, $context),
last-flow: susy-get(last-flow, $context),
margin: if(is-split($context), null, 0),
);
@include float-last($output...);
}
@mixin omega(
$context: $susy
) {
@include last($context);
}
// Get Edge
// --------
// Calculate edge value based on location, if possible
@function get-edge(
$span
) {
$span : parse-span($span);
$edge : susy-get(edge, $span);
@if not($edge) {
$count: susy-count(susy-get(columns, $span));
$location: susy-get(location, $span);
$n: susy-get(span, $span);
$number: if(type-of($location) == number, true, false);
$index: if($number and unitless($location), true, false);
@if $n == $count {
$edge: full;
} @else if $location and $n and $index {
@if $location == 1 {
$edge: if($n == $count, full, first);
} @else if $location + $n - 1 == $count {
$edge: last;
}
}
}
@if $edge == alpha or $edge == omega {
$edge: if($edge == alpha, first, last);
}
@return $edge;
}
// Get Location
// ------------
// Calculate location value based on edge, if possible
@function get-location(
$span
) {
$span : parse-span($span);
$location : susy-get(location, $span);
$edge : get-edge($span);
$n : susy-get(span, $span);
@if $edge and not($location) and type-of($n) == number and unitless($n) {
@if $edge == first {
$location: 1;
} @else if $edge == last {
$location: susy-count(susy-get(columns, $span)) - $n + 1;
}
}
@return $location
}

View file

@ -0,0 +1,216 @@
// Susy Settings
// =============
// Susy Language Defaults
// ----------------------
// - PRIVATE
@include susy-defaults((
container: auto,
math: fluid,
output: float,
container-position: center,
gutter-position: after,
global-box-sizing: content-box,
debug: (
image: hide,
color: rgba(#66f, .25),
output: background,
toggle: top right,
),
));
// Valid Keyword Values
// --------------------
// - PRIVATE: DONT'T TOUCH
$susy-keywords: (
container: auto,
math: static fluid,
output: isolate float,
container-position: left center right,
flow: ltr rtl,
gutter-position: before after split inside inside-static,
box-sizing: border-box content-box,
span: full,
edge: first alpha last omega full,
spread: narrow wide wider,
gutter-override: no-gutters no-gutter,
role: nest,
clear: break nobreak,
debug image: show hide show-columns show-baseline,
debug output: background overlay,
);
// Parse Susy Keywords and Maps
// ----------------------------
@function parse-settings(
$short: $susy
) {
$_return: ();
@if type-of($short) == map {
$_return: $short;
} @else {
@each $item in $short {
// strings
@if type-of($item) == string {
@each $key, $value in $susy-keywords {
@if index($value, $item) {
$_key-value: append($key, $item);
$_return: _susy-deep-set($_return, $_key-value...);
}
}
// maps
} @else if type-of($item) == map {
$_return: map-merge($_return, $item);
}
}
}
@return $_return;
}
// Parse Columns & Gutters
// -----------------------
@function parse-layout(
$short
) {
$_return: ();
$_columns: ();
$_gutters: null;
@if not(unitless(nth(nth($short, 1), 1))) {
$_gutters: nth($short, 1);
} @else {
$_columns: (columns: nth($short, 1));
$_gutters: if(length($short) > 1, nth($short, 2), $_gutters);
}
@if type-of($_gutters) == list and length($_gutters) > 0 {
$_gutters: (
gutters: nth($_gutters, 2) / nth($_gutters, 1),
column-width: nth($_gutters, 1),
);
} @else {
$_gutters: if($_gutters, (gutters: $_gutters), ());
}
$_return: map-merge($_return, $_columns);
$_return: map-merge($_return, $_gutters);
@return $_return;
}
// Parse Grid/Context
// ------------------
@function parse-grid(
$short: $susy
) {
$_return: parse-settings($short);
$_layout: ();
@if type-of($short) == map {
$_return: $short;
} @else {
@each $item in $short {
// number or list
@if type-of($item) == number or type-of($item) == list {
@if type-of($item) == list or unitless($item) {
$_layout: append($_layout, $item);
} @else {
$_return: map-merge($_return, (container: $item));
}
}
}
$_layout: if(length($_layout) > 0, parse-layout($_layout), $_layout);
}
@return map-merge($_return, $_layout);
}
// Parse Span
// ----------
@function parse-span(
$short,
$key: span
) {
$_return: ();
@if type-of($short) == map {
$_return: $short;
} @else {
$_at: index($short, at);
@if $_at {
$_loci: $_at + 1;
$_location: nth($short, $_loci);
$_return: map-merge($_return, (location: $_location));
$short: set-nth($short, $_at, null);
$short: set-nth($short, $_loci, null);
}
$_i: 1;
$_span: ();
@while $_i <= length($short) {
$_this: nth($short, $_i);
@if type-of($_this) == number {
$_span: append($_span, $_this);
$short: set-nth($short, $_i, null);
} @else if $_this == of {
$short: set-nth($short, $_i, null);
$_i: length($short) + 1;
}
$_i: $_i + 1;
}
@if length($_span) > 0 {
$_span: if(length($_span) == 1, nth($_span, 1), $_span);
$_return: map-merge($_return, ($key: $_span));
}
$_return: map-merge($_return, parse-grid($short));
}
@return $_return;
}
// Parse Gutters
// -------------
@function parse-gutters(
$short: $susy
) {
$_gutters: parse-span($short, gutter-override);
$_span: susy-get(gutter-override, $_gutters);
@if $_span and not(map-get($_gutters, columns)) {
$_context: ();
$_new: ();
@each $item in $_span {
@if type-of($item) == number and unitless($item) {
$_context: append($_context, $item);
} @else {
$_new: append($_new, $item);
}
}
$_context: parse-grid($_context);
$_new: if(length($_new) == 0, null, $_new);
$_new: if(length($_new) == 1, nth($_new, 1), $_new);
$_new: (gutter-override: if($_new != $_span, $_new, $_span));
$_gutters: map-merge($_gutters, $_new);
$_gutters: map-merge($_gutters, $_context);
}
@return $_gutters;
}

View file

@ -0,0 +1,163 @@
// Span Syntax
// ===========
// Span [mixin]
// ------------
// Set a spanning element using shorthand syntax.
// - $span : <span>
@mixin span(
$span
) {
$inspect: $span;
$span: parse-span($span);
$output: span-math($span);
$nesting: susy-get(span, $span);
$clear: susy-get(clear, $span);
$box: susy-get(box-sizing, $span);
$content-box: if(susy-get(global-box-sizing) != 'border-box', true, false);
$box: $box or if(is-inside($span) and $content-box, border-box, null);
@if $clear == break {
@include break;
} @else if $clear == nobreak {
@include nobreak;
}
@include susy-inspect(span, $inspect);
@include output((box-sizing: $box));
@include float-span-output($output...);
@if valid-columns($nesting, silent) {
@include nested($span) { @content; }
} @else {
@content;
}
}
// Span [function]
// ---------------
// Return the width of a span.
// - $span : <span>
@function span(
$span
) {
@return get-span-width($span);
}
// Span Math
// ---------
// Get all the span results.
// - $span: <map>
@function span-math(
$span
) {
$nest : if(susy-get(role, $span) == nest, true, false);
$split-nest : if(is-split($span) and $nest, true, false);
$edge : get-edge($span);
$location : get-location($span);
$float : from;
$padding-before : null;
$padding-after : null;
$margin-before : null;
$margin-after : null;
// calculate widths
$spread: index(map-values($span), spread);
$span: if($split-nest and not($spread), map-merge($span, (spread: wide)), $span);
$width: get-span-width($span);
$gutters: get-gutters($span);
// apply gutters
@if is-inside($span) {
@if not(susy-get(role, $span)) {
$padding-before: map-get($gutters, before);
$padding-after: map-get($gutters, after);
}
} @else {
@if not($split-nest) {
$margin-before: map-get($gutters, before);
$margin-after: map-get($gutters, after);
}
}
// special margin handling
@if susy-get(output, $span) == isolate and $location {
$margin-before: get-isolation($span);
$margin-after: -100%;
} @else if $edge {
$is-split: is-split($span);
$pos: susy-get(gutter-position, $span);
@if $edge == last {
$float: susy-get(last-flow, $span);
}
@if not($is-split) {
@if $edge == full or ($edge == first and $pos == before) {
$margin-before: 0;
}
@if $edge == full or ($edge == last and $pos == after) {
$margin-after: 0;
}
}
}
@return (
width : $width,
float : $float,
margin-before : $margin-before,
margin-after : $margin-after,
padding-before : $padding-before,
padding-after : $padding-after,
flow : susy-get(flow, $span),
);
}
// Get Span Width
// --------------
// Return span width.
// - $span: <map>
@function get-span-width(
$span
) {
$span : parse-span($span);
$n : susy-get(span, $span);
$location : get-location($span);
$columns : susy-get(columns, $span);
$gutters : susy-get(gutters, $span);
$spread : susy-get(spread, $span);
$context : null;
$span-sum : null;
$width : null;
@if $n == 'full' {
$pos: susy-get(gutter-position, $span);
$role: susy-get(role, $span);
$n: if($pos == split and $role != nest, susy-count($columns), 100%);
}
@if type-of($n) != number {
@warn "(#{type-of($n)}) #{$n} is not a valid span.";
} @else if unitless($n) {
$context: susy-sum($columns, $gutters, if(is-split($span), wide, narrow));
$spread: if(is-inside($span), $spread or wide, $spread);
$span-sum: susy($n, $location, $columns, $gutters, $spread);
$_math: susy-get(math, $span);
$_column-width: susy-get(column-width, $span);
@if $_math == static {
$width: $span-sum * valid-column-math($_math, $_column-width);
} @else {
$width: percentage($span-sum / $context);
}
} @else {
$width: $n;
}
@return $width;
}

View file

@ -0,0 +1,16 @@
// Validation
// ==========
// Validate Column Math
// --------------------
@function valid-column-math(
$math,
$column-width
) {
@if $math == static and not($column-width) {
@error 'Static math requires a valid column-width setting.';
}
@return $column-width;
}

View file

@ -0,0 +1,18 @@
// ---------------------------------------------------------------------------
// Imports
@import "compass/layout/grid-background";
@import "compass/css3/background-origin";
@import "compass/css3/background-clip";
// ---------------------------------------------------------------------------
// Susy Grid Background
//
// A wrapper for the compass "column-grid-background" mixin
// Uses all your settings to create a grid background for a container element.
// Note: Sub-pixel rounding can lead to several pixels of variation between browsers.
@mixin susy-grid-background(){
@include column-grid-background($total-columns, column(), gutter(), 0);
@include background-origin(content-box);
@include background-clip(content-box);
}

View file

@ -0,0 +1,377 @@
// ---------------------------------------------------------------------------
// Imports
// We need access to some basic font settings for handling media-queries.
@import "compass/typography/vertical_rhythm";
// For now, we also need this...
$browser-default-font-size-px : 16px;
$browser-default-font-size-percent : 100%;
$browser-default-font-size-pt : 12pt;
$rem-with-px-fallback : true !default;
// ---------------------------------------------------------------------------
// Sass list Functions
// Return a list with specific items removed
//
// filter($list, $target)
// - $list : The list to filter.
// - $target : An item to be removed from the list.
@function filter($list, $target) {
$clean: compact();
@if index($list, $target) {
@each $item in $list {
$clean: if($item == $target, $clean, append($clean, $item));
}
} @else { $clean: $list; }
@return $clean;
}
// ---------------------------------------------------------------------------
// Don't use static output when it will break things
// Switch element-level output to fluid, when container-width is wrong for static
//
// fix-static-misalignment([$style, $width])
// - $style: $container-style.
// - $width: $container-width.
@function fix-static-misalignment(
$style: $container-style,
$width: $container-width
) {
@if $container-width and $container-width != container-outer-width($width: false) {
$style: fluid;
}
@return $style;
}
// ---------------------------------------------------------------------------
// Grid Functions
// Returns the full width of a grid based on your grid settings.
//
// $columns : The number of columns to get width for.
@function columns-width(
$columns : $total-columns
) {
@if round($columns) != $columns {
@warn "Susy works best with integer column-spans." +
"For partial-columns, you may need to finesse the math by hand using functions directly.";
}
@return ($columns * $column-width) + (if($columns >= 1, ceil($columns - 1), 0) * $gutter-width);
}
// Return the grid width after adding or subtracting grid padding
//
// $width : the width of the grid without padding;
// $operation : ( add | subtract ) if padding should be added or subtracted;
@function handle-grid-padding(
$width,
$operation : subtract
) {
$pad: $grid-padding*2;
@if comparable($width, $grid-padding) {
$width: if($operation == subtract, $width - $pad, $width + $pad);
} @else {
@warn "$grid-padding must be set in units comparable to the container width.";
}
@return $width;
}
// Return the full outer width of a Container element.
//
// $columns : The number of columns in the Grid Layout.
@function container-outer-width(
$columns : $total-columns,
$width : $container-width
) {
$outerwidth: if($width, $width, columns-width($columns));
@if $width {
@if not($border-box-sizing) { $outerwidth: handle-grid-padding($outerwidth, subtract); }
} @else {
@if $border-box-sizing { $outerwidth: handle-grid-padding($outerwidth, add); }
}
@return $outerwidth;
}
// Return the percentage width of a single column in a given 'context'.
//
// $context : The grid context in columns, if nested.
// $style : The container style to use.
@function column(
$context : $total-columns,
$style : fix-static-misalignment()
) {
@return if($style == static, $column-width, relative-width($column-width, $context));
}
// Return the percentage width of multiple 'columns' in a given 'context'.
//
// $columns : The number of columns to get relative width for.
// $context : The grid context in columns, if nested.
// $style : The container style to use.
@function columns(
$columns,
$context : $total-columns,
$style : fix-static-misalignment()
) {
@return if($style == static, columns-width($columns), relative-width(columns-width($columns), $context));
}
// Return the percentage width of a single gutter in a given 'context'.
//
// $context : The grid context in columns, if nested.
// $style : The container style to use.
@function gutter(
$context : $total-columns,
$style : fix-static-misalignment()
) {
@return if($style == static, $gutter-width, relative-width($gutter-width, $context));
}
// Return the percentage width of a given value in a given 'context'.
//
// $width : Any given width value.
// $context : The grid context in columns, if nested.
@function relative-width(
$width,
$context : $total-columns
) {
@return percentage($width / columns-width($context));
}
// Return the total space occupied by multiple columns and associated gutters.
// Useful for adding padding or margins (prefix, suffix, push, pull, etc.)
//
// $columns : The number of columns to get relative space for.
// $context : The grid context in columns, if nested.
// $style : The container style to use.
@function space(
$columns,
$context : $total-columns,
$style : fix-static-misalignment()
) {
@return columns($columns, $context, $style) + if($columns >= 1, gutter($context, $style), 0);
}
// Accept a list including column-count and (optional) position.
// Return either the column count or the position alone.
//
// $columns : the list to split and interprate.
// $request : The value to return, either 'columns' or 'position'.
@function split-columns-value(
$columns,
$request : columns
) {
$pos : false;
$cols : false;
@each $var in $columns {
@if (type-of($var) == 'string') {
$pos: $var;
} @else {
@if (type-of($var) == 'number') and (unitless($var)) {
$cols: $var;
} @else {
@warn '"#{$var}" is not a valid part of "$columns: #{$columns}" in the columns() mixin.';
}
}
}
@if $request == 'columns' {
@return $cols;
} @else {
@if $request == 'position' {
@return $pos;
} @else {
@warn '"#{$request}" is not a valid value for $request';
}
}
}
// Accept nth-selector variables, and format them as a valid CSS3 selector.
//
// $n : [first | only | last | <equation>]
// $selector : [child | last-child | of-type | last-of-type ]
@function format-nth(
$n : last,
$selector : child
) {
@if ($n == 'last') or ($n =='first') or ($n =='only') {
$selector: '#{$n}-#{$selector}';
} @else {
$selector: 'nth-#{$selector}(#{$n})';
}
@return $selector;
}
// ---------------------------------------------------------------------------
// Media Functions
// Return an em value adjusted to match the browser default font size.
// Note: This only works if actual sizes are set relative to browser defaults.
//
// $ems : The initial value to be converted.
// $font-size : The current font-size in.
@function base-ems(
$ems,
$font-size: $base-font-size
){
$font-size : if(unit($ems) == 'rem', $base-font-size, $font-size);
$unit : unit($font-size);
$mult : $ems / ($ems * 0 + 1);
@if $unit == 'px' {
@return $font-size / $browser-default-font-size-px * $mult * 1em;
}
@else if $unit == '%' {
@return $font-size / $browser-default-font-size-percent * $mult * 1em;
}
@else if $unit == 'em' {
@return $font-size / 1em * $mult * 1em;
}
@else if $unit == 'pt' {
@return $font-size / $browser-default-font-size-pt * $mult * 1em;
}
@else {
@warn 'Variable $base-font-size does not have a valid font unit. Valid units for fonts in CSS are px, pt, em, and %.';
}
}
// This name will be deprecated...
@function absolute-ems(
$ems,
$font-size: $base-font-size
){
@return base-ems( $ems, $font-size);
}
// Return a length, after any em-values have been sent through absolute-ems().
//
// $length : The length value to be checked and adjusted if necessary.
// $font-size : The current font-size in px.
@function fix-ems(
$length,
$font-size: $base-font-size
){
@if $length {
@if (unit($length) == 'em') or (unit($length) == 'rem') {
$length: absolute-ems($length,$font-size);
}
}
@return $length;
}
// Sort a list of arguments into "$min $layout $max $ie" order, and return the list.
//
// $media-layout : a list of values [$min $layout $max $ie] including...
// : - one unitless number (columns in a layout)
// : - two optional lengths (min and max-width media-query breakpoints).
// : - one optional boolean or string to trigger fallback support for IE.
// $font-size : [optional] The base font-size of your layout, if you are using ems.
// : - defaults to $base-font-size
@function medialayout(
$media-layout,
$font-size: $base-font-size
) {
$media : false;
$min : false;
$layout : false;
$max : false;
$ie : false;
$has-layout : false;
@each $val in $media-layout {
@if (type-of($val) == "number") {
@if unitless($val) {
$layout : $val;
$has-layout : true;
} @else {
@if ($has-layout) and not($media) {
$max: $val;
} @else {
@if $media {
$media: join($media,$val);
} @else {
$media: $val;
}
}
}
} @else {
$ie: $val;
}
}
@if (length($media) > 0) {
@if (length($media) == 1) {
$min: nth($media,1);
} @else {
$min: nth($media,1);
$max: nth($media,2);
@if comparable($min, $max) {
@if ($min > $max) {
$max: nth($media,1);
$min: nth($media,2);
}
} @else {
@warn "Can't compare incompatible units." +
"Using #{$min} for min-width, and #{$max} for max-width";
}
@if (length($media) > 2) {
@warn "You can only send two lengths: a min-width and an (optional) max-width." +
"You sent #{length($media)}: #{$media}";
}
}
}
// media-queries must be set in ems relative to the browser default
// rather than the font-size set in CSS.
$min: fix-ems($min,$font-size);
$max: fix-ems($max,$font-size);
@return $min $layout $max $ie;
}
// Return the nearest layout (column-count) above a given breakpoint.
//
// $min : The min-width media-query breakpoint above which to establish a new layout.
@function get-layout(
$min
) {
$min : fix-ems($min);
$return : false;
@if comparable($min, $column-width) {
$return : ceil(($min + $gutter-width) / ($column-width + $gutter-width));
} @else {
@warn "Can't determine a layout, becuse #{$min} and #{$column-width} are not comparable.";
}
@return $return;
}
// Check to see if a given $media-layout list is simply the default.
//
// $media-layout : a list of values including -
// : One unitless number (columns in a layout)
// : Two optional lengths (min and max-width media-query breakpoints).
// : One optional boolean or string to trigger fallback support for IE.
@function is-default-layout(
$media-layout
) {
$media-layout : medialayout($media-layout);
$min : nth($media-layout,1);
$layout-cols : nth($media-layout,2);
$max : nth($media-layout,3);
@if $min or $max {
@return false;
} @else {
@return if($layout-cols == $total-columns,true,false);
}
}

View file

@ -0,0 +1,312 @@
// ---------------------------------------------------------------------------
// Imports
@import "compass/utilities/general/clearfix";
@import "compass/css3/box-sizing";
// ---------------------------------------------------------------------------
// Border-Box Sizing
// Apply the border-box sizing model to all elements
// and adjust the grid math appropriately.
@mixin border-box-sizing {
$border-box-sizing: true !global;
* { @include box-sizing(border-box); }
}
// ---------------------------------------------------------------------------
// Container
// Set the width of a container
//
// $columns : The number of columns in the Grid Layout.
@mixin set-container-width(
$columns : $total-columns,
$style : $container-style,
$px-vals : $pixel-values-only
){
$width: container-outer-width($columns);
@if $style == 'static' {
@if $px-vals == true {
width: round(convert-length($width, px));
} @else {
@include rem(width, $width);
}
} @else {
@if $style == 'fluid' {
@if unit($width) == '%' {
@if $px-vals == true {
width: round(convert-length($width, px));
} @else {
@include rem(width, $width);
}
}
} @else {
@if $px-vals == true {
max-width: round(convert-length($width, px));
} @else {
@include rem(max-width, $width);
}
@include for-legacy-browser(ie,"6") {
@if unit($width) == 'rem' {
_width: round(convert-length($width, px));
} @else {
_width: $width;
}
}
}
}
}
// Set the outer grid-containing element(s).
//
// $columns : The number of columns in the container.
@mixin apply-container(
$columns : $total-columns,
$px-vals : $pixel-values-only
){
@include pie-clearfix;
@include set-container-width($columns);
@if $px-vals == true {
padding-left: round(convert-length($grid-padding, px));
padding-right: round(convert-length($grid-padding, px));
} @else {
@include rem(padding-left, $grid-padding);
@include rem(padding-right, $grid-padding);
}
margin: { left: auto; right: auto; }
}
// Set one or more layouts on a grid-containing element at any number of media-query breakpoints.
//
// $media-layout-1 : [default:$total-columns] A list of values including -
// : One unitless number (representing columns in a layout)
// : Two optional lengths (representing min and max-width media-query breakpoints).
// $media-layout-2 ...-10 : [optional] Same as $media-layout-1
@mixin container(
$media-layouts...
){
$media-layouts: if(length($media-layouts) > 0, $media-layouts, $total-columns);
@each $ml in $media-layouts {
@if is-default-layout($ml) {
@include apply-container;
} @else {
@include at-breakpoint($ml) {
@include apply-container;
}
}
}
}
// ---------------------------------------------------------------------------
// Columns
// Create a grid element spanning any number of 'columns' in a grid 'context'.
// $columns : The number of columns to span.
// $context : [optional] The context (columns spanned by parent).
// : Context is required on any nested elements.
// : Context MUST NOT be declared on a root element.
// $padding : [optional] Padding applied to the inside of individual grid columns.
// : Padding is only output if one or two values are specified (e.g. 1em or 10px 20px)
// : Padding values are applied only on the horizontal axis in from-to order
// $from : The start direction of your layout (e.g. 'left' for ltr languages)
// $style : The container style to use.
@mixin span-columns(
$columns,
$context : $total-columns,
$padding : false,
$from : $from-direction,
$style : fix-static-misalignment()
) {
$from : unquote($from);
$to : opposite-position($from);
$pos : split-columns-value($columns,position);
$cols : split-columns-value($columns,columns);
$pad-from : if($style == static, 0 * $gutter-width, relative-width(0 * $gutter-width, $context));
$pad-to : if($style == static, 0 * $gutter-width, relative-width(0 * $gutter-width, $context));
@if $padding != false {
$pad-from : nth($padding, 1);
@if length($padding) > 1 {
$pad-to: nth($padding, 2);
} @else {
$pad-to: $pad-from;
}
$pad-from : if($style == static, $pad-from, relative-width($pad-from, $context));
$pad-to : if($style == static, $pad-to, relative-width($pad-to, $context));
padding-#{$from}: $pad-from;
padding-#{$to}: $pad-to;
}
width: columns($cols, $context, $style) - if($border-box-sizing, 0, $pad-to + $pad-from);
@if ($pos == 'omega') {
@include omega($from);
} @else {
float: $from;
margin-#{$to}: gutter($context, $style);
@include for-legacy-browser(ie, "6") {
display: inline;
}
}
}
// Apply to elements spanning the last column, to account for the page edge.
// Only needed as an override. Normally 'omega' can just be called by `columns`.
//
// $from : The start-direction for your document.
@mixin omega(
$from : $from-direction
) {
$from : unquote($from);
$to : opposite-position($from);
$hack : opposite-position($omega-float);
float: $omega-float;
margin-#{$to}: 0;
@include for-legacy-browser(ie, "6", "7") {
*margin-#{$hack}: - $gutter-width;
@include for-legacy-browser(ie, "6") {
display: inline;
}
}
}
// Shortcut to apply omega to a specific subset of elements.
//
// $n : [first | only | last | <equation>]
// $selector : [child | last-child | of-type | last-of-type ]
// $from : The start-direction for your document.
@mixin nth-omega(
$n : last,
$selector : child,
$from : $from-direction
) {
$from : unquote($from);
&:#{format-nth($n,$selector)} {
@if $n == "first" {
@include omega($from);
} @else {
@include with-browser-ranges(css-sel3) {
@include omega($from);
}
}
}
}
// ---------------------------------------------------------------------------
// Resets
// Reset a '+columns' grid element to default block behavior
//
// $from : The start direction of your layout (e.g. 'left' for ltr languages)
@mixin reset-columns(
$from: $from-direction
) {
$from : unquote($from);
$to : opposite-position($from);
$hack : opposite-position($omega-float);
float: none;
width: auto;
margin-#{$to}: auto;
@include for-legacy-browser(ie, "6", "7") {
*margin-#{$hack}: auto;
@include for-legacy-browser(ie, "6") {
display: block;
}
}
}
// Apply to elements previously set as omega.
// This will return floats and margins back to non-omega settigns.
//
// $context : [optional] The context (columns spanned by parent).
// $from : The start-direction for your document.
// $style : The container style to use.
@mixin remove-omega(
$context : $total-columns,
$from : $from-direction,
$style : fix-static-misalignment()
) {
$from : unquote($from);
$to : opposite-position($from);
$hack : opposite-position($omega-float);
float: $from;
margin-#{$to}: gutter($context, $style);
@include for-legacy-browser(ie, "6", "7") {
*margin-#{$hack}: auto;
}
}
// Shortcut to apply remove-omega to a specific subset of elements.
//
// $n : [first | only | last | <equation>]
// $selector : [child | last-child | of-type | last-of-type ]
// $context : [optional] The context (columns spanned by parent).
// $from : The start-direction for your document.
// $style : The container style to use.
@mixin remove-nth-omega(
$n : last,
$selector : child,
$context : $total-columns,
$from : $from-direction,
$style : fix-static-misalignment()
) {
$from : unquote($from);
&:#{format-nth($n,$selector)} {
@if $n == "first" {
@include remove-omega($context, $from, $style);
} @else {
@include with-browser-ranges(css-sel3) {
@include remove-omega($context, $from, $style);
}
}
}
}
// ---------------------------------------------------------------------------
// Change Settings
@mixin with-grid-settings(
$columns: $total-columns,
$width: $column-width,
$gutter: $gutter-width,
$padding: $grid-padding
) {
// keep the defaults around
$default-columns: $total-columns;
$default-width: $column-width;
$default-gutter: $gutter-width;
$default-padding: $grid-padding;
// use the new settings
$total-columns: $columns !global;
$column-width: $width !global;
$gutter-width: $gutter !global;
$grid-padding: $padding !global;
// apply to contents
@content;
// re-instate the defaults
$total-columns: $default-columns !global;
$column-width: $default-width !global;
$gutter-width: $default-gutter !global;
$grid-padding: $default-padding !global;
}

View file

@ -0,0 +1,51 @@
// ---------------------------------------------------------------------------
// Isolation
// Isolate the position of a grid element (use in addition to span-columns)
//
// $location : The grid column to isolate in, relative to the container;
// $context : [optional] The context (columns spanned by parent).
// $from : The start direction of your layout (e.g. 'left' for ltr languages)
@mixin isolate(
$location,
$context: $total-columns,
$from: $from-direction,
$style: fix-static-misalignment()
) {
$to: opposite-position($from);
margin-#{$to}: -100%;
margin-#{$from}: space($location - 1, $context, $style);
}
// Isolate a group of elements in a grid, using nth-child selectors
//
// $columns : The column-width of each item on the grid;
// $context : [optional] The context (columns spanned by parent).
// $selector : [child | of-type | last-of-type ] (default is 'child')
// $from : The start direction of your layout (e.g. 'left' for ltr languages)
@mixin isolate-grid(
$columns,
$context: $total-columns,
$selector: 'child',
$from: $from-direction,
$style: fix-static-misalignment()
) {
$to: opposite-position($from);
$location: 1;
$line: floor($context / $columns);
@include span-columns($columns, $context, $from: $from, $style: $style);
margin-#{$to}: -100%;
@for $item from 1 through $line {
$nth: '#{$line}n + #{$item}';
&:#{format-nth($nth,$selector)} {
margin-#{$from}: space($location - 1, $context, $style);
@if $location == 1 { clear: $from; }
@else { clear: none; }
$location: $location + $columns;
@if $location > $context { $location: 1; }
}
}
}

View file

@ -0,0 +1,93 @@
// ---------------------------------------------------------------------------
// Margin Mixins
// Apply 'columns' margin before an element to push it along the grid.
//
// $columns : The number of columns to span.
// $context : [optional] The context (columns spanned by parent).
// : Context is required on any nested elements.
// : Context MUST NOT be declared on a root element.
// $from : The start direction of your layout (e.g. 'left' for ltr languages)
// $style : The container style to use.
@mixin pre(
$columns,
$context : $total-columns,
$from : $from-direction,
$style : fix-static-misalignment()
) {
$from : unquote($from);
margin-#{$from}: space($columns, $context, $style);
}
// 'push' is a synonymn for 'pre'
@mixin push(
$columns,
$context : $total-columns,
$from : $from-direction,
$style : fix-static-misalignment()
) {
$from : unquote($from);
@include pre($columns, $context, $from, $style);
}
// Apply negative 'columns' margin before an element to pull it along the grid.
//
// $columns : The number of columns to span.
// $context : [optional] The context (columns spanned by parent).
// : Context is required on any nested elements.
// : Context MUST NOT be declared on a root element.
// $from : The start direction of your layout (e.g. 'left' for ltr languages)
// $style : The container style to use.
@mixin pull(
$columns,
$context : $total-columns,
$from : $from-direction,
$style : fix-static-misalignment()
) {
$from : unquote($from);
margin-#{$from}: 0 - space($columns, $context, $style);
}
// Apply 'columns' margin after an element to contain it in a grid.
//
// $columns : The number of columns to span.
// $context : [optional] The context (columns spanned by parent).
// : Context is required on any nested elements.
// : Context MUST NOT be declared on a root element.
// $from : The start direction of your layout (e.g. 'left' for ltr languages)
// $style : The container style to use.
@mixin post(
$columns,
$context : $total-columns,
$from : $from-direction,
$style : fix-static-misalignment()
) {
$from : unquote($from);
$to : opposite-position($from);
margin-#{$to}: space($columns, $context, $style);
}
// Apply 'columns' before and/or after an element to contain it on a grid.
//
// $pre : The number of columns to add as margin before.
// $post : The number of columns to add as margin after.
// $context : [optional] The context (columns spanned by parent).
// : Context is required on any nested elements.
// : Context MUST NOT be declared on a root element.
// $from : The start direction of your layout (e.g. 'left' for ltr languages)
// $style : The container style to use.
@mixin squish(
$pre : false,
$post : false,
$context : $total-columns,
$from : $from-direction,
$style : fix-static-misalignment()
) {
$from : unquote($from);
@if $pre {
@include pre($pre, $context, $from, $style)
}
@if $post {
@include post($post, $context, $from, $style)
}
}

View file

@ -0,0 +1,105 @@
// ---------------------------------------------------------------------------
// Media Mixins
// Create a new layout context for (@content) descendants.
//
// $layout-cols : a (unitless) number of columns to use for this layout.
@mixin layout(
$layout-cols
) {
// store default $total-columns setting for later, then change it.
$default-layout : $total-columns;
$total-columns : $layout-cols !global;
// apply children in this new layout context.
@content;
// return to default $total-columns setting.
$total-columns : $default-layout !global;
}
// Nest a block of code inside a new media-query and layout context.
//
// $media-layout : a list of values [$min $layout $max $ie] including...
// : - one unitless number (columns in a layout)
// : - two optional lengths (min and max-width media-query breakpoints).
// : - one optional boolean or string to trigger fallback support for IE.
// $font-size : [optional] The base font-size of your layout, if you are using ems.
// : - defaults to $base-font-size
@mixin at-breakpoint(
$media-layout,
$font-size: $base-font-size
) {
$media-layout : medialayout($media-layout,$font-size);
$min : nth($media-layout,1);
$layout : nth($media-layout,2);
$max : nth($media-layout,3);
$ie : nth($media-layout,4);
@if not($breakpoint-media-output) and not($breakpoint-ie-output) and not($breakpoint-raw-output) {
@warn "Either $breakpoint-media-output, $breakpoint-ie-output, or $breakpoint-raw-output must be true for at-breakpoint to work.";
}
// We need to have either a min-width breakpoint or a layout in order to proceed.
@if $min or $layout or $max {
// If we don't have a layout, we create one based on the min-width.
@if not($layout) {
$layout: get-layout($min);
}
// If we still don't have a layout, we have a problem.
@if $layout {
// Set our new layout context.
@include layout($layout) {
@if $breakpoint-media-output {
@include with-browser-ranges(css-mediaqueries) {
@if $min and $max {
// Both $min and $max
@media (min-width: $min) and (max-width: $max) {
@content;
}
} @else {
@if not($min) and not($max) {
// Neither $min nor $max:
// We can create a breakpoint based on the number of columns in the layout.
$min: fix-ems(container-outer-width($width: false));
}
@if $min {
// Min only:
@media (min-width: $min) {
@content;
}
} @else {
// Max only:
@media (max-width: $max) {
@content;
}
}
}
}
}
// Set an IE fallback
@if $ie and $breakpoint-ie-output {
@if (type-of($ie) == 'bool') {
$ie: 'lt-ie9';
}
.#{$ie} & {
@content;
}
}
@if $breakpoint-raw-output {
@content;
}
}
} @else {
@warn "We were unable to determine a layout for your breakpoint.";
}
} @else {
@warn "You need to provide either a valid layout (number of columns)"
+ "or a valid media-query min-width breakpoint (length).";
}
}

View file

@ -0,0 +1,92 @@
// ---------------------------------------------------------------------------
// Padding Mixins
// add empty colums as padding before an element.
// $columns : The number of columns to prefix.
// $context : [optional] The context (columns spanned by parent).
// : Context is required on any nested elements.
// : Context MUST NOT be declared on a root element.
// $from : The start direction of your layout (e.g. 'left' for ltr languages)
// $style : The container style to use.
@mixin prefix(
$columns,
$context : $total-columns,
$from : $from-direction,
$style : fix-static-misalignment()
) {
$from : unquote($from);
padding-#{$from}: space($columns, $context, $style);
}
// add empty colums as padding after an element.
// $columns : The number of columns to suffix.
// $context : [optional] The context (columns spanned by parent).
// : Context is required on any nested elements.
// : Context MUST NOT be declared on a root element.
// $from : The start direction of your layout (e.g. 'left' for ltr languages)
// $style : The container style to use.
@mixin suffix(
$columns,
$context : $total-columns,
$from : $from-direction,
$style : fix-static-misalignment()
) {
$from : unquote($from);
$to : opposite-position($from);
padding-#{$to}: space($columns, $context, $style);
}
// add empty colums as padding before and after an element.
// $columns : The number of columns to pad.
// $context : [optional] The context (columns spanned by parent).
// : Context is required on any nested elements.
// : Context MUST NOT be declared on a root element.
// $from : The start direction of your layout (e.g. 'left' for ltr languages)
// $style : The container style to use.
@mixin pad(
$prefix : false,
$suffix : false,
$context : $total-columns,
$from : $from-direction,
$style : fix-static-misalignment()
) {
$from : unquote($from);
@if $prefix {
@include prefix($prefix, $context, $from, $style);
}
@if $suffix {
@include suffix($suffix, $context, $from, $style);
}
}
// Bleed into colums with margin/padding on any side of an element.
// $width : The side of the bleed.
// : Any unit-length will be used directly.
// : Any unitless number will be used as a column-count.
// : Use "2 of 6" format to represent 2 cals in a 6-col nested context.
// $sides : One or more sides to bleed [ top | right | bottom | left | all ].
// $style : The container style to use.
@mixin bleed(
$width: $grid-padding,
$sides: left right,
$style: fix-static-misalignment()
) {
@if $border-box-sizing { @include box-sizing(content-box) }
@if type-of($width) == 'list' {
$width: filter($width, of);
$width: space(nth($width,1), nth($width,2), $style);
} @else if unitless($width) {
$width: space($width, $style: $style);
}
@if $sides == 'all' {
margin: - $width;
padding: $width;
} @else {
@each $side in $sides {
margin-#{$side}: - $width;
padding-#{$side}: $width;
}
}
}

View file

@ -0,0 +1,60 @@
// ---------------------------------------------------------------------------
// Susy Settings
// The total number of columns in the grid
$total-columns : 12 !default;
// The width of columns and gutters.
// These must all be set with the comparable units.
$column-width : 4em !default;
$gutter-width : 1em !default;
// Padding on the left and right of a Grid Container.
$grid-padding : $gutter-width !default;
// ---------------------------------------------------------------------------
// Advanced Settings
// From Direction:
// Controls for right-to-left or bi-directional sites.
$from-direction : left !default;
// Omega Float Direction:
// The direction that +omega elements are floated by deafult.
$omega-float : opposite-position($from-direction) !default;
// Container Width:
// Override the total width of your grid, using any length (50em, 75%, etc.)
$container-width : false !default;
// Container Style:
// 'magic' - Static (fixed or elastic) when there's enough space,
// fluid when there isn't. This is the SUSY MAGIC SAUCE(TM).
// 'static' - Forces the grid container to remain static at all times.
// 'fluid' - Forces the grid to remain fluid at all times.
// (this will overrule any static $container-width settings)
$container-style : magic !default;
// Border-Box Sizing
// Adjust the grid math appropriately for box-sizing: border-box;
// Warning: This does not actually apply the new box model!
// In most cases you can ignore this setting,
// and simply apply the border-box-sizing mixin.
$border-box-sizing : false !default;
// Pixel Values only:
// Make sure only pixel values are set for the container width.
$pixel-values-only : false !default;
// ---------------------------------------------------------------------------
// IE Settings
// When you are using a seperate IE stylesheet,
// you can use these settings to control the output of at-breakpoint.
// By default, at-breakpoint will output media-queries as well as
// any defined ie-fallback classes.
$breakpoint-media-output : true !default;
$breakpoint-ie-output : true !default;
// Danger Zone! Only set as 'true' in IE-specific style sheets.
$breakpoint-raw-output : false !default;

View file

@ -0,0 +1,9 @@
// Float API
// =========
@import "shared";
@import "float/container";
@import "float/span";
@import "float/end";
@import "float/isolate";

View file

@ -0,0 +1,15 @@
// Shared API
// ==========
@import "support";
@import "shared/inspect";
@import "shared/output";
@import "shared/direction";
@import "shared/background";
@import "shared/container";
@import "shared/margins";
@import "shared/padding";

View file

@ -0,0 +1,9 @@
// Susy Browser Support
// ====================
@import "support/support";
@import "support/prefix";
@import "support/background";
@import "support/box-sizing";
@import "support/rem";
@import "support/clearfix";

View file

@ -0,0 +1,16 @@
// Float Container API
// ===================
// Float Container
// ---------------
// - [$width] : <length>
// - [$justify] : left | center | right
// - [$math] : fluid | static
@mixin float-container(
$width,
$justify: auto auto,
$property: max-width
) {
@include susy-clearfix;
@include container-output($width, $justify, $property);
}

View file

@ -0,0 +1,40 @@
// Float Ends API
// ==============
// Susy End Defaults
// -----------------
// - PRIVATE
@include susy-defaults((
last-flow: to,
));
// Float Last
// ----------
// - [$flow] : ltr | rtl
@mixin float-last(
$flow: map-get($susy-defaults, flow),
$last-flow: map-get($susy-defaults, last-flow),
$margin: 0
) {
$to: to($flow);
$output: (
float: if($last-flow == to, $to, null),
margin-#{$to}: $margin,
);
@include output($output);
}
// Float First
// -----------
// - [$flow] : ltr | rtl
@mixin float-first(
$flow: map-get($susy-defaults, flow)
) {
$output: (
margin-#{from($flow)}: 0,
);
@include output($output);
}

View file

@ -0,0 +1,22 @@
// Float Isolation API
// ===================
// Isolate Output
// --------------
// - $push : <length>
// - [$flow] : ltr | rtl
@mixin isolate-output(
$push,
$flow: map-get($susy-defaults, flow)
) {
$to: to($flow);
$from: from($flow);
$output: (
float: $from,
margin-#{$from}: $push,
margin-#{$to}: -100%,
);
@include output($output);
}

View file

@ -0,0 +1,35 @@
// Float Span API
// ==============
// Float Span Output
// -----------------
// - $width : <length>
// - [$float] : from | to
// - [$margin-before] : <length>
// - [$margin-after] : <length>
// - [$padding-before] : <length>
// - [$padding-after] : <length>
// - [$flow] : ltr | rtl
@mixin float-span-output(
$width,
$float : from,
$margin-before : null,
$margin-after : null,
$padding-before : null,
$padding-after : null,
$flow : map-get($susy-defaults, flow)
) {
$to : to($flow);
$from : from($flow);
$output: (
width: $width,
float: if($float == to, $to, null) or if($float == from, $from, null),
margin-#{$from}: $margin-before,
margin-#{$to}: $margin-after,
padding-#{$from}: $padding-before,
padding-#{$to}: $padding-after,
);
@include output($output);
}

View file

@ -0,0 +1,26 @@
// Grid Background API
// ===================
// - Sub-pixel rounding can lead to several pixels variation between browsers.
// Grid Background Output
// ----------------------
// - $image: background-image
// - $size: background-size
// - $clip: background-clip
// - [$flow]: ltr | rtl
@mixin background-grid-output (
$image,
$size: null,
$clip: null,
$flow: map-get($susy-defaults, flow)
) {
$output: (
background-image: $image,
background-size: $size,
background-origin: $clip,
background-clip: $clip,
background-position: from($flow) top,
);
@include output($output);
}

View file

@ -0,0 +1,21 @@
// Shared Container API
// ====================
// Container Output
// ----------------
// - [$width] : <length>
// - [$justify] : left | center | right
// - [$math] : fluid | static
@mixin container-output(
$width,
$justify: auto auto,
$property: max-width
) {
$output: (
#{$property}: $width or 100%,
margin-left: nth($justify, 1),
margin-right: nth($justify, 2),
);
@include output($output);
}

View file

@ -0,0 +1,42 @@
// Direction Helpers
// =================
// Susy Flow Defaults
// ------------------
// - PRIVATE
@include susy-defaults((
flow: ltr,
));
// Get Direction
// -------------
// Return the 'from' or 'to' direction of a ltr or rtl flow.
// - [$flow] : ltr | rtl
// - [$key] : from | to
@function get-direction(
$flow: map-get($susy-defaults, flow),
$key: from
) {
$return: if($flow == rtl, (from: right, to: left), (from: left, to: right));
@return map-get($return, $key);
}
// To
// --
// Return the 'to' direction of a flow
// - [$flow] : ltr | rtl
@function to(
$flow: map-get($susy-defaults, flow)
) {
@return get-direction($flow, to);
}
// From
// ----
// Return the 'from' direction of a flow
// - [$flow] : ltr | rtl
@function from(
$flow: map-get($susy-defaults, flow)
) {
@return get-direction($flow, from);
}

View file

@ -0,0 +1,25 @@
// Debugging
// =========
// Susy Inspect
// ------------
// Output arguments passed to a inspect.
// - $mixin : <susy mixin>
// - $inspec : <mixin arguments>
@mixin susy-inspect(
$mixin,
$inspect
) {
$show: false;
@each $item in $inspect {
@if index($item, inspect) {
$show: true;
}
}
@if $show or susy-get(debug inspect) {
-susy-#{$mixin}: inspect($inspect);
}
}

View file

@ -0,0 +1,23 @@
// Margins API
// ===========
// Margin Output
// -------------
// - $before : <length>
// - $after : <length>
// - [$flow] : ltr | rtl
@mixin margin-output(
$before,
$after,
$flow: map-get($susy-defaults, flow)
) {
$to: to($flow);
$from: from($flow);
$output: (
margin-#{$from}: $before,
margin-#{$to}: $after,
);
@include output($output);
}

View file

@ -0,0 +1,14 @@
// Output
// ======
// Output
// ------
// Output CSS with proper browser support.
// - $styles : <map of css property-value pairs>
@mixin output(
$styles
) {
@each $prop, $val in $styles {
@include susy-support($prop, $val);
}
}

View file

@ -0,0 +1,23 @@
// Padding API
// ===========
// Padding Output
// --------------
// - $before : <length>
// - $after : <length>
// - [$flow] : ltr | rtl
@mixin padding-output(
$before,
$after,
$flow: map-get($susy-defaults, flow)
) {
$to: to($flow);
$from: from($flow);
$output: (
padding-#{$from}: $before,
padding-#{$to}: $after,
);
@include output($output);
}

View file

@ -0,0 +1,58 @@
// Background Properties
// =====================
// Susy Background Image
// ---------------------
// Check for an existing support mixin, or provide a simple fallback.
// - $image: <background-image>
@mixin susy-background-image(
$image
) {
@if susy-support(background-image, (mixin: background-image), $warn: false) {
@include background-image($image...);
} @else {
background-image: $image;
}
}
// Susy Background Size
// ---------------------
// Check for an existing support mixin, or provide a simple fallback.
// - $image: <background-size>
@mixin susy-background-size(
$size
) {
@if susy-support(background-options, (mixin: background-size)) {
@include background-size($size);
} @else {
background-size: $size;
}
}
// Susy Background Origin
// ----------------------
// Check for an existing support mixin, or provide a simple fallback.
// - $image: <background-origin>
@mixin susy-background-origin(
$origin
) {
@if susy-support(background-options, (mixin: background-origin)) {
@include background-origin($origin);
} @else {
background-origin: $origin;
}
}
// Susy Background Clip
// --------------------
// Check for an existing support mixin, or provide a simple fallback.
// - $image: <background-clip>
@mixin susy-background-clip(
$clip
) {
@if susy-support(background-options, (mixin: background-clip)) {
@include background-clip($clip);
} @else {
background-clip: $clip;
}
}

View file

@ -0,0 +1,19 @@
// Box Sizing
// ==========
// Box Sizing
// ----------
// Check for an existing support mixin, or provide a simple fallback.
// - $model: <box-sizing>
@mixin susy-box-sizing(
$model: content-box
) {
@if $model {
@if susy-support(box-sizing, (mixin: box-sizing), $warn: false) {
@include box-sizing($model);
} @else {
$prefix: (moz, webkit, official);
@include susy-prefix(box-sizing, $model, $prefix);
}
}
}

View file

@ -0,0 +1,18 @@
// Susy Fallback Clearfix
// ======================
// Clearfix
// --------
// Check for an existing support mixin, or provide a simple fallback.
@mixin susy-clearfix {
@if susy-support(clearfix, (mixin: clearfix)) {
@include clearfix;
} @else {
&:after {
content: " ";
display: block;
clear: both;
}
}
}

View file

@ -0,0 +1,19 @@
// Susy Prefix
// ===========
// Prefix
// ------
// Output simple prefixed properties.
// - $prop : <css property>
// - $val : <css value>
// - [$prefix] : <browser prefix list>
@mixin susy-prefix(
$prop,
$val,
$prefix: official
) {
@each $fix in $prefix {
$fix: if($fix == official or not($fix), $prop, '-#{$fix}-#{$prop}');
@include susy-rem($fix, $val);
}
}

View file

@ -0,0 +1,22 @@
// rem Support
// ===========
// rem
// ---
// Check for an existing support mixin, or output directly.
// - $prop : <css property>
// - $val : <css value>
@mixin susy-rem(
$prop,
$val
) {
$_reqs: (
variable: rhythm-unit rem-with-px-fallback,
mixin: rem,
);
@if susy-support(rem, $_reqs, $warn: false) and $rhythm-unit == rem {
@include rem($prop, $val);
} @else {
#{$prop}: $val;
}
}

View file

@ -0,0 +1,85 @@
// Browser Support
// ===============
// Susy Support Defaults
// ---------------------
@include susy-defaults((
use-custom: (
clearfix: false,
background-image: true,
background-options: false,
breakpoint: true,
box-sizing: true,
rem: true,
),
));
// Susy Support [mixin]
// --------------------
// Send property-value pairs to the proper support modules.
// - $prop : <css property>
// - $val : <css value>
@mixin susy-support(
$prop,
$val
) {
// Background Support
@if $prop == background-image {
@include susy-background-image($val);
} @else if $prop == background-size {
@include susy-background-size($val);
} @else if $prop == background-origin {
@include susy-background-origin($val);
} @else if $prop == background-clip {
@include susy-background-clip($val);
}
// Box-Sizing Support
@else if $prop == box-sizing {
@include susy-box-sizing($val);
}
// Rem Support
@else {
@include susy-rem($prop, $val);
}
}
// Susy Support [function]
// -----------------------
// Check for support of a feature.
// - $feature : <string>
// - e.g "rem" or "box-sizing"
// - $requirements : <map>
// - e.g (variable: rem-with-px-fallback, mixin: rem)
// - $warn : <bool>
@function susy-support(
$feature,
$requirements: (),
$warn: true
) {
$_support: susy-get(use-custom $feature);
@if $_support {
$_fail: false;
@each $_type, $_req in $requirements {
@each $_i in $_req {
$_pass: call(unquote("#{$_type}-exists"), $_i);
@if not($_pass) {
$_fail: true;
@if $warn {
@warn "You requested custom support of #{$feature}, but the #{$_i} #{$_type} is not available.";
}
}
}
}
$_support: if($_fail, false, $_support);
}
@return $_support;
}

View file

@ -0,0 +1,103 @@
// Column math
// ===========
// Is Symmetrical
// --------------
// Returns true if a grid is symmetrical.
// - [$columns] : <number> | <list>
@function is-symmetrical(
$columns: susy-get(columns)
) {
$columns: valid-columns($columns);
@return if(type-of($columns) == number, $columns, null);
}
// Susy Count
// ----------
// Find the number of columns in a given layout
// - [$columns] : <number> | <list>
@function susy-count(
$columns: susy-get(columns)
) {
$columns: valid-columns($columns);
@return is-symmetrical($columns) or length($columns);
}
// Susy Sum
// --------
// Find the total sum of column-units in a layout
// - [$columns] : <number> | <list>
// - [$gutters] : <ratio>
// - [$spread] : false/narrow | wide | wider
@function susy-sum(
$columns : susy-get(columns),
$gutters : susy-get(gutters),
$spread : false
) {
$columns: valid-columns($columns);
$gutters: valid-gutters($gutters);
$spread: if($spread == wide, 0, if($spread == wider, 1, -1));
$gutter-sum: (susy-count($columns) + $spread) * $gutters;
$column-sum: is-symmetrical($columns);
@if not($column-sum) {
@each $column in $columns {
$column-sum: ($column-sum or 0) + $column;
}
}
@return $column-sum + $gutter-sum;
}
// Susy Slice
// ----------
// Return a subset of columns at a given location.
// - $span : <number>
// - $location : <number>
// - [$columns] : <number> | <list>
@function susy-slice(
$span,
$location,
$columns: susy-get(columns)
) {
$columns: valid-columns($columns);
$sub-columns: $span;
@if not(is-symmetrical($columns)) {
$location: $location or 1;
$sub-columns: ();
@for $i from $location to ($location + $span) {
$sub-columns: append($sub-columns, nth($columns, $i));
}
}
@return $sub-columns;
}
// Susy
// ----
// Find the sum of a column-span.
// - $span : <number>
// - $location : <number>
// - [$columns] : <number> | <list>
// - [$gutters] : <ratio>
// - [$spread] : false/narrow | wide | wider
@function susy(
$span,
$location : false,
$columns : susy-get(columns),
$gutters : susy-get(gutters),
$spread : false
) {
$columns: valid-columns($columns);
$gutters: valid-gutters($gutters);
$span: susy-slice($span, $location, $columns);
@return susy-sum($span, $gutters, $spread);
}

View file

@ -0,0 +1,73 @@
// Settings
// ========
// Version
// -------
$su-version: 1.1;
// Default Settings
// ----------------
// PRIVATE: The basic settings
$susy-defaults: (
columns: 4,
gutters: .25,
);
// User Settings
// -------------
// - Define the $susy variable with a map of your own settings.
// - Set EITHER $column-width OR $container
// - Use $column-width for static layouts
$susy: () !default;
// Susy Defaults
// -------------
// PRIVATE: Add defaults to Susy
@mixin susy-defaults(
$defaults
) {
$susy-defaults: map-merge($susy-defaults, $defaults) !global;
}
// Susy Set
// --------
// Change one setting
// - $key : setting name
// - $value : setting value
@mixin susy-set(
$key-value...
) {
$susy: _susy-deep-set($susy, $key-value...) !global;
}
// Susy Get
// --------
// Return one setting from a grid
// - $key : <keyword>
// - $layout : <settings>
@function susy-get(
$key,
$layout: map-merge($susy-defaults, $susy)
) {
$layout: parse-grid($layout);
$_options: $layout $susy $susy-defaults;
$_break: false;
$_return: null;
@each $opt in $_options {
@if type-of($opt) == map and not($_break) {
$_keyset: _susy-deep-has-key($opt, $key...);
@if $_keyset {
$_return: _susy-deep-get($opt, $key...);
$_break: true;
}
}
}
@return $_return;
}

View file

@ -0,0 +1,111 @@
// Map Functions
// =============
// Truncate List
// -------------
// - Return a list, truncated to a given length
@function _susy-truncate-list(
$list,
$length
) {
$_return: ();
@for $i from 1 through length($list) {
$_return: if($i <= $length, append($_return, nth($list, $i)), $_return);
}
@return $_return;
}
// Deep Get
// --------
// - Return a value deep in nested maps
@function _susy-deep-get(
$map,
$keys...
) {
$_return: $map;
@each $key in $keys {
@if type-of($_return) == map {
$_return: map-get($_return, $key);
}
}
@return $_return;
}
// Deep Set
// --------
// - Set a value deep in nested maps
@function _susy-deep-set(
$map,
$keys-value...
) {
$_value: nth($keys-value, -1);
$_keys: _susy-truncate-list($keys-value, length($keys-value) - 1);
$_length: length($_keys);
$_return: ();
@for $i from 1 through $_length {
$_n: 0 - $i;
$_level: _susy-truncate-list($_keys, $_length + $_n);
$_level: _susy-deep-get($map, $_level...);
$_merge: nth($_keys, $_n);
$_merge: ($_merge: $_value);
$_return: if($_level, map-merge($_level, $_merge), $_merge);
$_value: $_return;
}
@return $_return;
}
// Deep Merge
// ----------
// Return 2 objects of any depth, merged
@function _susy-deep-merge(
$map1,
$map2
) {
@if type-of($map1) != map or type-of($map2) != map {
$map1: $map2;
} @else {
@each $key, $value in $map2 {
$_new: ($key: _susy_deep-merge(map-get($map1, $key), $value));
$map1: map-merge($map1, $_new);
}
}
@return $map1;
}
// Deep Has-Key
// ------------
// - Return true if a deep key exists
@function _susy-deep-has-key(
$map,
$keys...
) {
$_return: null;
$_stop: false;
@each $key in $keys {
@if not($_stop) {
$_return: map-has-key($map, $key);
}
@if $_return {
$map: map-get($map, $key);
} @else {
$_stop: true;
}
}
@return $_return;
}

View file

@ -0,0 +1,57 @@
// Math Validation
// ===============
// Valid Columns
// -------------
// Check that a column setting is valid.
@function valid-columns(
$columns,
$silent: false
) {
$type: type-of($columns);
$return: null;
@if $type == number and unitless($columns) {
$return: $columns;
} @else if $type == list {
$fail: null;
@each $col in $columns {
@if type-of($col) == number {
$fail: $fail or if(unitless($col), null, true);
} @else {
$fail: true;
}
}
$return: if($fail, $return, $columns);
}
@if $return != $columns and not($silent) {
$return: null;
$warn: '$columns must be a unitless number or list of unitless numbers.';
@warn $warn + ' Current value [#{$type}]: #{$columns}';
}
@return $return;
}
// Valid Gutters
// -------------
// Check that a gutter setting is valid.
@function valid-gutters(
$gutters,
$silent: false
) {
$type: type-of($gutters);
$return: null;
@if $type == number and unitless($gutters) {
$return: $gutters;
} @else if not($silent) {
$warn: '$gutters must be a unitless number.';
@warn $warn + ' Current value [#{$type}]: #{$gutters}';
}
@return $return;
}

View file

@ -35,7 +35,7 @@ layout: compress
{% endif %}
<div id="main" role="main">
<div class="sidebar sticky">
<div class="sidebar">
{% if page.author_profile %}{% include author-profile.html %}{% endif %}
{% if page.sidebar %}
{% for s in page.sidebar %}

File diff suppressed because one or more lines are too long