Upgrade to Susy 3 (#42)
Most of Susy's mixins have been deprecated, `@include container()`, `@include full()`, `@include span()`, `@include prefix()`, `@include suffix()`, `@include gallery()`, etc replace with new functions. Fixes #21
This commit is contained in:
parent
eeebb7e4ff
commit
628629d268
|
@ -1,16 +0,0 @@
|
|||
---
|
||||
engines:
|
||||
duplication:
|
||||
enabled: false
|
||||
eslint:
|
||||
enabled: false
|
||||
fixme:
|
||||
enabled: false
|
||||
scss-lint:
|
||||
enabled: true
|
||||
ratings:
|
||||
paths:
|
||||
- "**.js"
|
||||
- "**.rb"
|
||||
- "_sass/**/*.scss"
|
||||
exclude_paths: []
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
[![Gem](https://img.shields.io/gem/v/jekyll-theme-basically-basic.svg?style=flat-square)](https://rubygems.org/gems/jekyll-theme-basically-basic)
|
||||
[![license](https://img.shields.io/github/license/mmistakes/jekyll-theme-basically-basic.svg?style=flat-square)](LICENSE.md)
|
||||
[![Code Climate](https://img.shields.io/codeclimate/github/mmistakes/jekyll-theme-basically-basic.svg?style=flat-square)](https://codeclimate.com/github/mmistakes/jekyll-theme-basically-basic)
|
||||
|
||||
Basically Basic is a [Jekyll theme](https://jekyllrb.com/docs/themes/) meant as
|
||||
a substitute for the default --- [Minima](https://github.com/jekyll/minima).
|
||||
|
|
|
@ -5,14 +5,12 @@
|
|||
* https://github.com/mmistakes/jekyll-theme-basically-basic/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
/* Mixins and functions */
|
||||
@import "basically-basic/vendor/susy";
|
||||
@import "basically-basic/vendor/breakpoint";
|
||||
@include breakpoint-set("to ems", true);
|
||||
@import "basically-basic/mixins";
|
||||
|
||||
/* Variables */
|
||||
@import "basically-basic/functions";
|
||||
@import "basically-basic/variables";
|
||||
@import "basically-basic/mixins";
|
||||
@import "basically-basic/vendor/breakpoint/breakpoint";
|
||||
@include breakpoint-set("to ems", true);
|
||||
@import "basically-basic/vendor/susy/susy";
|
||||
|
||||
/* Core CSS */
|
||||
@import "basically-basic/reset";
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
}
|
||||
|
||||
.byline-item {
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
|
@ -53,7 +52,6 @@
|
|||
========================================================================== */
|
||||
|
||||
.entries {
|
||||
|
||||
.entry-title {
|
||||
word-wrap: break-word; /* break long words that could overflow */
|
||||
|
||||
|
@ -64,7 +62,7 @@
|
|||
|
||||
.entry-excerpt {
|
||||
@include breakpoint($medium) {
|
||||
@include span(11 of 16);
|
||||
width: span(11 of 16);
|
||||
}
|
||||
|
||||
/* normalize font sizes */
|
||||
|
@ -80,7 +78,7 @@
|
|||
|
||||
.entry-content {
|
||||
@include breakpoint($medium) {
|
||||
@include span(11 of 16);
|
||||
width: span(11 of 16);
|
||||
}
|
||||
|
||||
/* remove space after last child element */
|
||||
|
@ -91,8 +89,9 @@
|
|||
|
||||
.entry-meta {
|
||||
@include breakpoint($medium) {
|
||||
@include span(5 of 16 last);
|
||||
@include prefix(1 of 16);
|
||||
float: right;
|
||||
width: span(5 of 16 last);
|
||||
padding-left: gutter(1 of 16);
|
||||
}
|
||||
|
||||
ul {
|
||||
|
@ -114,7 +113,6 @@
|
|||
}
|
||||
|
||||
> .summary {
|
||||
|
||||
> p:first-child {
|
||||
font-size: 1.125em;
|
||||
line-height: 1.625;
|
||||
|
@ -123,7 +121,6 @@
|
|||
}
|
||||
|
||||
.entry-content {
|
||||
|
||||
> p:first-child {
|
||||
font-size: 1.125em;
|
||||
line-height: 1.625;
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
@import "functions/color";
|
||||
@import "functions/fluid-type";
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
.intro,
|
||||
main {
|
||||
|
||||
> .inner {
|
||||
padding: 0 0.5rem;
|
||||
|
||||
|
@ -50,9 +49,10 @@ main {
|
|||
}
|
||||
|
||||
main {
|
||||
|
||||
section {
|
||||
@include container;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,9 +66,7 @@ main {
|
|||
|
||||
.layout--post,
|
||||
.layout--page {
|
||||
|
||||
.entry-content {
|
||||
|
||||
@include breakpoint($large) {
|
||||
width: span(14 of 16);
|
||||
}
|
||||
|
@ -76,7 +74,6 @@ main {
|
|||
}
|
||||
|
||||
.layout--about {
|
||||
|
||||
.entry-wrap {
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
|
@ -90,7 +87,6 @@ main {
|
|||
}
|
||||
|
||||
.entry-content {
|
||||
|
||||
@include breakpoint($medium) {
|
||||
-ms-flex: 1;
|
||||
flex: 1;
|
||||
|
@ -118,14 +114,11 @@ main {
|
|||
}
|
||||
|
||||
.layout--cv {
|
||||
|
||||
.entries {
|
||||
|
||||
.entry-header {
|
||||
|
||||
@include breakpoint($medium) {
|
||||
@include span(5 of 16);
|
||||
@include suffix(1 of 16);
|
||||
width: span(5 of 16);
|
||||
padding-right: gutter(1 of 16);
|
||||
|
||||
/* remove space after last child element */
|
||||
> *:last-child {
|
||||
|
@ -136,13 +129,13 @@ main {
|
|||
|
||||
.entry-content {
|
||||
@include breakpoint($medium) {
|
||||
@include span(11 of 16 last);
|
||||
float: right;
|
||||
width: span(11 of 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.entry {
|
||||
|
||||
a {
|
||||
color: $accent-color;
|
||||
}
|
||||
|
@ -179,7 +172,6 @@ main {
|
|||
}
|
||||
|
||||
.taxonomy {
|
||||
|
||||
+ .taxonomy {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
@import 'mixins/color';
|
||||
@import 'mixins/clearfix';
|
||||
@import 'mixins/fluid-type';
|
||||
@import 'mixins/float';
|
||||
@import 'mixins/image';
|
||||
@import 'mixins/lists';
|
||||
@import 'mixins/text-truncate';
|
||||
@import "mixins/clearfix";
|
||||
@import "mixins/float";
|
||||
@import "mixins/image";
|
||||
@import "mixins/lists";
|
||||
@import "mixins/text-truncate";
|
||||
|
|
|
@ -19,11 +19,15 @@ $max-font-size: 18px !default;
|
|||
$modular-scale-1: 1.067 !default; /* small */
|
||||
$modular-scale-2: 1.296 !default; /* large */
|
||||
/* Heading 1 */
|
||||
$h1-min: $modular-scale-1 * $modular-scale-1 * $modular-scale-1 * $modular-scale-1 * $base-font-size !default;
|
||||
$h1-max: $modular-scale-2 * $modular-scale-2 * $modular-scale-2 * $modular-scale-2 * $base-font-size !default;
|
||||
$h1-min: $modular-scale-1 * $modular-scale-1 * $modular-scale-1 *
|
||||
$modular-scale-1 * $base-font-size !default;
|
||||
$h1-max: $modular-scale-2 * $modular-scale-2 * $modular-scale-2 *
|
||||
$modular-scale-2 * $base-font-size !default;
|
||||
/* Heading 2 */
|
||||
$h2-min: $modular-scale-1 * $modular-scale-1 * $modular-scale-1 * $base-font-size !default;
|
||||
$h2-max: $modular-scale-2 * $modular-scale-2 * $modular-scale-2 * $base-font-size !default;
|
||||
$h2-min: $modular-scale-1 * $modular-scale-1 * $modular-scale-1 *
|
||||
$base-font-size !default;
|
||||
$h2-max: $modular-scale-2 * $modular-scale-2 * $modular-scale-2 *
|
||||
$base-font-size !default;
|
||||
/* Heading 3 */
|
||||
$h3-min: $modular-scale-1 * $modular-scale-1 * $base-font-size !default;
|
||||
$h3-max: $modular-scale-2 * $modular-scale-2 * $base-font-size !default;
|
||||
|
@ -41,7 +45,8 @@ $h6-max: ($base-font-size / $modular-scale-2) !default;
|
|||
$base-font-family: "Fira Sans", sans-serif !default;
|
||||
/* Other font families */
|
||||
$headline-font-family: $base-font-family !default;
|
||||
$monospace-font-family: Menlo, Consolas, Monaco, "Courier New", Courier, monospace !default;
|
||||
$monospace-font-family: Menlo, Consolas, Monaco, "Courier New", Courier,
|
||||
monospace !default;
|
||||
|
||||
/* Colors */
|
||||
$base-color: #393e46 !default;
|
||||
|
@ -79,6 +84,3 @@ $navicon-content-bg: $text-color !default;
|
|||
/* Site image */
|
||||
$site-image-width: 50px !default;
|
||||
$site-image-height: 50px !default;
|
||||
|
||||
/* Susy grid settings */
|
||||
$susy: (columns: 16, gutters: 0, math: fluid, output: float) !default;
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
// Su
|
||||
// ==
|
||||
|
||||
@import 'susy/su';
|
|
@ -1,4 +0,0 @@
|
|||
// Susy
|
||||
// ====
|
||||
|
||||
@import 'susy/language/susy';
|
|
@ -1,4 +0,0 @@
|
|||
// Susy
|
||||
// ====
|
||||
|
||||
@import 'susy/language/susyone';
|
|
@ -23,15 +23,15 @@ $breakpoint: () !default;
|
|||
//////////////////////////////
|
||||
// Imports
|
||||
//////////////////////////////
|
||||
@import "breakpoint/settings";
|
||||
@import 'breakpoint/context';
|
||||
@import 'breakpoint/helpers';
|
||||
@import 'breakpoint/parsers';
|
||||
@import 'breakpoint/no-query';
|
||||
@import "settings";
|
||||
@import "context";
|
||||
@import "helpers";
|
||||
@import "parsers";
|
||||
@import "no-query";
|
||||
|
||||
@import 'breakpoint/respond-to';
|
||||
@import "respond-to";
|
||||
|
||||
@import "breakpoint/legacy-settings";
|
||||
@import "legacy-settings";
|
||||
|
||||
//////////////////////////////
|
||||
// Breakpoint Mixin
|
|
@ -1,7 +1,4 @@
|
|||
// Su
|
||||
// ==
|
||||
|
||||
@import "su/utilities";
|
||||
@import "su/settings";
|
||||
@import "su/validation";
|
||||
@import "su/grid";
|
||||
@import 'susy/su';
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// Susy (Prefixed)
|
||||
// ===============
|
||||
|
||||
$susy-version: 3;
|
||||
|
||||
@import 'susy/utilities';
|
||||
@import 'susy/su-validate';
|
||||
@import 'susy/su-math';
|
||||
@import 'susy/settings';
|
||||
@import 'susy/normalize';
|
||||
@import 'susy/parse';
|
||||
@import 'susy/syntax-helpers';
|
||||
@import 'susy/api';
|
|
@ -0,0 +1,5 @@
|
|||
// Susy (Un-Prefixed)
|
||||
// ==================
|
||||
|
||||
@import 'susy-prefix';
|
||||
@import 'susy/unprefix';
|
|
@ -1,24 +0,0 @@
|
|||
// 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";
|
|
@ -1,13 +0,0 @@
|
|||
// ---------------------------------------------------------------------------
|
||||
// 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";
|
|
@ -1,385 +0,0 @@
|
|||
// 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);
|
||||
}
|
|
@ -1,200 +0,0 @@
|
|||
// 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;
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
// 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);
|
||||
}
|
||||
}
|
|
@ -1,185 +0,0 @@
|
|||
// 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;
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
// 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;
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// 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;
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
// 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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
// 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));
|
||||
}
|
|
@ -1,154 +0,0 @@
|
|||
// 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;
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
// 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;
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
// 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);
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
// 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);
|
||||
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
// 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
|
||||
}
|
|
@ -1,216 +0,0 @@
|
|||
// 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;
|
||||
}
|
|
@ -1,163 +0,0 @@
|
|||
// 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;
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
// 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;
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
// ---------------------------------------------------------------------------
|
||||
// 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);
|
||||
}
|
|
@ -1,377 +0,0 @@
|
|||
// ---------------------------------------------------------------------------
|
||||
// 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);
|
||||
}
|
||||
}
|
|
@ -1,312 +0,0 @@
|
|||
// ---------------------------------------------------------------------------
|
||||
// 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;
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
// ---------------------------------------------------------------------------
|
||||
// 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; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
// ---------------------------------------------------------------------------
|
||||
// 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)
|
||||
}
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
// ---------------------------------------------------------------------------
|
||||
// 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).";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
// ---------------------------------------------------------------------------
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
// ---------------------------------------------------------------------------
|
||||
// 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;
|
|
@ -1,9 +0,0 @@
|
|||
// Float API
|
||||
// =========
|
||||
|
||||
@import "shared";
|
||||
|
||||
@import "float/container";
|
||||
@import "float/span";
|
||||
@import "float/end";
|
||||
@import "float/isolate";
|
|
@ -1,15 +0,0 @@
|
|||
// 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";
|
||||
|
||||
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
// Susy Browser Support
|
||||
// ====================
|
||||
|
||||
@import "support/support";
|
||||
@import "support/prefix";
|
||||
@import "support/background";
|
||||
@import "support/box-sizing";
|
||||
@import "support/rem";
|
||||
@import "support/clearfix";
|
|
@ -1,16 +0,0 @@
|
|||
// 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);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
// 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);
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
// 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);
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
// 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);
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
// 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);
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
// 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);
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
// 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);
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
// 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);
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
// 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);
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// 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);
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
// 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);
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
// 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;
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
// 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);
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
// 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;
|
||||
}
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
// 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;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
// SVG Grid Background
|
||||
// ===================
|
||||
|
||||
@import 'svg-grid/prefix';
|
||||
@import 'svg-grid/svg-unprefix';
|
|
@ -0,0 +1,7 @@
|
|||
// Prefixed SVG Plugin
|
||||
// ===================
|
||||
|
||||
@import 'svg-settings';
|
||||
@import 'svg-utilities';
|
||||
@import 'svg-grid-math';
|
||||
@import 'svg-api';
|
|
@ -0,0 +1,114 @@
|
|||
/// Plugin: SVG Grid Image
|
||||
/// ======================
|
||||
/// @group plugin_svg-grid
|
||||
/// @see susy-svg-grid
|
||||
|
||||
|
||||
|
||||
/// ## Overview
|
||||
/// If you want to generate svg-backgrounds
|
||||
/// for help visualizing and debugging your grids,
|
||||
/// import the SVG Grid Plugin.
|
||||
///
|
||||
/// The plugin adds `svg-grid-colors` setting
|
||||
/// to your global defaults,
|
||||
/// which you can override in `$susy`.
|
||||
/// It also provides you with a new function,
|
||||
/// `susy-svg-grid()`,
|
||||
/// which will return inline svg for use in
|
||||
/// backgrounds or generated content.
|
||||
///
|
||||
/// This function come with an unprefixed alias by default,
|
||||
/// using the `svg-grid` import.
|
||||
/// If you only only want prefixed versions of the API,
|
||||
/// import the `svg-grid/prefix` partial instead.
|
||||
///
|
||||
/// @group plugin_svg-grid
|
||||
///
|
||||
/// @example scss - importing the plugin
|
||||
/// // The full path to import Susy will depend on your setup…
|
||||
///
|
||||
/// // unprefixed
|
||||
/// @import 'plugins/svg-grid';
|
||||
///
|
||||
/// // prefixed
|
||||
/// @import 'plugins/svg-grid/prefix';
|
||||
///
|
||||
/// @example scss - generating background grids
|
||||
/// .grid {
|
||||
/// background: susy-svg-grid() no-repeat scroll;
|
||||
/// }
|
||||
|
||||
|
||||
|
||||
// SVG Grid
|
||||
// --------
|
||||
/// Return inline svg-data in to display the grid.
|
||||
///
|
||||
/// @group plugin_svg-grid
|
||||
///
|
||||
/// @param {Map | List} $grid [$susy] -
|
||||
/// Map or shorthand defining the current grid
|
||||
/// @param {Color | List | null} $colors [null] -
|
||||
/// Column color, or list of colors for column-gradient,
|
||||
/// used to override the global `svg-grid-colors` setting
|
||||
/// @param {Length | null} $offset [null] -
|
||||
/// Manually override the default grid-image offset,
|
||||
/// to account for grid edges
|
||||
///
|
||||
/// @return {String} -
|
||||
/// CSS inline-data SVG string, in `url(<svg>)` format,
|
||||
/// for use in image or content properties
|
||||
/// @example scss
|
||||
/// .grid {
|
||||
/// background: susy-svg-grid() no-repeat scroll;
|
||||
/// }
|
||||
@function susy-svg-grid(
|
||||
$grid: $susy,
|
||||
$colors: null,
|
||||
$offset: null
|
||||
) {
|
||||
// Grid parsing & normalizing
|
||||
$grid: susy-compile($grid, $context-only: true);
|
||||
|
||||
// Color and gradient handling
|
||||
$gradient: '';
|
||||
|
||||
@if (not $colors) {
|
||||
$colors: susy-get('svg-grid-colors');
|
||||
}
|
||||
|
||||
@if length($colors) > 1 {
|
||||
$gradient: _susy-svg-gradient($colors);
|
||||
$colors: 'url(%23susy-svg-gradient)';
|
||||
} @else {
|
||||
$colors: _susy-svg-color($colors);
|
||||
}
|
||||
|
||||
// Get a default image-width
|
||||
$span: (
|
||||
'span': map-get($grid, 'columns'),
|
||||
'spread': map-get($grid, 'container-spread'),
|
||||
);
|
||||
$span: map-merge($grid, $span);
|
||||
$image-width: su-call('su-span', $span);
|
||||
$image-width: if((type-of($image-width) == 'number'), $image-width, 100%);
|
||||
|
||||
// SVG construction
|
||||
$columns: map-get($grid, 'columns');
|
||||
$offset: $offset or _susy-svg-offset($grid);
|
||||
|
||||
$attrs: 'fill="#{$colors}" width="#{$image-width}"';
|
||||
$svg: 'data:image/svg+xml,';
|
||||
$svg: $svg + '%3Csvg xmlns="http://www.w3.org/2000/svg" #{$attrs} %3E';
|
||||
$svg: $svg + $gradient;
|
||||
|
||||
@for $column from 1 through length($columns) {
|
||||
$width: susy-span(1 narrow at $column, $grid);
|
||||
$x: _susy-svg-column-position($column, $grid);
|
||||
|
||||
$svg: $svg + _susy-svg-rect($x, $width, $offset);
|
||||
}
|
||||
|
||||
@return url('#{$svg}%3C/svg%3E');
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
// SVG Grid Math
|
||||
// =============
|
||||
|
||||
|
||||
|
||||
// SVG Column Position
|
||||
// -------------------
|
||||
/// Determine the proper horizontal position
|
||||
/// for a column rectangle
|
||||
///
|
||||
/// @access private
|
||||
///
|
||||
/// @param {Integer} $column -
|
||||
/// 1-indexed column location on the grid
|
||||
/// @param {Map} $grid -
|
||||
/// Normalized settings map representing the current grid
|
||||
///
|
||||
/// @return {Length} -
|
||||
/// Horizontal position of svg column rectangle,
|
||||
/// as distance from the grid edge
|
||||
@function _susy-svg-column-position(
|
||||
$column,
|
||||
$grid
|
||||
) {
|
||||
$x: $column - 1;
|
||||
|
||||
@if ($x > 0) {
|
||||
$x: susy-span(first $x wide, $grid);
|
||||
}
|
||||
|
||||
@return $x;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// SVG Offset
|
||||
// ----------
|
||||
/// Determine if a grid image needs to be offset,
|
||||
/// to account for edge gutters.
|
||||
///
|
||||
/// @access private
|
||||
///
|
||||
/// @param {Map} $grid -
|
||||
/// Normalized settings map representing the current grid
|
||||
///
|
||||
/// @return {Length | null} -
|
||||
/// Expected distance from container edge to first column,
|
||||
/// based on spread values and gutter-widths
|
||||
@function _susy-svg-offset(
|
||||
$grid
|
||||
) {
|
||||
$columns: su-valid-columns(map-get($grid, 'columns'));
|
||||
$gutters: su-valid-gutters(map-get($grid, 'gutters'));
|
||||
$container: su-valid-spread(map-get($grid, 'container-spread')) + 1;
|
||||
|
||||
@if ($container == 0) {
|
||||
@return null;
|
||||
}
|
||||
|
||||
$gutter: su-call('su-gutter', $grid);
|
||||
|
||||
@if (type-of($gutter) == 'string') {
|
||||
@return 'calc(#{$container} * #{$gutter} / 2)';
|
||||
}
|
||||
|
||||
@return $container * $gutter / 2;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// SVG Settings
|
||||
// ============
|
||||
|
||||
|
||||
// Susy SVG Defaults
|
||||
// =================
|
||||
/// This plugin adds the `svg-grid-colors` property
|
||||
/// and default value to `$_susy-defaults` —
|
||||
/// you can override that value in `$susy`
|
||||
/// or any other grid settings map.
|
||||
/// @group plugin_svg-grid
|
||||
$_susy-defaults: map-merge((
|
||||
'svg-grid-colors': hsla(120, 50%, 50%, 0.5) hsla(120, 50%, 75%, 0.5),
|
||||
), $_susy-defaults);
|
|
@ -0,0 +1,18 @@
|
|||
// Unprefix Susy SVG Grid
|
||||
// ======================
|
||||
|
||||
|
||||
|
||||
// SVG Grid
|
||||
// --------
|
||||
/// Un-prefixed alias for `susy-svg-grid`
|
||||
///
|
||||
/// @group plugin_svg-grid
|
||||
/// @alias susy-svg-grid
|
||||
@function svg-grid(
|
||||
$grid: $susy,
|
||||
$colors: susy-get('svg-grid-colors'),
|
||||
$offset: null
|
||||
) {
|
||||
@return susy-svg-grid($grid, $colors, $offset);
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
// SVG Utilities
|
||||
// =============
|
||||
|
||||
|
||||
|
||||
// SVG Validate Units
|
||||
// ------------------
|
||||
/// Make sure a length is supported in svg
|
||||
///
|
||||
/// @access private
|
||||
///
|
||||
/// @param {Length} $length -
|
||||
/// The length to validate
|
||||
/// @param {String} $name [null] -
|
||||
/// Optional name of length origin,
|
||||
/// for error reporting
|
||||
///
|
||||
/// @return {Length} -
|
||||
/// An svg-validated length, or comparable valid length
|
||||
@function _susy-svg-validate-units(
|
||||
$length,
|
||||
$name: null
|
||||
) {
|
||||
$_svg-units: ('em', 'ex', 'px', 'pt', 'pc', 'cm', 'mm', 'in', '%');
|
||||
$string: type-of($length) == 'string';
|
||||
|
||||
@if ($length == 0) or ($string) or index($_svg-units, unit($length)) {
|
||||
@return $length;
|
||||
}
|
||||
|
||||
@return _susy-error(
|
||||
'`#{unit($length)}` #{$name} units are not supported in SVG',
|
||||
'_susy-svg-validate-units');
|
||||
}
|
||||
|
||||
|
||||
|
||||
// SVG Rect
|
||||
// --------
|
||||
/// Build a single svg rectangle
|
||||
///
|
||||
/// @access private
|
||||
///
|
||||
/// @param {Length} $x -
|
||||
/// Horizontal position for the rectangle
|
||||
/// @param {Length} $width -
|
||||
/// Width of the rectangle
|
||||
/// @param {Length} $offset [null] -
|
||||
/// Offset the rectangle, to account for edge gutters
|
||||
///
|
||||
/// @return {String} -
|
||||
/// Escaped string representing one svg rectangle
|
||||
@function _susy-svg-rect(
|
||||
$x,
|
||||
$width,
|
||||
$offset: null
|
||||
) {
|
||||
$x: _susy-svg-validate-units($x);
|
||||
$width: _susy-svg-validate-units($width);
|
||||
$offset: if($offset == 0, null, $offset);
|
||||
|
||||
@if (type-of($offset) == 'number') and (type-of($x) == 'number') {
|
||||
@if comparable($x, $offset) {
|
||||
$x: $x + $offset;
|
||||
} @else {
|
||||
$x: 'calc(#{$x} + #{$offset})';
|
||||
}
|
||||
} @else if $offset and ($x != 0) {
|
||||
$x: 'calc(#{$x} + #{$offset})';
|
||||
} @else if $offset {
|
||||
$x: $offset;
|
||||
}
|
||||
|
||||
@return '%3Crect x="#{$x}" width="#{$width}" height="100%"/%3E';
|
||||
}
|
||||
|
||||
|
||||
|
||||
// SVG Color
|
||||
// ---------
|
||||
/// Stringify colors, and escape hex symbol
|
||||
///
|
||||
/// @access private
|
||||
///
|
||||
/// @param {Color} $color -
|
||||
/// Color to stringify and escape
|
||||
///
|
||||
/// @return {String} -
|
||||
/// Escaped string value of color
|
||||
@function _susy-svg-color(
|
||||
$color
|
||||
) {
|
||||
$color: inspect($color); // convert to string
|
||||
|
||||
@if (str-index($color, '#') == 1) {
|
||||
$color: '%23' + str-slice($color, 2);
|
||||
}
|
||||
|
||||
@return $color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// SVG Gradient
|
||||
// ------------
|
||||
/// Create a multi-color svg gradient
|
||||
///
|
||||
/// @access private
|
||||
///
|
||||
/// @param {List} $colors -
|
||||
/// List of colors to be equally spaced from `0%` to `100%`
|
||||
/// in each column rectangle
|
||||
///
|
||||
/// @return {String} -
|
||||
/// Escaped string representing one svg gradient
|
||||
/// (`id="susy-svg-gradient"`)
|
||||
@function _susy-svg-gradient(
|
||||
$colors
|
||||
) {
|
||||
$gradient: '%3Cdefs%3E%3ClinearGradient spreadMethod="pad"';
|
||||
$gradient: '#{$gradient} id="susy-svg-gradient"';
|
||||
$gradient: '#{$gradient} x1="0%" y1="0%" x2="100%" y2="0%"%3E';
|
||||
|
||||
@for $i from 1 through length($colors) {
|
||||
$color: _susy-svg-color(nth($colors, $i));
|
||||
$offset: percentage(($i - 1) / (length($colors) - 1));
|
||||
$stop: '%3Cstop offset="#{$offset}" style="stop-color:#{$color};" /%3E';
|
||||
|
||||
$gradient: $gradient + $stop;
|
||||
}
|
||||
|
||||
@return $gradient + '%3C/linearGradient%3E%3C/defs%3E';
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
// 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);
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
// 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;
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
// 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;
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
// 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;
|
||||
}
|
|
@ -0,0 +1,318 @@
|
|||
/// Susy3 API Functions
|
||||
/// ===================
|
||||
/// These three functions form the core of Susy's
|
||||
/// layout-building grid API.
|
||||
///
|
||||
/// - Use `span()` and `gutter()` to return any grid-width,
|
||||
/// and apply the results wherever you need them:
|
||||
/// CSS `width`, `margin`, `padding`, `flex-basis`, `transform`, etc.
|
||||
/// - For asymmetrical-fluid grids,
|
||||
/// `slice()` can help manage your nesting context.
|
||||
///
|
||||
/// All three functions come with an unprefixed alias by default,
|
||||
/// using the `susy` import.
|
||||
/// Import the `susy-prefix` partial instead,
|
||||
/// if you only only want prefixed versions of the API.
|
||||
///
|
||||
/// This is a thin syntax-sugar shell around
|
||||
/// the "Su" core-math functions: `su-span`, `su-gutter`, and `su-slice`.
|
||||
/// If you prefer the more constrained syntax of the math engine,
|
||||
/// you are welcome to use those functions instead.
|
||||
///
|
||||
/// @group b-api
|
||||
/// @see susy-span
|
||||
/// @see susy-gutter
|
||||
/// @see susy-slice
|
||||
/// @see su-span
|
||||
/// @see su-gutter
|
||||
/// @see su-slice
|
||||
|
||||
|
||||
|
||||
/// ## Shorthand
|
||||
///
|
||||
/// All functions draw on the same shorthand syntax in two parts,
|
||||
/// seperated by the word `of`.
|
||||
///
|
||||
/// ### Span Syntax: `<width>` [`<location>` `<spread>`]
|
||||
/// The first part describes the
|
||||
/// **span** width, location, and spread in any order.
|
||||
/// Only the width is required:
|
||||
///
|
||||
/// - `span(2)` will return the width of 2 columns.
|
||||
/// - `span(3 wide)` will return 3-columns, with an additional gutter.
|
||||
/// - location is only needed with asymmetrical grids,
|
||||
/// where `span(3 at 2)` will return the width of
|
||||
/// specific columns on the grid.
|
||||
/// Since these are functions, they will not handle placement for you.
|
||||
///
|
||||
/// ### Context Syntax: `[of <columns> <container-spread> <gutters>]`
|
||||
/// The second half of Susy's shorthand
|
||||
/// describes the grid-**context** –
|
||||
/// available columns, container-spread, and optional gutter override –
|
||||
/// in any order.
|
||||
/// All of these settings have globally-defined defaults:
|
||||
///
|
||||
/// - `span(2 of 6)` will set the context to
|
||||
/// a slice of 6 columns from the global grid.
|
||||
/// More details below.
|
||||
/// - `span(2 of 12 wide)` changes the container-spread
|
||||
/// as well as the column-context.
|
||||
/// - `span(2 of 12 set-gutters 0.5em)`
|
||||
/// will override the global gutters setting
|
||||
/// for this one calculation.
|
||||
///
|
||||
/// A single unitless number for `columns`
|
||||
/// will be treated as a slice of the parent grid.
|
||||
/// On a grid with `columns: susy-repeat(12, 120px)`,
|
||||
/// the shorthand `of 4` will use the parent `120px` column-width.
|
||||
/// You can also be more explicit,
|
||||
/// and say `of susy-repeat(4, 100px)`.
|
||||
/// If you are using asymmetrical grids,
|
||||
/// like `columns: (1 1 2 3 5 8)`,
|
||||
/// Susy can't slice it for you without knowing which columns you want.
|
||||
/// The `slice` function accepts exactly the same syntax as `span`,
|
||||
/// but returns a list of columns rather than a width.
|
||||
/// Use it in your context like `of slice(first 3)`.
|
||||
///
|
||||
/// @group b-api
|
||||
|
||||
|
||||
|
||||
// Susy Span
|
||||
// ---------
|
||||
/// This is the primary function in Susy —
|
||||
/// used to return the width of a span across one or more columns,
|
||||
/// and any relevant gutters along the way.
|
||||
/// With the default settings,
|
||||
/// `span(3)` will return the width of 3 columns,
|
||||
/// and the 2 intermediate gutters.
|
||||
/// This can be used to set the `width` property of grid elements,
|
||||
/// or `margin` and `padding`
|
||||
/// to push, pull, and pad your elements.
|
||||
///
|
||||
/// - This is a thin syntax-sugar shell around
|
||||
/// the core-math `su-span()` function.
|
||||
/// - The un-prefixed alias `span()` is available by default.
|
||||
///
|
||||
/// @group b-api
|
||||
/// @see su-span
|
||||
/// @see $susy
|
||||
///
|
||||
/// @param {list} $span -
|
||||
/// Shorthand expression to define the width of the span,
|
||||
/// optionally containing:
|
||||
/// - a count, length, or column-list span.
|
||||
/// - `at $n`, `first`, or `last` location on asymmetrical grids,
|
||||
/// where `at 1 == first`,
|
||||
/// and `last` will calculate the proper location
|
||||
/// based on columns and span.
|
||||
/// - `narrow`, `wide`, or `wider` for optionally spreading
|
||||
/// across adjacent gutters.
|
||||
/// - `of $n <spread>` for available grid columns
|
||||
/// and spread of the container.
|
||||
/// Span counts like `of 6` are valid
|
||||
/// in the context of symmetrical grids,
|
||||
/// where Susy can safely infer a slice of the parent columns.
|
||||
/// - and `set-gutters $n` to override global gutter settings.
|
||||
///
|
||||
/// @param {map} $config [()] -
|
||||
/// Optional map of Susy grid configuration settings.
|
||||
/// See `$susy` documentation for details.
|
||||
///
|
||||
/// @return {length} -
|
||||
/// Calculated length value, using the units given,
|
||||
/// or converting to `%` for fraction-based grids,
|
||||
/// or a full `calc` function when units/fractions
|
||||
/// are not comparable outside the browser.
|
||||
///
|
||||
/// @example scss - span half the grid
|
||||
/// .foo {
|
||||
/// // the result is a bit under 50% to account for gutters
|
||||
/// width: susy-span(6 of 12);
|
||||
/// }
|
||||
///
|
||||
/// @example scss - span a specific segment of asymmetrical grid
|
||||
/// .foo {
|
||||
/// width: susy-span(3 at 3 of (1 2 3 5 8));
|
||||
/// }
|
||||
@function susy-span(
|
||||
$span,
|
||||
$config: ()
|
||||
) {
|
||||
$output: susy-compile($span, $config);
|
||||
|
||||
@if map-get($output, 'span') {
|
||||
@return su-call('su-span', $output);
|
||||
}
|
||||
|
||||
$actual: '[#{type-of($span)}] `#{inspect($span)}`';
|
||||
@return _susy-error(
|
||||
'Unable to determine span value from #{$actual}.',
|
||||
'susy-span');
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Susy Gutter
|
||||
// -----------
|
||||
/// The gutter function returns
|
||||
/// the width of a single gutter on your grid,
|
||||
/// to be applied where you see fit –
|
||||
/// on `margins`, `padding`, `transform`, or element `width`.
|
||||
///
|
||||
/// - This is a thin syntax-sugar shell around
|
||||
/// the core-math `su-gutter()` function.
|
||||
/// - The un-prefixed alias `gutter()` is available by default.
|
||||
///
|
||||
/// @group b-api
|
||||
/// @see su-gutter
|
||||
/// @see $susy
|
||||
///
|
||||
/// @param {list | number} $context [null] -
|
||||
/// Optional context for nested gutters,
|
||||
/// including shorthand for
|
||||
/// `columns`, `gutters`, and `container-spread`
|
||||
/// (additional shorthand will be ignored)
|
||||
///
|
||||
/// @param {map} $config [()] -
|
||||
/// Optional map of Susy grid configuration settings.
|
||||
/// See `$susy` documentation for details.
|
||||
///
|
||||
/// @return {length} -
|
||||
/// Width of a gutter as `%` of current context,
|
||||
/// or in the units defined by `column-width` when available
|
||||
///
|
||||
/// @example scss - add gutters before or after an element
|
||||
/// .floats {
|
||||
/// float: left;
|
||||
/// width: span(3 of 6);
|
||||
/// margin-left: gutter(of 6);
|
||||
/// }
|
||||
///
|
||||
/// @example scss - add gutters to padding
|
||||
/// .flexbox {
|
||||
/// flex: 1 1 span(3 wide of 6 wide);
|
||||
/// padding: gutter(of 6) / 2;
|
||||
/// }
|
||||
///
|
||||
@function susy-gutter(
|
||||
$context: susy-get('columns'),
|
||||
$config: ()
|
||||
) {
|
||||
$context: susy-compile($context, $config, 'context-only');
|
||||
|
||||
@return su-call('su-gutter', $context);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Susy Slice
|
||||
// ----------
|
||||
/// Working with asymmetrical grids (un-equal column widths)
|
||||
/// can be challenging –
|
||||
/// expecially when they involve fluid/fractional elements.
|
||||
/// Describing a context `of (15em 6em 6em 6em 15em)` is a lot
|
||||
/// to put inside the span or gutter function shorthand.
|
||||
/// This slice function returns a sub-slice of asymmetrical columns to use
|
||||
/// for a nested context.
|
||||
/// `slice(3 at 2)` will give you a subset of the global grid,
|
||||
/// spanning 3 columns, starting with the second.
|
||||
///
|
||||
/// - This is a thin syntax-sugar shell around
|
||||
/// the core-math `su-slice()` function.
|
||||
/// - The un-prefixed alias `slice()` is available by default.
|
||||
///
|
||||
/// @group b-api
|
||||
/// @see su-slice
|
||||
/// @see $susy
|
||||
///
|
||||
/// @param {list} $span -
|
||||
/// Shorthand expression to define the subset span, optionally containing:
|
||||
/// - `at $n`, `first`, or `last` location on asymmetrical grids;
|
||||
/// - `of $n <spread>` for available grid columns
|
||||
/// and spread of the container
|
||||
/// - Span-counts like `of 6` are only valid
|
||||
/// in the context of symmetrical grids
|
||||
/// - Valid spreads include `narrow`, `wide`, or `wider`
|
||||
///
|
||||
/// @param {map} $config [()] -
|
||||
/// Optional map of Susy grid configuration settings.
|
||||
/// See `$susy` documentation for details.
|
||||
///
|
||||
/// @return {list} -
|
||||
/// Subset list of columns for use for a nested context
|
||||
///
|
||||
/// @example scss - Return a nested segment of asymmetrical grid
|
||||
/// $context: susy-slice(3 at 3 of (1 2 3 5 8));
|
||||
/// /* $context: #{$context}; */
|
||||
@function susy-slice(
|
||||
$span,
|
||||
$config: ()
|
||||
) {
|
||||
$span: susy-compile($span, $config);
|
||||
|
||||
@return su-call('su-slice', $span);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// ## Building Grids
|
||||
/// The web has come a long way
|
||||
/// since the days of double-margin-hacks
|
||||
/// and inconsistent subpixel rounding.
|
||||
/// In addition to floats and tables,
|
||||
/// we can now use much more powerful tools,
|
||||
/// like flexbox and CSS grid,
|
||||
/// to build more interesting and responsive layouts.
|
||||
///
|
||||
/// With Susy3, we hope you'll start moving in that direction.
|
||||
/// You can still build classic 12-column Grid Systems,
|
||||
/// and we'll help you get there,
|
||||
/// but Susy3 is primarily designed for a grid-math-on-demand
|
||||
/// approach to layout:
|
||||
/// applying our functions only where you really need grid math.
|
||||
/// Read the [intro article by OddBird][welcome] for more details.
|
||||
///
|
||||
/// [welcome]: http://oddbird.net/2017/06/28/susy3/
|
||||
///
|
||||
/// @group b-api
|
||||
/// @link http://oddbird.net/2017/06/28/susy3/ Article: Welcome to Susy3
|
||||
///
|
||||
/// @example scss - floats
|
||||
/// .float {
|
||||
/// width: span(3);
|
||||
/// margin-right: gutter();
|
||||
/// }
|
||||
///
|
||||
/// @example scss - flexbox
|
||||
/// .flexbox {
|
||||
/// flex: 1 1 span(3);
|
||||
/// // half a gutter on either side…
|
||||
/// padding: 0 gutter() / 2;
|
||||
/// }
|
||||
///
|
||||
/// @example scss - pushing and pulling
|
||||
/// .push-3 {
|
||||
/// margin-left: span(3 wide);
|
||||
/// }
|
||||
///
|
||||
/// .pull-3 {
|
||||
/// margin-left: 0 - span(3 wide);
|
||||
/// }
|
||||
///
|
||||
/// @example scss - building an attribute system
|
||||
/// // markup example: <div data-span="last 3"></div>
|
||||
/// [data-span] {
|
||||
/// float: left;
|
||||
///
|
||||
/// &:not([data-span*='last']) {
|
||||
/// margin-right: gutter();
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// @for $span from 1 through length(susy-get('columns')) {
|
||||
/// [data-span*='#{$span}'] {
|
||||
/// width: span($span);
|
||||
/// }
|
||||
/// }
|
|
@ -0,0 +1,261 @@
|
|||
/// Syntax Normalization
|
||||
/// ====================
|
||||
/// Susy is divided into two layers:
|
||||
/// "Su" provides the core math functions with a stripped-down syntax,
|
||||
/// while "Susy" adds global settings, shorthand syntax,
|
||||
/// and other helpers.
|
||||
/// Each setting (e.g. span, location, columns, spread, etc.)
|
||||
/// has a single canonical syntax in Su.
|
||||
///
|
||||
/// This normalization module helps translate between those layers,
|
||||
/// transforming parsed Susy input into
|
||||
/// values that Su will understand.
|
||||
///
|
||||
/// @group x-normal
|
||||
///
|
||||
/// @see susy-normalize
|
||||
/// @see susy-normalize-span
|
||||
/// @see susy-normalize-columns
|
||||
/// @see susy-normalize-spread
|
||||
/// @see susy-normalize-location
|
||||
|
||||
|
||||
|
||||
// Susy Normalize
|
||||
// --------------
|
||||
/// Normalize the values in a configuration map.
|
||||
/// In addition to the global `$susy` properties,
|
||||
/// this map can include local span-related imformation,
|
||||
/// like `span` and `location`.
|
||||
///
|
||||
/// Normalization does not check that values are valid,
|
||||
/// which will happen in the Su math layer.
|
||||
/// These functions merely look for known Susy syntax –
|
||||
/// returning a map with those shorthand values
|
||||
/// converted into low-level data for Su.
|
||||
/// For example `span: all` and `location: first`
|
||||
/// will be converted into specific numbers.
|
||||
///
|
||||
/// @group x-normal
|
||||
/// @see $susy
|
||||
/// @see susy-parse
|
||||
///
|
||||
/// @param {map} $config -
|
||||
/// Map of Susy configuration settings to normalize.
|
||||
/// See `$susy` and `susy-parse()` documentation for details.
|
||||
/// @param {map | null} $context [null] -
|
||||
/// Map of Susy configuration settings to use as global reference,
|
||||
/// or `null` to use global settings.
|
||||
///
|
||||
/// @return {map} -
|
||||
/// Map of Susy configuration settings,
|
||||
/// with all values normalized for Su math functions.
|
||||
@function susy-normalize(
|
||||
$config,
|
||||
$context: null
|
||||
) {
|
||||
// Spread
|
||||
@each $setting in ('spread', 'container-spread') {
|
||||
$value: map-get($config, $setting);
|
||||
|
||||
@if $value {
|
||||
$value: susy-normalize-spread($value);
|
||||
$config: map-merge($config, ($setting: $value));
|
||||
}
|
||||
}
|
||||
|
||||
// Columns
|
||||
$columns: map-get($config, 'columns');
|
||||
|
||||
@if $columns {
|
||||
$columns: susy-normalize-columns($columns, $context);
|
||||
$config: map-merge($config, ('columns': $columns));
|
||||
}
|
||||
|
||||
@if not $columns {
|
||||
$map: type-of($context) == 'map';
|
||||
$columns: if($map, map-get($context, 'columns'), null);
|
||||
$columns: $columns or susy-get('columns');
|
||||
}
|
||||
|
||||
// Span
|
||||
$span: map-get($config, 'span');
|
||||
|
||||
@if $span {
|
||||
$span: susy-normalize-span($span, $columns);
|
||||
$config: map-merge($config, ('span': $span));
|
||||
}
|
||||
|
||||
// Location
|
||||
$location: map-get($config, 'location');
|
||||
|
||||
@if $location {
|
||||
$location: susy-normalize-location($span, $location, $columns);
|
||||
$config: map-merge($config, ('location': $location));
|
||||
}
|
||||
|
||||
@return $config;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Normalize Span
|
||||
// --------------
|
||||
/// Normalize `span` shorthand for Su.
|
||||
/// Su span syntax allows an explicit length (e.g. `3em`),
|
||||
/// unitless column-span number (e.g. `3` columns),
|
||||
/// or an explicit list of columns (e.g. `(3 5 8)`).
|
||||
///
|
||||
/// Susy span syntax also allows the `all` keyword,
|
||||
/// which will be converted to a slice of the context
|
||||
/// in normalization.
|
||||
///
|
||||
/// @group x-normal
|
||||
///
|
||||
/// @param {number | list | 'all'} $span -
|
||||
/// Span value to normalize.
|
||||
/// @param {list} $columns -
|
||||
/// Normalized list of columns in the grid
|
||||
///
|
||||
/// @return {number | list} -
|
||||
/// Number or list value for `$span`
|
||||
@function susy-normalize-span(
|
||||
$span,
|
||||
$columns: susy-get('columns')
|
||||
) {
|
||||
@if ($span == 'all') {
|
||||
@return length($columns);
|
||||
}
|
||||
|
||||
@return $span;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Normalize Columns
|
||||
// -----------------
|
||||
/// Normalize `column` shorthand for Su.
|
||||
/// Su column syntax only allows column lists (e.g. `120px 1 1 1 120px`).
|
||||
///
|
||||
/// Susy span syntax also allows a unitless `slice` number (e.g `of 5`),
|
||||
/// which will be converted to a slice of the context
|
||||
/// in normalization.
|
||||
///
|
||||
/// @group x-normal
|
||||
///
|
||||
/// @param {list | integer} $columns -
|
||||
/// List of available columns,
|
||||
/// or unitless integer representing a slice of
|
||||
/// the available context.
|
||||
/// @param {map | null} $context [null] -
|
||||
/// Map of Susy configuration settings to use as global reference,
|
||||
/// or `null` to access global settings.
|
||||
///
|
||||
/// @return {list} -
|
||||
/// Columns list value, normalized for Su input.
|
||||
///
|
||||
/// @throws
|
||||
/// when attempting to access a slice of asymmetrical context
|
||||
@function susy-normalize-columns(
|
||||
$columns,
|
||||
$context: null
|
||||
) {
|
||||
$context: $context or susy-settings();
|
||||
|
||||
@if type-of($columns) == 'list' {
|
||||
@return _susy-flatten($columns);
|
||||
}
|
||||
|
||||
@if (type-of($columns) == 'number') and (unitless($columns)) {
|
||||
$span: $columns;
|
||||
$context: map-get($context, 'columns');
|
||||
$symmetrical: susy-repeat(length($context), nth($context, 1));
|
||||
|
||||
@if ($context == $symmetrical) {
|
||||
@return susy-repeat($span, nth($context, 1));
|
||||
} @else {
|
||||
$actual: 'of `#{$span}`';
|
||||
$columns: 'grid-columns `#{$context}`';
|
||||
@return _susy-error(
|
||||
'context-slice #{$actual} can not be determined based on #{$columns}.',
|
||||
'susy-normalize-columns');
|
||||
}
|
||||
}
|
||||
|
||||
@return $columns;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Normalize Spread
|
||||
// ----------------
|
||||
/// Normalize `spread` shorthand for Su.
|
||||
/// Su spread syntax only allows the numbers `-1`, `0`, or `1` –
|
||||
/// representing the number of gutters covered
|
||||
/// in relation to columns spanned.
|
||||
///
|
||||
/// Susy spread syntax also allows keywords for each value –
|
||||
/// `narrow` for `-1`, `wide` for `0`, or `wider` for `1` –
|
||||
/// which will be converted to their respective integers
|
||||
/// in normalization.
|
||||
///
|
||||
/// @group x-normal
|
||||
///
|
||||
/// @param {0 | 1 | -1 | 'narrow' | 'wide' | 'wider'} $spread -
|
||||
/// Spread across adjacent gutters, relative to a column-count —
|
||||
/// either `narrow` (-1), `wide` (0), or `wider` (1)
|
||||
///
|
||||
/// @return {number} -
|
||||
/// Numeric value for `$spread`
|
||||
@function susy-normalize-spread(
|
||||
$spread
|
||||
) {
|
||||
$normal-spread: (
|
||||
'narrow': -1,
|
||||
'wide': 0,
|
||||
'wider': 1,
|
||||
);
|
||||
|
||||
@return map-get($normal-spread, $spread) or $spread;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Normalize Location
|
||||
// ------------------
|
||||
/// Normalize `location` shorthand for Su.
|
||||
/// Su location syntax requires the (1-indexed) number for a column.
|
||||
///
|
||||
/// Susy also allows the `first` and `last` keywords,
|
||||
/// where `first` is always `1`,
|
||||
/// and `last` is calculated based on span and column values.
|
||||
/// Both keywords are normalized into an integer index
|
||||
/// in normalization.
|
||||
///
|
||||
/// @group x-normal
|
||||
///
|
||||
/// @param {number} $span -
|
||||
/// Number of grid-columns to be spanned
|
||||
/// @param {integer | 'first' | 'last'} $location -
|
||||
/// Starting (1-indexed) column position of a span,
|
||||
/// or a named location keyword.
|
||||
/// @param {list} $columns -
|
||||
/// Already-normalized list of columns in the grid.
|
||||
///
|
||||
/// @return {integer} -
|
||||
/// Numeric value for `$location`
|
||||
@function susy-normalize-location(
|
||||
$span,
|
||||
$location,
|
||||
$columns
|
||||
) {
|
||||
$count: length($columns);
|
||||
$normal-locations: (
|
||||
'first': 1,
|
||||
'alpha': 1,
|
||||
'last': $count - $span + 1,
|
||||
'omega': $count - $span + 1,
|
||||
);
|
||||
|
||||
@return map-get($normal-locations, $location) or $location;
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
/// Shorthand Syntax Parser
|
||||
/// =======================
|
||||
/// The syntax parser converts [shorthand syntax][short]
|
||||
/// into a map of settings that can be compared/merged with
|
||||
/// other config maps and global setting.
|
||||
///
|
||||
/// [short]: b-api.html
|
||||
///
|
||||
/// @group x-parser
|
||||
|
||||
|
||||
|
||||
// Parse
|
||||
// -----
|
||||
/// The `parse` function provides all the syntax-sugar in Susy,
|
||||
/// converting user shorthand
|
||||
/// into a usable map of keys and values
|
||||
/// that can be normalized and passed to Su.
|
||||
///
|
||||
/// @group x-parser
|
||||
/// @see $susy
|
||||
///
|
||||
/// @param {list} $shorthand -
|
||||
/// Shorthand expression to define the width of the span,
|
||||
/// optionally containing:
|
||||
/// - a count, length, or column-list span;
|
||||
/// - `at $n`, `first`, or `last` location on asymmetrical grids;
|
||||
/// - `narrow`, `wide`, or `wider` for optionally spreading
|
||||
/// across adjacent gutters;
|
||||
/// - `of $n <spread>` for available grid columns
|
||||
/// and spread of the container
|
||||
/// (span counts like `of 6` are only valid
|
||||
/// in the context of symmetrical grids);
|
||||
/// - and `set-gutters $n` to override global gutter settings
|
||||
/// @param {bool} $context-only [false] -
|
||||
/// Allow the parser to ignore span and span-spread values,
|
||||
/// only parsing context and container-spread.
|
||||
/// This makes it possible to accept spanless values,
|
||||
/// like the `gutters()` syntax.
|
||||
/// When parsing context-only,
|
||||
/// the `of` indicator is optional.
|
||||
///
|
||||
/// @return {map} -
|
||||
/// Map of span and grid settings
|
||||
/// parsed from shorthand input –
|
||||
/// including all the properties available globally –
|
||||
/// `columns`, `gutters`, `spread`, `container-spread` –
|
||||
/// along with the span-specific properties
|
||||
/// `span`, and `location`.
|
||||
///
|
||||
/// @throw
|
||||
/// when a shorthand value is not recognized
|
||||
@function susy-parse(
|
||||
$shorthand,
|
||||
$context-only: false
|
||||
) {
|
||||
$parse-error: 'Unknown shorthand property:';
|
||||
$options: (
|
||||
'first': 'location',
|
||||
'last': 'location',
|
||||
'alpha': 'location',
|
||||
'omega': 'location',
|
||||
'narrow': 'spread',
|
||||
'wide': 'spread',
|
||||
'wider': 'spread',
|
||||
);
|
||||
|
||||
$return: ();
|
||||
$span: null;
|
||||
$columns: null;
|
||||
|
||||
$of: null;
|
||||
$next: false;
|
||||
|
||||
// Allow context-only shorthand, without span
|
||||
@if ($context-only) and (not index($shorthand, 'of')) {
|
||||
@if su-valid-columns($shorthand, 'fail-silent') {
|
||||
$shorthand: 'of' $shorthand;
|
||||
} @else {
|
||||
$shorthand: join('of', $shorthand);
|
||||
}
|
||||
}
|
||||
|
||||
// loop through the shorthand list
|
||||
@for $i from 1 through length($shorthand) {
|
||||
$item: nth($shorthand, $i);
|
||||
$type: type-of($item);
|
||||
$error: false;
|
||||
$details: '[#{$type}] `#{$item}`';
|
||||
|
||||
// if we know what's supposed to be coming next…
|
||||
@if $next {
|
||||
|
||||
// Add to the return map
|
||||
$return: map-merge($return, ($next: $item));
|
||||
|
||||
// Reset next to `false`
|
||||
$next: false;
|
||||
|
||||
} @else { // If we don't know what's supposed to be coming…
|
||||
|
||||
// Keywords…
|
||||
@if ($type == 'string') {
|
||||
// Check the map for keywords…
|
||||
@if map-has-key($options, $item) {
|
||||
$setting: map-get($options, $item);
|
||||
|
||||
// Spread could be on the span or the container…
|
||||
@if ($setting == 'spread') and ($of) {
|
||||
$return: map-merge($return, ('container-spread': $item));
|
||||
} @else {
|
||||
$return: map-merge($return, ($setting: $item));
|
||||
}
|
||||
|
||||
} @else if ($item == 'all') {
|
||||
// `All` is a span shortcut
|
||||
$span: 'all';
|
||||
} @else if ($item == 'at') {
|
||||
// Some keywords setup what's next…
|
||||
$next: 'location';
|
||||
} @else if ($item == 'set-gutters') {
|
||||
$next: 'gutters';
|
||||
} @else if ($item == 'of') {
|
||||
$of: true;
|
||||
} @else {
|
||||
$error: true;
|
||||
}
|
||||
|
||||
} @else if ($type == 'number') or ($type == 'list') { // Numbers & lists…
|
||||
|
||||
@if not ($span or $of) {
|
||||
// We don't have a span, and we're not expecting context…
|
||||
$span: $item;
|
||||
} @else if ($of) and (not $columns) {
|
||||
// We are expecting context…
|
||||
$columns: $item;
|
||||
} @else {
|
||||
$error: true;
|
||||
}
|
||||
|
||||
} @else {
|
||||
$error: true;
|
||||
}
|
||||
}
|
||||
|
||||
@if $error {
|
||||
@return _susy-error('#{$parse-error} #{$details}', 'susy-parse');
|
||||
}
|
||||
}
|
||||
|
||||
// If we have span, merge it in
|
||||
@if $span {
|
||||
$return: map-merge($return, ('span': $span));
|
||||
}
|
||||
|
||||
// If we have columns, merge them in
|
||||
@if $columns {
|
||||
$return: map-merge($return, ('columns': $columns));
|
||||
}
|
||||
|
||||
// Return the map of settings…
|
||||
@return $return;
|
||||
}
|
|
@ -0,0 +1,329 @@
|
|||
/// Susy3 Configuration
|
||||
/// ===================
|
||||
/// Susy3 has 4 core settings, in a single settings map.
|
||||
/// You'll notice a few differences from Susy2:
|
||||
///
|
||||
/// **Columns** no longer accept a single number, like `12`,
|
||||
/// but use a syntax more similar to the new
|
||||
/// CSS [grid-template-columns][columns] –
|
||||
/// a list of relative sizes for each column on the grid.
|
||||
/// Unitless numbers in Susy act very similar to `fr` units in CSS,
|
||||
/// and the `susy-repeat()` function (similar to the css `repeat()`)
|
||||
/// helps quickly establish equal-width columns.
|
||||
///
|
||||
/// [columns]: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns
|
||||
///
|
||||
/// - `susy-repeat(12)` will create 12 fluid, equal-width columns
|
||||
/// - `susy-repeat(6, 120px)` will create 6 equal `120px`-wide columns
|
||||
/// - `120px susy-repeat(4) 120px` will create 6 columns,
|
||||
/// the first and last are `120px`,
|
||||
/// while the middle 4 are equal fractions of the remainder.
|
||||
/// Susy will output `calc()` values in order to achieve this.
|
||||
///
|
||||
/// **Gutters** haven't changed –
|
||||
/// a single fraction or explicit width –
|
||||
/// but the `calc()` output feature
|
||||
/// means you can now use any combination of units and fractions
|
||||
/// to create static-gutters on a fluid grid, etc.
|
||||
///
|
||||
/// **Spread** existed in the Susy2 API as a span option,
|
||||
/// and was otherwise handled behind the scenes.
|
||||
/// Now we're giving you full control over all spread issues.
|
||||
/// You can find a more [detailed explanation of spread on the blog][spread].
|
||||
///
|
||||
/// [spread]: http://oddbird.net/2017/06/13/susy-spread/
|
||||
///
|
||||
/// You can access your global settings at any time
|
||||
/// with the `susy-settings()` function,
|
||||
/// or grab a single setting from the global scope
|
||||
/// with `susy-get('columns')`, `susy-get('gutters')` etc.
|
||||
///
|
||||
/// @group a-config
|
||||
/// @link http://oddbird.net/2017/06/13/susy-spread/
|
||||
/// Article: Understanding Spread in Susy3
|
||||
///
|
||||
/// @see $susy
|
||||
/// @see susy-settings
|
||||
/// @see susy-get
|
||||
|
||||
|
||||
|
||||
// Susy
|
||||
// ----
|
||||
/// The grid is defined in a single map variable,
|
||||
/// with four initial properties:
|
||||
/// `columns`, `gutters`, `spread` and `container-spread`.
|
||||
/// Anything you put in the root `$susy` variable map
|
||||
/// will be treated as a global project default.
|
||||
/// You can create similar configuration maps
|
||||
/// under different variable names,
|
||||
/// to override the defaults as-needed.
|
||||
///
|
||||
/// @group a-config
|
||||
/// @type Map
|
||||
///
|
||||
/// @see $_susy-defaults
|
||||
/// @see {function} susy-repeat
|
||||
/// @link
|
||||
/// https://codepen.io/mirisuzanne/pen/EgmJJp?editors=1100
|
||||
/// Spread examples on CodePen
|
||||
///
|
||||
/// @prop {list} columns -
|
||||
/// Columns are described by a list of numbers,
|
||||
/// representing the relative width of each column.
|
||||
/// The syntax is a simplified version of CSS native
|
||||
/// `grid-template-columns`,
|
||||
/// expecting a list of grid-column widths.
|
||||
/// Unitless numbers create fractional fluid columns
|
||||
/// (similar to the CSS-native `fr` unit),
|
||||
/// while length values (united numbers)
|
||||
/// are used to define static columns.
|
||||
/// You can mix-and match units and fractions,
|
||||
/// to create a mixed grid.
|
||||
/// Susy will generate `calc()` values when necessary,
|
||||
/// to make all your units work together.
|
||||
///
|
||||
/// Use the `susy-repeat($count, $value)` function
|
||||
/// to more easily repetative columns,
|
||||
/// similar to the CSS-native `repeat()`.
|
||||
///
|
||||
/// - `susy-repeat(8)`:
|
||||
/// an 8-column, symmetrical, fluid grid.
|
||||
/// <br />Identical to `(1 1 1 1 1 1 1 1)`.
|
||||
/// - `susy-repeat(6, 8em)`:
|
||||
/// a 6-column, symmetrical, em-based grid.
|
||||
/// <br />Identical to `(8em 8em 8em 8em 8em 8em)`.
|
||||
/// - `(300px susy-repeat(4) 300px)`:
|
||||
/// a 6-column, asymmetrical, mixed fluid/static grid
|
||||
/// using `calc()` output.
|
||||
/// <br />Identical to `(300px 1 1 1 1 300px)`.
|
||||
///
|
||||
/// **NOTE** that `12` is no longer a valid 12-column grid definition,
|
||||
/// and you must list all the columns individually
|
||||
/// (or by using the `susy-repeat()` function).
|
||||
///
|
||||
/// @prop {number} gutters -
|
||||
/// Gutters are defined as a single width,
|
||||
/// or fluid ratio, similar to the native-CSS
|
||||
/// `grid-column-gap` syntax.
|
||||
/// Similar to columns,
|
||||
/// gutters can use any valid CSS length unit,
|
||||
/// or unitless numbers to define a relative fraction.
|
||||
///
|
||||
/// - `0.5`:
|
||||
/// a fluid gutter, half the size of a single-fraction column.
|
||||
/// - `1em`:
|
||||
/// a static gutter, `1em` wide.
|
||||
///
|
||||
/// Mix static gutters with fluid columns, or vice versa,
|
||||
/// and Susy will generate the required `calc()` to make it work.
|
||||
///
|
||||
/// @prop {string} spread [narrow] -
|
||||
/// Spread of an element across adjacent gutters:
|
||||
/// either `narrow` (none), `wide` (one), or `wider` (two)
|
||||
///
|
||||
/// - Both spread settings default to `narrow`,
|
||||
/// the most common use-case.
|
||||
/// A `narrow` spread only has gutters *between* columns
|
||||
/// (one less gutter than columns).
|
||||
/// This is how all css-native grids work,
|
||||
/// and most margin-based grid systems.
|
||||
/// - A `wide` spread includes the same number of gutters as columns,
|
||||
/// spanning across a single side-gutter.
|
||||
/// This is how most padding-based grid systems often work,
|
||||
/// and is also useful for pushing and pulling elements into place.
|
||||
/// - The rare `wider` spread includes gutters
|
||||
/// on both sides of the column-span
|
||||
/// (one more gutters than columns).
|
||||
///
|
||||
/// @prop {string} container-spread [narrow] -
|
||||
/// Spread of a container around adjacent gutters:
|
||||
/// either `narrow` (none), `wide` (one), or `wider` (two).
|
||||
/// See `spread` property for details.
|
||||
///
|
||||
/// @since 3.0.0-beta.1 -
|
||||
/// `columns` setting no longer accepts numbers
|
||||
/// (e.g. `12`) for symmetrical fluid grids,
|
||||
/// or the initial `12 x 120px` syntax for
|
||||
/// symmetrical fixed-unit grids.
|
||||
/// Use `susy-repeat(12)` or `susy-repeat(12, 120px)` instead.
|
||||
///
|
||||
/// @example scss - default values
|
||||
/// // 4 symmetrical, fluid columns
|
||||
/// // gutters are 1/4 the size of a column
|
||||
/// // elements span 1 less gutter than columns
|
||||
/// // containers span 1 less gutter as well
|
||||
/// $susy: (
|
||||
/// 'columns': susy-repeat(4),
|
||||
/// 'gutters': 0.25,
|
||||
/// 'spread': 'narrow',
|
||||
/// 'container-spread': 'narrow',
|
||||
/// );
|
||||
///
|
||||
/// @example scss - inside-static gutters
|
||||
/// // 6 symmetrical, fluid columns…
|
||||
/// // gutters are static, triggering calc()…
|
||||
/// // elements span equal columns & gutters…
|
||||
/// // containers span equal columns & gutters…
|
||||
/// $susy: (
|
||||
/// 'columns': susy-repeat(6),
|
||||
/// 'gutters': 0.5em,
|
||||
/// 'spread': 'wide',
|
||||
/// 'container-spread': 'wide',
|
||||
/// );
|
||||
$susy: () !default;
|
||||
|
||||
|
||||
|
||||
// Susy Repeat
|
||||
// -----------
|
||||
/// Similar to the `repeat(<count>, <value>)` function
|
||||
/// that is available in native CSS Grid templates,
|
||||
/// the `susy-repeat()` function helps generate repetative layouts
|
||||
/// by repeating any value a given number of times.
|
||||
/// Where Susy previously allowed `8` as a column definition
|
||||
/// for 8 equal columns, you should now use `susy-repeat(8)`.
|
||||
///
|
||||
/// @group a-config
|
||||
///
|
||||
/// @param {integer} $count -
|
||||
/// The number of repetitions, e.g. `12` for a 12-column grid.
|
||||
/// @param {*} $value [1] -
|
||||
/// The value to be repeated.
|
||||
/// Technically any value can be repeated here,
|
||||
/// but the function exists to repeat column-width descriptions:
|
||||
/// e.g. the default `1` for single-fraction fluid columns,
|
||||
/// `5em` for a static column,
|
||||
/// or even `5em 120px` if you are alternating column widths.
|
||||
///
|
||||
/// @return {list} -
|
||||
/// List of repeated values
|
||||
///
|
||||
/// @example scss
|
||||
/// // 12 column grid, with 5em columns
|
||||
/// $susy: (
|
||||
/// columns: susy-repeat(12, 5em),
|
||||
/// );
|
||||
///
|
||||
/// @example scss
|
||||
/// // asymmetrical 5-column grid
|
||||
/// $susy: (
|
||||
/// columns: 20px susy-repeat(3, 100px) 20px,
|
||||
/// );
|
||||
///
|
||||
/// /* result: #{susy-get('columns')} */
|
||||
@function susy-repeat(
|
||||
$count,
|
||||
$value: 1
|
||||
) {
|
||||
$return: ();
|
||||
|
||||
@for $i from 1 through $count {
|
||||
$return: join($return, $value);
|
||||
}
|
||||
|
||||
@return $return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Susy Defaults
|
||||
// -------------
|
||||
/// Configuration map of Susy factory defaults.
|
||||
/// Do not override this map directly –
|
||||
/// use `$susy` for user and project setting overrides.
|
||||
///
|
||||
/// @access private
|
||||
/// @type Map
|
||||
///
|
||||
/// @see $susy
|
||||
///
|
||||
/// @prop {number | list} columns [susy-repeat(4)]
|
||||
/// @prop {number} gutters [0.25]
|
||||
/// @prop {string} spread ['narrow']
|
||||
/// @prop {string} container-spread ['narrow']
|
||||
$_susy-defaults: (
|
||||
'columns': susy-repeat(4),
|
||||
'gutters': 0.25,
|
||||
'spread': 'narrow',
|
||||
'container-spread': 'narrow',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Susy Settings
|
||||
// -------------
|
||||
/// Return a combined map of Susy settings,
|
||||
/// based on the factory defaults (`$_susy-defaults`),
|
||||
/// user-defined project configuration (`$susy`),
|
||||
/// and any local overrides required –
|
||||
/// such as a configuration map passed into a function.
|
||||
///
|
||||
/// @group a-config
|
||||
///
|
||||
/// @param {maps} $overrides… -
|
||||
/// Optional map override of global configuration settings.
|
||||
/// See `$susy` above for properties.
|
||||
///
|
||||
/// @return {map} -
|
||||
/// Combined map of Susy configuration settings,
|
||||
/// in order of specificity:
|
||||
/// any `$overrides...`,
|
||||
/// then `$susy` project settings,
|
||||
/// and finally the `$_susy-defaults`
|
||||
///
|
||||
/// @example scss - global settings
|
||||
/// @each $key, $value in susy-settings() {
|
||||
/// /* #{$key}: #{$value} */
|
||||
/// }
|
||||
///
|
||||
/// @example scss - local settings
|
||||
/// $local: ('columns': 1 2 3 5 8);
|
||||
///
|
||||
/// @each $key, $value in susy-settings($local) {
|
||||
/// /* #{$key}: #{$value} */
|
||||
/// }
|
||||
@function susy-settings(
|
||||
$overrides...
|
||||
) {
|
||||
$settings: map-merge($_susy-defaults, $susy);
|
||||
|
||||
@each $config in $overrides {
|
||||
$settings: map-merge($settings, $config);
|
||||
}
|
||||
|
||||
@return $settings;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Susy Get
|
||||
// --------
|
||||
/// Return the current global value of any Susy setting
|
||||
///
|
||||
/// @group a-config
|
||||
///
|
||||
/// @param {string} $key -
|
||||
/// Setting to retrieve from the configuration.
|
||||
///
|
||||
/// @return {*} -
|
||||
/// Value mapped to `$key` in the configuration maps,
|
||||
/// in order of specificity:
|
||||
/// `$susy`, then `$_susy-defaults`
|
||||
///
|
||||
/// @example scss -
|
||||
/// /* columns: #{susy-get('columns')} */
|
||||
/// /* gutters: #{susy-get('gutters')} */
|
||||
@function susy-get(
|
||||
$key
|
||||
) {
|
||||
$settings: susy-settings();
|
||||
|
||||
@if not map-has-key($settings, $key) {
|
||||
@return _susy-error(
|
||||
'There is no Susy setting called `#{$key}`',
|
||||
'susy-get');
|
||||
}
|
||||
|
||||
@return map-get($settings, $key);
|
||||
}
|
|
@ -0,0 +1,441 @@
|
|||
/// Grid Math Engine
|
||||
/// ================
|
||||
/// The `su` functions give you direct access to the math layer,
|
||||
/// without any syntax-sugar like shorthand parsing, and normalization.
|
||||
/// If you prefer named arguments, and stripped-down syntax,
|
||||
/// you can use these functions directly in your code –
|
||||
/// replacing `span`, `gutter`, and `slice`.
|
||||
///
|
||||
/// These functions are also useful
|
||||
/// for building mixins or other extensions to Susy.
|
||||
/// Apply the Susy syntax to new mixins and functions,
|
||||
/// using our "Plugin Helpers",
|
||||
/// or write your own syntax and pass the normalized results along
|
||||
/// to `su` for compilation.
|
||||
///
|
||||
/// @group su-math
|
||||
///
|
||||
/// @see su-span
|
||||
/// @see su-gutter
|
||||
/// @see su-slice
|
||||
/// @ignore _su-sum
|
||||
/// @ignore _su-calc-span
|
||||
/// @ignore _su-calc-sum
|
||||
/// @ignore _su-needs-calc-output
|
||||
|
||||
|
||||
|
||||
// Su Span
|
||||
// -------
|
||||
/// Calculates and returns a CSS-ready span width,
|
||||
/// based on normalized span and context data –
|
||||
/// a low-level version of `susy-span`,
|
||||
/// with all of the logic and none of the syntax sugar.
|
||||
///
|
||||
/// - Grids defined with unitless numbers will return `%` values.
|
||||
/// - Grids defined with comparable units
|
||||
/// will return a value in the units provided.
|
||||
/// - Grids defined with a mix of units,
|
||||
/// or a combination of untiless numbers and unit-lengths,
|
||||
/// will return a `calc()` string.
|
||||
///
|
||||
/// @group su-math
|
||||
/// @see susy-span
|
||||
///
|
||||
/// @param {number | list} $span -
|
||||
/// Number or list of grid columns to span
|
||||
/// @param {list} $columns -
|
||||
/// List of columns available
|
||||
/// @param {number} $gutters -
|
||||
/// Width of a gutter in column-comparable units
|
||||
/// @param {0 | 1 | -1} $spread -
|
||||
/// Number of gutters spanned,
|
||||
/// relative to `span` count
|
||||
/// @param {0 | 1 | -1} $container-spread [$spread] -
|
||||
/// Number of gutters spanned,
|
||||
/// relative to `columns` count
|
||||
/// @param {integer} $location [1] -
|
||||
/// Optional position of sub-span among full set of columns
|
||||
///
|
||||
/// @return {length} -
|
||||
/// Relative or static length of a span on the grid
|
||||
@function su-span(
|
||||
$span,
|
||||
$columns,
|
||||
$gutters,
|
||||
$spread,
|
||||
$container-spread: $spread,
|
||||
$location: 1
|
||||
) {
|
||||
$span: su-valid-span($span);
|
||||
$columns: su-valid-columns($columns);
|
||||
$gutters: su-valid-gutters($gutters);
|
||||
$spread: su-valid-spread($spread);
|
||||
|
||||
@if (type-of($span) == 'number') {
|
||||
@if (not unitless($span)) {
|
||||
@return $span;
|
||||
}
|
||||
|
||||
$location: su-valid-location($span, $location, $columns);
|
||||
$span: su-slice($span, $columns, $location, $validate: false);
|
||||
}
|
||||
|
||||
@if _su-needs-calc-output($span, $columns, $gutters, $spread, not 'validate') {
|
||||
@return _su-calc-span($span, $columns, $gutters, $spread, $container-spread, not 'validate');
|
||||
}
|
||||
|
||||
$span-width: _su-sum($span, $gutters, $spread, $validate: false);
|
||||
|
||||
@if unitless($span-width) {
|
||||
$container-spread: su-valid-spread($container-spread);
|
||||
$container: _su-sum($columns, $gutters, $container-spread, $validate: false);
|
||||
@return percentage($span-width / $container);
|
||||
}
|
||||
|
||||
@return $span-width;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Su Gutter
|
||||
// ---------
|
||||
/// Calculates and returns a CSS-ready gutter width,
|
||||
/// based on normalized grid data –
|
||||
/// a low-level version of `susy-gutter`,
|
||||
/// with all of the logic and none of the syntax sugar.
|
||||
///
|
||||
/// - Grids defined with unitless numbers will return `%` values.
|
||||
/// - Grids defined with comparable units
|
||||
/// will return a value in the units provided.
|
||||
/// - Grids defined with a mix of units,
|
||||
/// or a combination of untiless numbers and unit-lengths,
|
||||
/// will return a `calc()` string.
|
||||
///
|
||||
/// @group su-math
|
||||
/// @see susy-gutter
|
||||
///
|
||||
/// @param {list} $columns -
|
||||
/// List of columns in the grid
|
||||
/// @param {number} $gutters -
|
||||
/// Width of a gutter in column-comparable units
|
||||
/// @param {0 | 1 | -1} $container-spread -
|
||||
/// Number of gutters spanned,
|
||||
/// relative to `columns` count
|
||||
///
|
||||
/// @return {length} -
|
||||
/// Relative or static length of one gutter in a grid
|
||||
@function su-gutter(
|
||||
$columns,
|
||||
$gutters,
|
||||
$container-spread
|
||||
) {
|
||||
@if (type-of($gutters) == 'number') {
|
||||
@if ($gutters == 0) or (not unitless($gutters)) {
|
||||
@return $gutters;
|
||||
}
|
||||
}
|
||||
|
||||
@if _su-needs-calc-output($gutters, $columns, $gutters, -1, not 'validate') {
|
||||
@return _su-calc-span($gutters, $columns, $gutters, -1, $container-spread, not 'validate');
|
||||
}
|
||||
|
||||
$container: _su-sum($columns, $gutters, $container-spread);
|
||||
@return percentage($gutters / $container);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Su Slice
|
||||
// --------
|
||||
/// Returns a list of columns
|
||||
/// based on a given span/location slice of the grid –
|
||||
/// a low-level version of `susy-slice`,
|
||||
/// with all of the logic and none of the syntax sugar.
|
||||
///
|
||||
/// @group su-math
|
||||
/// @see susy-slice
|
||||
///
|
||||
/// @param {number} $span -
|
||||
/// Number of grid columns to span
|
||||
/// @param {list} $columns -
|
||||
/// List of columns in the grid
|
||||
/// @param {number} $location [1] -
|
||||
/// Starting index of a span in the list of columns
|
||||
/// @param {bool} $validate [true] -
|
||||
/// Check that arguments are valid before proceeding
|
||||
///
|
||||
/// @return {list} -
|
||||
/// Subset list of grid columns, based on span and location
|
||||
@function su-slice(
|
||||
$span,
|
||||
$columns,
|
||||
$location: 1,
|
||||
$validate: true
|
||||
) {
|
||||
@if $validate {
|
||||
$columns: su-valid-columns($columns);
|
||||
$location: su-valid-location($span, $location, $columns);
|
||||
}
|
||||
|
||||
$floor: floor($span);
|
||||
$sub-columns: ();
|
||||
|
||||
@for $i from $location to ($location + $floor) {
|
||||
$sub-columns: append($sub-columns, nth($columns, $i));
|
||||
}
|
||||
|
||||
@if $floor != $span {
|
||||
$remainder: $span - $floor;
|
||||
$column: $location + $floor;
|
||||
$sub-columns: append($sub-columns, nth($columns, $column) * $remainder);
|
||||
}
|
||||
|
||||
@return $sub-columns;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Su Sum
|
||||
// ------
|
||||
/// Get the total sum of column-units in a layout.
|
||||
///
|
||||
/// @group su-math
|
||||
/// @access private
|
||||
///
|
||||
/// @param {list} $columns -
|
||||
/// List of columns in the grid
|
||||
/// @param {number} $gutters -
|
||||
/// Width of a gutter in column-comparable units
|
||||
/// @param {0 | 1 | -1} $spread -
|
||||
/// Number of gutters spanned,
|
||||
/// relative to `columns` count
|
||||
/// @param {bool} $validate [true] -
|
||||
/// Check that arguments are valid before proceeding
|
||||
///
|
||||
/// @return {number} -
|
||||
/// Total sum of column-units in a grid
|
||||
@function _su-sum(
|
||||
$columns,
|
||||
$gutters,
|
||||
$spread,
|
||||
$validate: true
|
||||
) {
|
||||
@if $validate {
|
||||
$columns: su-valid-span($columns);
|
||||
$gutters: su-valid-gutters($gutters);
|
||||
$spread: su-valid-spread($spread);
|
||||
}
|
||||
|
||||
// Calculate column-sum
|
||||
$column-sum: 0;
|
||||
@each $column in $columns {
|
||||
$column-sum: $column-sum + $column;
|
||||
}
|
||||
|
||||
$gutter-sum: (ceil(length($columns)) + $spread) * $gutters;
|
||||
$total: if(($gutter-sum > 0), $column-sum + $gutter-sum, $column-sum);
|
||||
|
||||
@return $total;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Su Calc
|
||||
// -------
|
||||
/// Return a usable span width as a `calc()` function,
|
||||
/// in order to create mixed-unit grids.
|
||||
///
|
||||
/// @group su-math
|
||||
/// @access private
|
||||
///
|
||||
/// @param {number | list} $span -
|
||||
/// Pre-sliced list of grid columns to span
|
||||
/// @param {list} $columns -
|
||||
/// List of columns available
|
||||
/// @param {number} $gutters -
|
||||
/// Width of a gutter in column-comparable units
|
||||
/// @param {0 | 1 | -1} $spread -
|
||||
/// Number of gutters spanned,
|
||||
/// relative to `span` count
|
||||
/// @param {0 | 1 | -1} $container-spread [$spread] -
|
||||
/// Number of gutters spanned,
|
||||
/// relative to `columns` count
|
||||
/// @param {bool} $validate [true] -
|
||||
/// Check that arguments are valid before proceeding
|
||||
///
|
||||
/// @return {length} -
|
||||
/// Relative or static length of a span on the grid
|
||||
@function _su-calc-span(
|
||||
$span,
|
||||
$columns,
|
||||
$gutters,
|
||||
$spread,
|
||||
$container-spread: $spread,
|
||||
$validate: true
|
||||
) {
|
||||
@if $validate {
|
||||
$span: su-valid-span($span);
|
||||
$columns: su-valid-columns($columns);
|
||||
$gutters: su-valid-gutters($gutters);
|
||||
$spread: su-valid-spread($spread);
|
||||
$container-spread: su-valid-spread($container-spread);
|
||||
}
|
||||
|
||||
// Span and context
|
||||
$span: _su-calc-sum($span, $gutters, $spread, not 'validate');
|
||||
$context: _su-calc-sum($columns, $gutters, $container-spread, not 'validate');
|
||||
|
||||
// Fixed and fluid
|
||||
$fixed-span: map-get($span, 'fixed');
|
||||
$fluid-span: map-get($span, 'fluid');
|
||||
$fixed-context: map-get($context, 'fixed');
|
||||
$fluid-context: map-get($context, 'fluid');
|
||||
|
||||
$calc: '#{$fixed-span}';
|
||||
$fluid-calc: '(100% - #{$fixed-context})';
|
||||
|
||||
// Fluid-values
|
||||
@if (not $fluid-span) {
|
||||
$fluid-calc: null;
|
||||
} @else if ($fluid-span != $fluid-context) {
|
||||
$fluid-span: '* #{$fluid-span}';
|
||||
$fluid-context: if($fluid-context, '/ #{$fluid-context}', '');
|
||||
$fluid-calc: '(#{$fluid-calc $fluid-context $fluid-span})';
|
||||
}
|
||||
|
||||
@if $fluid-calc {
|
||||
$calc: if(($calc != ''), '#{$calc} + ', '');
|
||||
$calc: '#{$calc + $fluid-calc}';
|
||||
}
|
||||
|
||||
@return calc(#{unquote($calc)});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Su Calc-Sum
|
||||
// -----------
|
||||
/// Get the total sum of fixed and fluid column-units
|
||||
/// for creating a mixed-unit layout with `calc()` values.
|
||||
///
|
||||
/// @group su-math
|
||||
/// @access private
|
||||
///
|
||||
/// @param {list} $columns -
|
||||
/// List of columns available
|
||||
/// @param {number} $gutters -
|
||||
/// Width of a gutter in column-comparable units
|
||||
/// @param {0 | 1 | -1} $spread -
|
||||
/// Number of gutters spanned,
|
||||
/// relative to `span` count
|
||||
/// @param {bool} $validate [true] -
|
||||
/// Check that arguments are valid before proceeding
|
||||
///
|
||||
/// @return {map} -
|
||||
/// Map with `fixed` and `fluid` keys
|
||||
/// containing the proper math as strings
|
||||
@function _su-calc-sum(
|
||||
$columns,
|
||||
$gutters,
|
||||
$spread,
|
||||
$validate: true
|
||||
) {
|
||||
@if $validate {
|
||||
$columns: su-valid-span($columns);
|
||||
$gutters: su-valid-gutters($gutters);
|
||||
$spread: su-valid-spread($spread);
|
||||
}
|
||||
|
||||
$fluid: 0;
|
||||
$fixed: ();
|
||||
$calc: null;
|
||||
|
||||
// Gutters
|
||||
$gutters: $gutters * (length($columns) + $spread);
|
||||
|
||||
// Columns
|
||||
@each $col in append($columns, $gutters) {
|
||||
@if unitless($col) {
|
||||
$fluid: $fluid + $col;
|
||||
} @else {
|
||||
$fixed: _su-map-add-units($fixed, $col);
|
||||
}
|
||||
}
|
||||
|
||||
// Compile Fixed Units
|
||||
@each $unit, $total in $fixed {
|
||||
@if ($total != (0 * $total)) {
|
||||
$calc: if($calc, '#{$calc} + #{$total}', '#{$total}');
|
||||
}
|
||||
}
|
||||
|
||||
// Calc null or string
|
||||
@if $calc {
|
||||
$calc: if(str-index($calc, '+'), '(#{$calc})', '#{$calc}');
|
||||
}
|
||||
|
||||
// Fluid 0 => null
|
||||
$fluid: if(($fluid == 0), null, $fluid);
|
||||
|
||||
|
||||
// Return map
|
||||
$return: (
|
||||
'fixed': $calc,
|
||||
'fluid': $fluid,
|
||||
);
|
||||
|
||||
@return $return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Needs Calc
|
||||
// ----------
|
||||
/// Check if `calc()` will be needed in defining a span,
|
||||
/// if the necessary units in a grid are not comparable.
|
||||
///
|
||||
/// @group su-math
|
||||
/// @access private
|
||||
///
|
||||
/// @param {list} $span -
|
||||
/// Slice of columns to span
|
||||
/// @param {list} $columns -
|
||||
/// List of available columns in the grid
|
||||
/// @param {number} $gutters -
|
||||
/// Width of a gutter
|
||||
/// @param {0 | 1 | -1} $spread -
|
||||
/// Number of gutters spanned,
|
||||
/// relative to `span` count
|
||||
/// @param {bool} $validate [true] -
|
||||
/// Check that arguments are valid before proceeding
|
||||
///
|
||||
/// @return {bool} -
|
||||
/// `True` when units do not match, and `calc()` will be required
|
||||
@function _su-needs-calc-output(
|
||||
$span,
|
||||
$columns,
|
||||
$gutters,
|
||||
$spread,
|
||||
$validate: true
|
||||
) {
|
||||
@if $validate {
|
||||
$span: su-valid-span($span);
|
||||
$columns: su-valid-columns($columns);
|
||||
$gutters: su-valid-gutters($gutters);
|
||||
}
|
||||
|
||||
$has-gutter: if((length($span) > 1) or ($spread >= 0), true, false);
|
||||
$check: if($has-gutter, append($span, $gutters), $span);
|
||||
$safe-span: _su-is-comparable($check...);
|
||||
|
||||
@if ($safe-span == 'static') {
|
||||
@return false;
|
||||
} @else if (not $safe-span) {
|
||||
@return true;
|
||||
}
|
||||
|
||||
$safe-fluid: _su-is-comparable($gutters, $columns...);
|
||||
|
||||
@return not $safe-fluid;
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
/// Validation
|
||||
/// ==========
|
||||
/// Each argument to Su has a single canonical syntax.
|
||||
/// These validation functions check to ensure
|
||||
/// that each argument is valid,
|
||||
/// in order to provide useful errors
|
||||
/// before attempting to calculate the results/
|
||||
///
|
||||
/// @group x-validation
|
||||
///
|
||||
/// @see su-valid-columns
|
||||
/// @see su-valid-gutters
|
||||
/// @see su-valid-spread
|
||||
/// @see su-valid-location
|
||||
|
||||
|
||||
|
||||
// Valid Span
|
||||
// ----------
|
||||
/// Check that the `span` argument
|
||||
/// is a number, length, or column-list
|
||||
///
|
||||
/// @group x-validation
|
||||
///
|
||||
/// @param {number | list} $span -
|
||||
/// Number of columns, or length of span
|
||||
///
|
||||
/// @return {number | list} -
|
||||
/// Validated `$span` number, length, or columns list
|
||||
///
|
||||
/// @throw
|
||||
/// when span value is not a number, or valid column list
|
||||
@function su-valid-span(
|
||||
$span
|
||||
) {
|
||||
$type: type-of($span);
|
||||
@if ($type == 'number') {
|
||||
@return $span;
|
||||
} @else if ($type == 'list') and su-valid-columns($span, 'silent-failure') {
|
||||
@return $span;
|
||||
}
|
||||
|
||||
$actual: '[#{type-of($span)}] `#{inspect($span)}`';
|
||||
@return _susy-error(
|
||||
'#{$actual} is not a valid number, length, or column-list for $span.',
|
||||
'su-valid-span');
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Valid Columns
|
||||
// -------------
|
||||
/// Check that the `columns` argument is a valid
|
||||
/// list of column-lengths
|
||||
///
|
||||
/// @group x-validation
|
||||
///
|
||||
/// @param {list} $columns -
|
||||
/// List of column-lengths
|
||||
/// @param {bool} $silent-failure [true] -
|
||||
/// Set false to return null on failure
|
||||
///
|
||||
/// @return {list} -
|
||||
/// Validated `$columns` list
|
||||
///
|
||||
/// @throw
|
||||
/// when column value is not a valid list of numbers
|
||||
@function su-valid-columns(
|
||||
$columns,
|
||||
$silent-failure: false
|
||||
) {
|
||||
@if (type-of($columns) == 'list') {
|
||||
$fail: false;
|
||||
|
||||
@each $col in $columns {
|
||||
@if (type-of($col) != 'number') {
|
||||
$fail: true;
|
||||
}
|
||||
}
|
||||
|
||||
@if not $fail {
|
||||
@return $columns;
|
||||
}
|
||||
}
|
||||
|
||||
// Silent Failure
|
||||
@if $silent-failure {
|
||||
@return null;
|
||||
}
|
||||
|
||||
// Error Message
|
||||
$actual: '[#{type-of($columns)}] `#{inspect($columns)}`';
|
||||
|
||||
@return _susy-error(
|
||||
'#{$actual} is not a valid list of numbers for $columns.',
|
||||
'su-valid-columns');
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Valid Gutters
|
||||
// -------------
|
||||
/// Check that the `gutters` argument is a valid number
|
||||
///
|
||||
/// @group x-validation
|
||||
///
|
||||
/// @param {number} $gutters -
|
||||
/// Width of a gutter
|
||||
///
|
||||
/// @return {number} -
|
||||
/// Validated `$gutters` number
|
||||
///
|
||||
/// @throw
|
||||
/// when gutter value is not a number
|
||||
@function su-valid-gutters(
|
||||
$gutters
|
||||
) {
|
||||
$type: type-of($gutters);
|
||||
|
||||
@if ($type == 'number') {
|
||||
@return $gutters;
|
||||
}
|
||||
|
||||
$actual: '[#{$type}] `#{inspect($gutters)}`';
|
||||
@return _susy-error(
|
||||
'#{$actual} is not a number or length for $gutters.',
|
||||
'su-valid-gutters');
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Valid Spread
|
||||
// ------------
|
||||
/// Check that the `spread` argument is a valid
|
||||
/// intiger between `-1` and `1`
|
||||
///
|
||||
/// @group x-validation
|
||||
///
|
||||
/// @param {0 | 1 | -1} $spread -
|
||||
/// Number of gutters to include in a span,
|
||||
/// relative to the number columns
|
||||
///
|
||||
/// @return {0 | 1 | -1} -
|
||||
/// Validated `$spread` number
|
||||
///
|
||||
/// @throw
|
||||
/// when spread value is not a valid spread
|
||||
@function su-valid-spread(
|
||||
$spread
|
||||
) {
|
||||
@if index(0 1 -1, $spread) {
|
||||
@return $spread;
|
||||
}
|
||||
|
||||
$actual: '[#{type-of($spread)}] `#{inspect($spread)}`';
|
||||
@return _susy-error(
|
||||
'#{$actual} is not a normalized [0 | 1 | -1] value for `$spread`.',
|
||||
'su-valid-spread');
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Valid Location
|
||||
// --------------
|
||||
/// Check that the `location` argument is a valid number,
|
||||
/// within the scope of available columns
|
||||
///
|
||||
/// @group x-validation
|
||||
///
|
||||
/// @param {number} $span -
|
||||
/// Number of grid-columns to be spanned
|
||||
/// @param {integer | string} $location -
|
||||
/// Starting (1-indexed) column-position of that span
|
||||
/// @param {list} $columns -
|
||||
/// List of available columns in the grid
|
||||
///
|
||||
/// @return {integer} -
|
||||
/// Validated `$location` intiger
|
||||
///
|
||||
/// @throw
|
||||
/// when location value is not a valid index,
|
||||
/// given the context and span.
|
||||
@function su-valid-location(
|
||||
$span,
|
||||
$location,
|
||||
$columns
|
||||
) {
|
||||
$count: length($columns);
|
||||
|
||||
@if $location {
|
||||
@if (type-of($location) != 'number') or (not unitless($location)) {
|
||||
$actual: '[#{type-of($location)}] `#{$location}`';
|
||||
@return _susy-error(
|
||||
'#{$actual} is not a unitless number for $location.',
|
||||
'su-valid-location');
|
||||
} @else if (round($location) != $location) {
|
||||
@return _susy-error(
|
||||
'Location (`#{$location}`) must be a 1-indexed intiger position.',
|
||||
'su-valid-location');
|
||||
} @else if ($location > $count) or ($location < 1) {
|
||||
@return _susy-error(
|
||||
'Position `#{$location}` does not exist in grid `#{$columns}`.',
|
||||
'su-valid-location');
|
||||
} @else if ($location + $span - 1 > $count) {
|
||||
$details: 'grid `#{$columns}` for span `#{$span}` at `#{$location}`';
|
||||
@return _susy-error(
|
||||
'There are not enough columns in #{$details}.',
|
||||
'su-valid-location');
|
||||
}
|
||||
}
|
||||
|
||||
@return $location;
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
/// Syntax Utilities for Extending Susy
|
||||
/// ===================================
|
||||
/// There are many steps involved
|
||||
/// when translating between the Susy syntax layer,
|
||||
/// and the Su core math.
|
||||
/// That entire process can be condensed with these two functions.
|
||||
/// For anyone that wants to access the full power of Susy,
|
||||
/// and build their own plugins, functions, or mixins –
|
||||
/// this is the primary API for compiling user input,
|
||||
/// and accessing the core math.
|
||||
///
|
||||
/// This is the same technique we use internally,
|
||||
/// to keep our API layer simple and light-weight.
|
||||
/// Every function accepts two arguments,
|
||||
/// a "shorthand" description of the span or context,
|
||||
/// and an optional settings-map to override global defaults.
|
||||
///
|
||||
/// - Use `susy-compile()` to parse, merge, and normalize
|
||||
/// all the user settings into a single map.
|
||||
/// - Then use `su-call()` to call one of the core math functions,
|
||||
/// with whatever data is needed for that function.
|
||||
///
|
||||
/// @group plugin-utils
|
||||
/// @see susy-compile
|
||||
/// @see su-call
|
||||
///
|
||||
/// @example scss - Susy API `gutter` function
|
||||
/// @function susy-gutter(
|
||||
/// $context: susy-get('columns'),
|
||||
/// $config: ()
|
||||
/// ) {
|
||||
/// // compile and normalize all user arguments and global settings
|
||||
/// $context: susy-compile($context, $config, 'context-only');
|
||||
/// // call `su-gutter` with the appropriate data
|
||||
/// @return su-call('su-gutter', $context);
|
||||
/// }
|
||||
///
|
||||
/// @example scss - Sample `span` mixin for floated grids
|
||||
/// @mixin span(
|
||||
/// $span,
|
||||
/// $config: ()
|
||||
/// ) {
|
||||
/// $context: susy-compile($span, $config);
|
||||
/// width: su-call('su-span', $context);
|
||||
///
|
||||
/// @if index($span, 'last') {
|
||||
/// float: right;
|
||||
/// } @else {
|
||||
/// float: left;
|
||||
/// margin-right: su-call('su-gutter', $context);
|
||||
/// }
|
||||
/// }
|
||||
|
||||
|
||||
|
||||
// Compile
|
||||
// -------
|
||||
/// Susy's syntax layer has various moving parts,
|
||||
/// with syntax-parsing for the grid/span shorthand,
|
||||
/// and normalization for each of the resulting values.
|
||||
/// The compile function rolls this all together
|
||||
/// in a single call –
|
||||
/// for quick access from our internal API functions,
|
||||
/// or any additional functions and mixins you add to your project.
|
||||
/// Pass user input and configuration maps to the compiler,
|
||||
/// and it will hand back a map of values ready for Su.
|
||||
/// Combine this with the `su-call` function
|
||||
/// to quickly parse, normalize, and process grid calculations.
|
||||
///
|
||||
/// @group plugin-utils
|
||||
/// @see su-call
|
||||
///
|
||||
/// @param {list | map} $shorthand -
|
||||
/// Shorthand expression to define the width of the span,
|
||||
/// optionally containing:
|
||||
/// - a count, length, or column-list span;
|
||||
/// - `at $n`, `first`, or `last` location on asymmetrical grids;
|
||||
/// - `narrow`, `wide`, or `wider` for optionally spreading
|
||||
/// across adjacent gutters;
|
||||
/// - `of $n <spread>` for available grid columns
|
||||
/// and spread of the container
|
||||
/// (span counts like `of 6` are only valid
|
||||
/// in the context of symmetrical grids);
|
||||
/// - and `set-gutters $n` to override global gutter settings
|
||||
/// @param {map} $config [null] -
|
||||
/// Optional map of Susy grid configuration settings
|
||||
/// @param {bool} $context-only [false] -
|
||||
/// Allow the parser to ignore span and span-spread values,
|
||||
/// only parsing context and container-spread
|
||||
///
|
||||
/// @return {map} -
|
||||
/// Parsed and normalized map of settings,
|
||||
/// based on global and local configuration,
|
||||
/// alongwith shorthad adjustments.
|
||||
///
|
||||
/// @example scss -
|
||||
/// $user-input: 3 wide of susy-repeat(6, 120px) set-gutters 10px;
|
||||
/// $grid-data: susy-compile($user-input, $susy);
|
||||
///
|
||||
/// @each $key, $value in $grid-data {
|
||||
/// /* #{$key}: #{$value}, */
|
||||
/// }
|
||||
@function susy-compile(
|
||||
$short,
|
||||
$config: null,
|
||||
$context-only: false
|
||||
) {
|
||||
// Get and normalize config
|
||||
$config: if($config, susy-settings($config), susy-settings());
|
||||
$normal-config: susy-normalize($config);
|
||||
|
||||
// Parse and normalize shorthand
|
||||
@if (type-of($short) != 'map') and (length($short) > 0) {
|
||||
$short: susy-parse($short, $context-only);
|
||||
}
|
||||
|
||||
$normal-short: susy-normalize($short, $normal-config);
|
||||
|
||||
// Merge and return
|
||||
@return map-merge($normal-config, $normal-short);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Call
|
||||
// ----
|
||||
/// The Susy parsing and normalization process
|
||||
/// results in a map of configuration settings,
|
||||
/// much like the global `$susy` settings map.
|
||||
/// In order to pass that information along to Su math functions,
|
||||
/// the proper values have to be picked out,
|
||||
/// and converted to arguments.
|
||||
///
|
||||
/// The `su-call` function streamlines that process,
|
||||
/// weeding out the unnecessary data,
|
||||
/// and passing the rest along to Su in the proper format.
|
||||
/// Combine this with `susy-compile` to quickly parse,
|
||||
/// normalize, and process grid calculations.
|
||||
///
|
||||
/// @group plugin-utils
|
||||
///
|
||||
/// @require su-span
|
||||
/// @require su-gutter
|
||||
/// @require su-slice
|
||||
/// @see susy-compile
|
||||
///
|
||||
/// @param {'su-span' | 'su-gutter' | 'su-slice'} $name -
|
||||
/// Name of the Su math function to call.
|
||||
/// @param {map} $config -
|
||||
/// Parsed and normalized map of Susy configuration settings
|
||||
/// to use for math-function arguments.
|
||||
///
|
||||
/// @return {*} -
|
||||
/// Results of the function being called.
|
||||
///
|
||||
/// @example scss -
|
||||
/// $user-input: 3 wide of susy-repeat(6, 120px) set-gutters 10px;
|
||||
/// $grid-data: susy-compile($user-input, $susy);
|
||||
///
|
||||
/// .su-span {
|
||||
/// width: su-call('su-span', $grid-data);
|
||||
/// }
|
||||
@function su-call(
|
||||
$name,
|
||||
$config
|
||||
) {
|
||||
$grid-function-args: (
|
||||
'su-span': ('span', 'columns', 'gutters', 'spread', 'container-spread', 'location'),
|
||||
'su-gutter': ('columns', 'gutters', 'container-spread'),
|
||||
'su-slice': ('span', 'columns', 'location'),
|
||||
);
|
||||
|
||||
$args: map-get($grid-function-args, $name);
|
||||
|
||||
@if not $args {
|
||||
$options: 'Try one of these: #{map-keys($grid-function-args)}';
|
||||
@return _susy-error(
|
||||
'#{$name} is not a public Su function. #{$options}',
|
||||
'su-call');
|
||||
}
|
||||
|
||||
$call: if(function-exists('get-function'), get-function($name), $name);
|
||||
$output: ();
|
||||
|
||||
@each $arg in $args {
|
||||
$value: map-get($config, $arg);
|
||||
$output: if($value, map-merge($output, ($arg: $value)), $output);
|
||||
}
|
||||
|
||||
@return call($call, $output...);
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
// Unprefix Susy
|
||||
// =============
|
||||
|
||||
|
||||
// Span
|
||||
// ----
|
||||
/// Un-prefixed alias for `susy-span`
|
||||
/// (available by default)
|
||||
///
|
||||
/// @group api
|
||||
/// @alias susy-span
|
||||
///
|
||||
/// @param {list} $span
|
||||
/// @param {map} $config [()]
|
||||
@function span(
|
||||
$span,
|
||||
$config: ()
|
||||
) {
|
||||
@return susy-span($span, $config);
|
||||
}
|
||||
|
||||
|
||||
// Gutter
|
||||
// ------
|
||||
/// Un-prefixed alias for `susy-gutter`
|
||||
/// (available by default)
|
||||
///
|
||||
/// @group api
|
||||
/// @alias susy-gutter
|
||||
///
|
||||
/// @param {integer | list} $context [null] -
|
||||
/// @param {map} $config [()]
|
||||
@function gutter(
|
||||
$context: susy-get('columns'),
|
||||
$config: ()
|
||||
) {
|
||||
@return susy-gutter($context, $config);
|
||||
}
|
||||
|
||||
|
||||
// Slice
|
||||
// -----
|
||||
/// Un-prefixed alias for `susy-slice`
|
||||
/// (available by default)
|
||||
///
|
||||
/// @group api
|
||||
/// @alias susy-slice
|
||||
///
|
||||
/// @param {list} $span
|
||||
/// @param {map} $config [()]
|
||||
@function slice(
|
||||
$span,
|
||||
$config: ()
|
||||
) {
|
||||
@return susy-slice($span, $config);
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
// Sass Utilities
|
||||
// ==============
|
||||
// - Susy Error Output Override [variable]
|
||||
// - Susy Error [function]
|
||||
|
||||
|
||||
|
||||
// Susy Error Output Override
|
||||
// --------------------------
|
||||
/// Turn off error output for testing
|
||||
/// @group x-utility
|
||||
/// @access private
|
||||
$_susy-error-output-override: false !default;
|
||||
|
||||
|
||||
|
||||
// Susy Error
|
||||
// ----------
|
||||
/// Optionally return error messages without failing,
|
||||
/// as a way to test error cases
|
||||
///
|
||||
/// @group x-utility
|
||||
/// @access private
|
||||
///
|
||||
/// @param {string} $message -
|
||||
/// A useful error message, explaining the problem
|
||||
/// @param {string} $source -
|
||||
/// The original source of the error for debugging
|
||||
/// @param {bool} $override [$_susy-error-output-override] -
|
||||
/// Optionally return the error rather than failing
|
||||
/// @return {string} -
|
||||
/// Combined error with source and message
|
||||
/// @throws When `$override == true`
|
||||
@function _susy-error(
|
||||
$message,
|
||||
$source,
|
||||
$override: $_susy-error-output-override
|
||||
) {
|
||||
@if $override {
|
||||
@return 'ERROR [#{$source}] #{$message}';
|
||||
}
|
||||
|
||||
@error '[#{$source}] #{$message}';
|
||||
}
|
||||
|
||||
|
||||
// Su Is Comparable
|
||||
// ----------------
|
||||
/// Check that the units in a grid are comparable
|
||||
///
|
||||
/// @group x-validation
|
||||
/// @access private
|
||||
///
|
||||
/// @param {numbers} $lengths… -
|
||||
/// Arglist of all the number values to compare
|
||||
/// (columns, gutters, span, etc)
|
||||
///
|
||||
/// @return {'fluid' | 'static' | false} -
|
||||
/// The type of span (fluid or static) when units match,
|
||||
/// or `false` for mismatched units
|
||||
@function _su-is-comparable(
|
||||
$lengths...
|
||||
) {
|
||||
$first: nth($lengths, 1);
|
||||
|
||||
@if (length($lengths) == 1) {
|
||||
@return if(unitless($first), 'fluid', 'static');
|
||||
}
|
||||
|
||||
@for $i from 2 through length($lengths) {
|
||||
$comp: nth($lengths, $i);
|
||||
|
||||
$fail: not comparable($first, $comp);
|
||||
$fail: $fail or (unitless($first) and not unitless($comp));
|
||||
$fail: $fail or (unitless($comp) and not unitless($first));
|
||||
|
||||
@if $fail {
|
||||
@return false;
|
||||
}
|
||||
}
|
||||
|
||||
@return if(unitless($first), 'fluid', 'static');
|
||||
}
|
||||
|
||||
|
||||
// Su Map Add Units
|
||||
// ----------------
|
||||
/// The calc features use a map of units and values
|
||||
/// to compile the proper algorythm.
|
||||
/// This function adds a new value to any comparable existing unit/value,
|
||||
/// or adds a new unit/value pair to the map
|
||||
///
|
||||
/// @group x-utility
|
||||
/// @access private
|
||||
///
|
||||
/// @param {map} $map -
|
||||
/// A map of unit/value pairs, e.g. ('px': 120px)
|
||||
/// @param {length} $value -
|
||||
/// A new length to be added to the map
|
||||
/// @return {map} -
|
||||
/// The updated map, with new value added
|
||||
///
|
||||
/// @example scss -
|
||||
/// $map: (0px: 120px);
|
||||
/// $map: _su-map-add-units($map, 1in); // add a comparable unit
|
||||
/// $map: _su-map-add-units($map, 3vw); // add a new unit
|
||||
///
|
||||
/// @each $units, $value in $map {
|
||||
/// /* #{$units}: #{$value} */
|
||||
/// }
|
||||
@function _su-map-add-units(
|
||||
$map,
|
||||
$value
|
||||
) {
|
||||
$unit: $value * 0;
|
||||
$has: map-get($map, $unit) or 0;
|
||||
|
||||
@if ($has == 0) {
|
||||
@each $try, $could in $map {
|
||||
$match: comparable($try, $value);
|
||||
$unit: if($match, $try, $unit);
|
||||
$has: if($match, $could, $has);
|
||||
}
|
||||
}
|
||||
|
||||
@return map-merge($map, ($unit: $has + $value));
|
||||
}
|
||||
|
||||
|
||||
// Susy Flatten
|
||||
// ------------
|
||||
/// Flatten a multidimensional list
|
||||
///
|
||||
/// @group x-utility
|
||||
/// @access private
|
||||
///
|
||||
/// @param {list} $list -
|
||||
/// The list to be flattened
|
||||
/// @return {list} -
|
||||
/// The flattened list
|
||||
///
|
||||
/// @example scss -
|
||||
/// $list: 120px (30em 30em) 120px;
|
||||
/// /* #{_susy-flatten($list)} */
|
||||
@function _susy-flatten(
|
||||
$list
|
||||
) {
|
||||
$flat: ();
|
||||
|
||||
// Don't iterate over maps
|
||||
@if (type-of($list) == 'map') {
|
||||
@return $list;
|
||||
}
|
||||
|
||||
// Iterate over lists (or single items)
|
||||
@each $item in $list {
|
||||
@if (type-of($item) == 'list') {
|
||||
$item: _susy-flatten($item);
|
||||
$flat: join($flat, $item);
|
||||
} @else {
|
||||
$flat: append($flat, $item);
|
||||
}
|
||||
}
|
||||
|
||||
// Return flattened list
|
||||
@return $flat;
|
||||
}
|
Loading…
Reference in New Issue