Last active
April 23, 2017 20:20
-
-
Save kgcreative/820db39fc32bbe4997ec426067712113 to your computer and use it in GitHub Desktop.
Element System in SCSS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@charset 'UTF-8'; | |
//// | |
/// Smart merge | |
/// @author Kevin Garcia | |
//// | |
/// Returns a merged map, a single map, or a null value, depending on the results of the function's operations | |
/// | |
/// @param {map} default-map - The default map the mixin consumes | |
/// @param {map} map [null] - The optional override map to merge in | |
/// | |
/// @example scss - SCSS | |
/// $map--default: ( | |
/// property1: value1, | |
/// property2: value2, | |
/// property3: value3, | |
/// // etc... | |
/// )!default; | |
/// | |
/// $my-new-map: ( | |
/// property1: my-value1, | |
/// property3: null, // By explicitly declaring a | |
/// // null value in the merged map, | |
/// // we can suppress this property | |
/// my-new-property: my-new-value, | |
/// // etc... | |
/// ); | |
/// | |
/// $merged-map: smart-merge($map--default, $my-new-map); | |
/// | |
/// | |
/// @example scss - Merged SCSS Map | |
/// $merged-map: ( | |
/// property1: my-value1, | |
/// property2: value2, | |
/// my-new-property: my-new-value, | |
/// // etc... | |
/// ); | |
/// | |
@function smart-merge($default-map, $map) { | |
@if $map { | |
@if $default-map { | |
@return map-merge($default-map, $map); | |
} @else { | |
@return $map; | |
} | |
} @else { | |
@if $default-map { | |
@return $default-map; | |
} @else { | |
@warn 'Could not return map.'; | |
@return false; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@charset "UTF-8"; | |
//// | |
/// Nested properties | |
/// @author Kevin Garcia | |
//// | |
/// | |
/// Returns a list of recursively nested `$property`: `$value` pairs. | |
/// The mixin will continue to iterate as long as any map value is a nested map. | |
/// | |
/// @param {css property} $_property - The CSS Property | |
/// @param {css value | map} $_value - The CSS Value the property contains, or, if a map, the properties of the nested selector. | |
/// | |
/// @access private | |
@mixin _nested-properties($_property, $_value) { | |
@if type-of($_value) == map { | |
#{$_property} { | |
@each $_nested-property, $_nested-value in $_value { | |
@if type-of($_nested-value) == map { | |
@include _nested-properties($_nested-property, $_nested-value); | |
} @else { | |
#{$_nested-property}: #{$_nested-value}; | |
} | |
} | |
} | |
} @else { | |
#{$_property}: #{$_value}; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@charset 'UTF-8'; | |
//// | |
/// Properties | |
/// @author Kevin Garcia | |
//// | |
/// Returns a list of `$property`: `$value` pairs | |
/// | |
/// @param {map} default-settings - The default map the mixin consumes | |
/// @param {map} settings [null] - The optional override map to merge in | |
/// | |
/// @example scss - source SCSS | |
/// $default-map: ( | |
/// color: blue, | |
/// margin: 0 auto, | |
/// ); | |
/// | |
/// $map-override: ( | |
/// color: red, | |
/// overflow: hidden, | |
/// ); | |
/// | |
/// .default-element { | |
/// @include properties($default-map); | |
/// } | |
/// | |
/// .override-element { | |
/// @include properties($map-override); | |
/// } | |
/// | |
/// .merged-element { | |
/// @include properties($default-map, $map-override); | |
/// } | |
/// | |
/// @example css - output CSS | |
/// | |
/// .default-element { | |
/// color: blue; | |
/// margin: 0 auto; | |
/// } | |
/// | |
/// .override-element: { | |
/// color: red; | |
/// overflow: hidden; | |
/// }; | |
/// | |
/// .merged-element { | |
/// color: red; | |
/// margin: 0 auto; | |
/// overflow: hidden; | |
/// } | |
/// | |
/// @example scss - When to use default + merged elements (scss) | |
/// | |
/// // The main use case is when one wants to output variations of an element. | |
/// | |
/// $default-button: ( | |
/// background-color: #333333, | |
/// color: white, | |
/// margin: 0 auto, | |
/// padding: 1em, | |
/// ); | |
/// | |
/// $blue-button: ( | |
/// background-color: blue, | |
/// ); | |
/// | |
/// // You can pass it a default map | |
/// .button { | |
/// @include element-properties($default-button); | |
/// } | |
/// | |
/// // You can pass it a named map | |
/// .button--blue { | |
/// @include element-properties($default-button, $blue-button); | |
/// } | |
/// | |
/// // You may also pass it an inline map | |
/// .button--green { | |
/// @include element-properties($default-button, (font-size: 1.125em, background-color: green, color: inherit, margin: null, )); | |
/// } | |
/// | |
/// @example css - When to use default + merged elements (output) | |
/// | |
/// .button: { | |
/// background-color: #333333; | |
/// color: white; | |
/// margin: 0 auto; | |
/// padding: 1em; | |
/// }; | |
/// | |
/// .button--blue: ( | |
/// background-color: blue; | |
/// color: white; | |
/// margin: 0 auto; | |
/// padding: 1em; | |
/// ); | |
/// | |
/// /* Notice that explicitly null values in overrides are removed from the output */ | |
/// .button--green: ( | |
/// background-color: green; /* <- overriden value */ | |
/// color: inherit; /* <- overriden value */ | |
/// padding: 1em; /* <- Notice that the margin property is gone. */ | |
/// font-size: 1.125em /* <- values not present in the default map are amended to the end */ | |
/// ); | |
/// | |
/// | |
/// @requires [function] smart-merge | |
/// @requires [mixin] _nested-properties | |
/// | |
@mixin properties($default-settings, $settings: null) { | |
$_settings: smart-merge($default-settings, $settings); | |
@each $_property, $_value in $_settings { | |
@include _nested-properties($_property, $_value); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@charset "UTF-8"; | |
//// | |
/// Element | |
/// @author Kevin Garcia | |
//// | |
/// | |
/// Returns an element with property:value pairs based on a map. If no maps are available, it outputs it's own @content | |
/// @content | |
/// | |
/// @param {selector} $element - The CSS selector that the property map applies to | |
/// @param {map} default-settings [null] - The default map the mixin consumes | |
/// @param {map} settings [null] - The optional override map to merge in | |
/// | |
/// | |
/// @example scss - source SCSS | |
/// $default-map: ( | |
/// color: blue, | |
/// margin: 0 auto, | |
/// ); | |
/// | |
/// $map-override: ( | |
/// color: red, | |
/// overflow: hidden, | |
/// '&:after': ( | |
/// content: '"pseudo element"', | |
/// display: block, | |
/// ) | |
/// ); | |
/// | |
/// | |
/// @include ('.element', $default-map, $map-override); | |
/// | |
/// @example css - output CSS | |
/// .element { | |
/// color: red; | |
/// margin: 0 auto; | |
/// overflow: hidden; | |
/// } | |
/// | |
/// .element:after { | |
/// content: "pseudo element"; | |
/// display: block; | |
/// } | |
/// | |
/// @requires {mixin} element-properties | |
@mixin element($element, $default-settings: null, $settings: null) { | |
$_settings: smart-merge($default-settings, $settings); | |
#{$element} { | |
@if ($_settings == null) { | |
@warn '$_settings map returned a null value. Attempting to use @content instead'; | |
@content; | |
} @else { | |
@include properties($default-settings, $settings); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@charset "UTF-8"; | |
//// | |
/// Element group | |
/// @author Kevin Garcia | |
//// | |
/// | |
/// Returns a group of configurable elements based on a map. | |
/// | |
/// @param {map} $element-group - The element map the mixin consumes | |
/// | |
/// @example scss - SCSS | |
/// $default-element: ( | |
/// background-color: purple, | |
/// margin-left: auto, | |
/// margin-right: auto, | |
/// margin-bottom: 2em, | |
/// display: inline, | |
/// ); | |
/// | |
/// $element-a: ( | |
/// background-color: green, | |
/// ); | |
/// | |
/// $element-b: ( | |
/// display: block, | |
/// margin-left: null, | |
/// margin-right: null, | |
/// ); | |
/// | |
/// $element-c: ( | |
/// display: null, | |
/// overflow: hidden, | |
/// ); | |
/// | |
/// $group-1: ( | |
/// '#test-a': (default-settings: $default-element, settings: $element-a), | |
/// '#test-b': (default-settings: $default-element, settings: $element-b), | |
/// '#test-c': (default-settings: $element-c), | |
/// ); | |
/// | |
/// @include element-group($group-1); | |
/// | |
/// @example css - CSS output | |
/// | |
/// #test-a { | |
/// background-color: green; | |
/// margin-left: auto; | |
/// margin-right: auto; | |
/// margin-bottom: 2em; | |
/// display: inline; | |
/// } | |
/// | |
/// #test-b { | |
/// background-color: purple; | |
/// margin-bottom: 2em; | |
/// display: block; | |
/// } | |
/// | |
/// #test-c { | |
/// overflow: hidden; | |
/// } | |
/// | |
/// @requires {mixin} element | |
@mixin elements($elements) { | |
@each $element, $map in $elements { | |
$_default-settings: map-get($map, default-settings); | |
$_settings: map-get($map, settings); | |
@include element($element, $_default-settings, $_settings); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment