Skip to content

Instantly share code, notes, and snippets.

@Undistraction
Last active August 29, 2015 14:07
Show Gist options
  • Save Undistraction/7143b3ade0cd29cad6b2 to your computer and use it in GitHub Desktop.
Save Undistraction/7143b3ade0cd29cad6b2 to your computer and use it in GitHub Desktop.
Generated by SassMeister.com.
// ----
// Sass (v3.4.4)
// Compass (v1.0.1)
// ----
// What / Why?
// 1. Allow people to use constants for box-values. for example 'single' 'half',
// 'third' etc.
// 2. Link these values to vertical and horizontal rhythm
// properties (to allow adjustments for optical distortion)
// 3. Make rhythm units breakpoint-specific – Push all box-model property setting
// through an API so that these constants can be adjusted automatically at
// breakpoints, for example `single` will always be a single rhythm unit, but at
// default, that unit might be 10px, and at a $medium breakpoint, that might be 14px.
// Box – Mixins
// -------------------------------------------------------------------------
// Pass in a map
@mixin box($map) {
@each $key, $value in $map {
#{$key}: #{box-process-arbitrary-value($key, $value)};
}
}
// Margin
@mixin margin($value) {
$value: box-process-multiple-values($value);
margin: #{$value};
}
@mixin margin-top($value) {
$value: box-process-single-value($value, vertical);
margin-top: #{$value};
}
@mixin margin-right($value) {
$value: box-process-single-value($value, horizontal);
margin-right: #{$value};
}
@mixin margin-bottom($value) {
$value: box-process-single-value($value, vertical);
margin-bottom: #{$value};
}
@mixin margin-left($value) {
$value: box-process-single-value($value, horizontal);
margin-left: #{$value};
}
// Padding
@mixin padding($value) {
$value: box-process-multiple-values($value);
padding: #{$value};
}
@mixin padding-top($value) {
$value: box-process-single-value($value, vertical);
padding-top: #{$value};
}
@mixin padding-right($value) {
$value: box-process-single-value($value, horizontal);
padding-right: #{$value};
}
@mixin padding-bottom($value) {
$value: box-process-single-value($value, vertical);
padding-bottom: #{$value};
}
@mixin padding-left($value) {
$value: box-process-single-value($value, horizontal);
padding-left: #{$value};
}
// Border
@mixin border($value) {
$value: box-process-multiple-values($value);
border: #{$value};
}
@mixin border-top($value) {
$value: box-process-single-value($value, vertical);
border-top: #{$value};
}
@mixin border-right($value) {
$value: box-process-single-value($value, horizontal);
border-right: #{$value};
}
@mixin border-bottom($value) {
$value: box-process-single-value($value, vertical);
border-bottom: #{$value};
}
@mixin border-left($value) {
$value: box-process-single-value($value, horizontal);
border-left: #{$value};
}
// Box – Support
// -------------------------------------------------------------------------
$box-valid-unitless-values: auto initial inherit 0;
$box-valid-multi-arguments: margin padding border;
$box-valid-single-arguments: margin-top
margin-right
margin-bottom
margin-left
padding-top
padding-right
padding-bottom
padding-left
border-top
border-right
border-bottom
border-left;
$box-valid-arguments: join($box-valid-multi-arguments, $box-valid-single-arguments);
@function box-process-arbitrary-value($key, $value) {
@if box-is-valid-property($key) {
@if box-is-single-property($key) {
@if length($value) == 1 {
$orientation: box-orientation-of-property($key);
@return box-process-single-value($value, $orientation);
} @else {
@error "#{$key} only supports a single value, but value was `#{$value}`";
}
} @else {
@return box-process-multiple-values($value);
}
} @else {
@error "#{$key} is not a supported value";
}
}
// Process value if it isn't already a valid number
@function box-process-single-value($value, $orientation) {
@if box-should-parse-value($value) {
$value: box-parse-value-filter($value, $orientation);
}
@return $value;
}
@function box-process-multiple-values($values) {
$values: box-process-to-four-values($values);
$processed-values: ();
$orientation: null;
@for $i from 1 through length($values) {
$value: nth($values, $i);
@if even($i) {
$orientation: horizontal;
} @else {
$orientation: vertical;
}
@if box-should-parse-value($value) {
$value: box-parse-value-filter($value, $orientation);
}
$processed-values: append($processed-values, $value);
}
@return $processed-values;
}
// Process all value lists to four values to make processing easy.
@function box-process-to-four-values($values) {
$length: length($values);
// Convert all values to 4 values
@if $length < 4 {
@if length($values) == 3 {
// (T,L+R,B) We need to add the 2nd prop again as the last prop
$values: append($values, nth($values, 2));
} @else if $length == 2 {
// (T+B, L+R) We need to duplicate
$values: join($values, $values);
} @else {
// (T+R+B+L) We need to duplicate 4 times
$values: append( append(append($values, nth($values, 1)), nth($values, 1)), nth($values, 1));
}
}
@return $values;
}
// 1. Check if the value maps to one of our keywords and if so, swap out the value
// This is just a hook to be overridden. By default we just pass back the value
@function box-parse-value-filter($value, $orientation){
@error "Unsupported value #{$value}";
}
// Check if value is even
@function even($number) {
@return $number % 2 == 0;
}
@function box-should-parse-value($value) {
@return not( box-is-number-with-unit($value)
or box-is-valid-unitless($value)
or box-is-calc($value));
}
@function box-is-calc($value) {
@return str-slice($value + "", 1, 4) == "calc";
}
@function box-is-valid-unitless($value) {
@return not not index($box-valid-unitless-values, $value);
}
@function box-is-number-with-unit($value) {
@return (type-of($value) == number and not unitless($value));
}
@function box-is-valid-property($value) {
@return not not index($box-valid-arguments, $value);
}
@function box-is-single-property($value) {
@return not not index($box-valid-single-arguments, $value);
}
@function box-orientation-of-property($value) {
$direction: str-slice($value, str-index($value, '-')+1);
@if not not index(left right, $direction) {
@return horizontal;
} @else {
@return vertical;
}
}
// Test Defaults
// -------------------------------------------------------------------------
/* Defaults */
.Default-padding-top {
@include padding-top(10px);
}
.Default-padding-right {
@include padding-right(10px);
}
// APP
// -------------------------------------------------------------------------
$rhythm-units-map: (
single: 1,
double: 2,
triple: 3,
quadruple: 4,
half: 0.5,
third: 0.33333333333,
quarter: 0.25
);
$rhythm-map: (
vertical: 12px,
horizontal: 16px
);
// If the value isn't a united number or a known keyword, look up the keyword
// in the $rhythm-units-map (which will resolve to a unitless number)
@function box-parse-value-filter($key, $orientation){
@if map-has-key($rhythm-units-map, $key) {
$unit: map-get($rhythm-units-map, $key);
@return map-get($rhythm-map, $orientation) * $unit;
} @else {
@error "Unsupported key #{$key}";
}
}
// Test Custom
// -------------------------------------------------------------------------
/* Custom */
.box {
@include box(
(
margin: single 10px half,
padding: half,
border-right: 1px
)
);
}
.box-with-specific {
@include box(
(
margin: single,
padding: half,
border-top: 1px
)
);
}
.padding-top {
@include padding-top(auto);
}
.padding-bottom {
@include padding-top(calc(50%+4px));
}
.padding-right {
@include padding-right(single);
}
.padding-one-arg {
@include padding(single);
}
.padding-two-args {
@include padding(single double);
}
.padding-three-args {
@include padding(single double auto);
}
.padding-four-args {
@include padding(single double triple half);
}
/* Defaults */
.Default-padding-top {
padding-top: 10px;
}
.Default-padding-right {
padding-right: 10px;
}
/* Custom */
.box {
margin: 12px 10px 6px 10px;
padding: 6px 8px 6px 8px;
border-right: 1px;
}
.box-with-specific {
margin: 12px 16px 12px 16px;
padding: 6px 8px 6px 8px;
border-top: 1px;
}
.padding-top {
padding-top: auto;
}
.padding-bottom {
padding-top: calc(50%+4px);
}
.padding-right {
padding-right: 16px;
}
.padding-one-arg {
padding: 12px 16px 12px 16px;
}
.padding-two-args {
padding: 12px 32px 12px 32px;
}
.padding-three-args {
padding: 12px 32px auto 32px;
}
.padding-four-args {
padding: 12px 32px 36px 8px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment