Skip to content

Instantly share code, notes, and snippets.

@sgregson
Last active August 29, 2015 14:07
Show Gist options
  • Save sgregson/2288ce8a1eafd5354f7e to your computer and use it in GitHub Desktop.
Save sgregson/2288ce8a1eafd5354f7e to your computer and use it in GitHub Desktop.
SCSS Configuration Objects
// ----
// Sass (v3.4.9)
// Compass (v1.0.1)
// Sassy Maps (v0.4.0)
// ----
@import "sassy-maps";
////
/// @author Pedr Browne
/// @group support
////
/// Perform a deep merge of two maps, optionally overwriting existing values.
/// Note: I have a PR open adding this to Sassy maps
///
/// @param {Map} $map-old
/// The map to merge to.
///
/// @param {Map} $map-new
/// The map to merge into `$map-old`
///
/// @param {Bool} $overwrite (true)
/// How should the merge deal with existing values? If true, any existing values will be
/// Overwritten. If false, existing values will be preserved. The logic handling overwriting
/// Will fully recurse the map, so merging is based on path rather than node.
///
/// @return {Map}
/// A new map resulting from the merge of `$map-old` and `$map-new`.
///
@function map-merge-deep($map-old, $map-new, $overwrite: true) {
// Iterate through each value of the new map
@each $key, $new-value in $map-new {
// Check if that value already exists on the old map
@if map-has-key($map-old, $key) {
// There is an existing key
$old-value: map-get($map-old, $key);
@if type-of($new-value) == map and type-of($old-value) == map {
// If both are maps, recurse regardless of $overwrite
$merged-value: map-merge-deep($old-value, $new-value);
$map-old: map-set($map-old, $key, $merged-value);
}@else{
// Otherwise check $overwrite
@if $overwrite{
$map-old: map-set($map-old, $key, $new-value);
}
}
}@else{
// There is no existing key so add
$map-old: map-set($map-old, $key, $new-value);
}
}
@return $map-old;
}
//////////////////////////////////////////////////////////////////////////////
// Based on http://hugogiraudel.com/2014/05/05/bringing-configuration-objects-to-sass/
// a modular way to build partials with signatures
//////////////////////////////////////////////////////////////////////////////
//VARIABLES FILE
$primary: #0072BC;
//////////////////////GLOBALS FILE//////////////////////////////////////////////
// The output should be different
// currently:
// overwrites instead of merging any root-level keys in $base that exist in $ext
// uses $base value for any root-level keys that don't exist in $ext
@function extend($base, $ext) {
//include the scope of the @include statement, to allow mixin to function within a parent selector
$ext: map-merge($ext, ('scope': #{&}));
@return map-merge-deep($base, $ext);
}
@mixin config($conf) {
$scope: if(map-get($conf, 'scope') != '', str-length(map-get($conf, 'scope')), 0 );
$sel: if($scope > 0, str-slice(#{&}, $scope+2), #{&});
@each $k, $v in map-get($conf, $sel) {
// use leading underscore to create duplicate selector, useful for IE hacks
// try to have first @if be the most common case to decrease compile time dramatically
@if not (str-index(#{$k}, '_') == 1) {
@if (str-index(#{$k}, '@include') == 1) {
/*check yourself*/
}
#{$k}: #{$v};
}
@else { #{str-slice($k, 2)}: #{$v}; }
}
}
@mixin box_sizing($type) {
-webkit-box-sizing: $type;
-moz-box-sizing: $type;
box-sizing: $type;
}
//////////////////////PARTIALS FILE/////////////////////////////////////////////
@mixin topnav-mainsearch($conf:()) {
$conf: extend((
'input.search': (
padding: (30px 0 10px),
width: null,
margin-top: 2px,
outline: none,
),
'.search .btn_search': (
position: absolute,
top: 0,
right: 0
)), $conf);
input.search {
@include config($conf);
//Layout function included as default for all page variations
// these can't be incorporated into the mixin signature until
// mixins are made into first-class data structures
// The dream: '@include_1': (box_sizing, $type:border-box), '@include_2' etc
// https://github.com/sass/sass/issues/626
@include box_sizing($type:border-box);
}
.search .btn_search {
@include config($conf);
}
}
//////////////////////PAGE FILE VARIATIONS//////////////////////////////////////
/**********************************
VARIATION 1: PARAMETERLESS
*/
@include topnav-mainsearch();
/**********************************
VARIATION 2: KILLING A SELECTOR
'null' removes .search .btn_search {...}
*/
@include topnav-mainsearch((
'.search .btn_search': null
));
/**********************************
VARIATION 3: PARTIAL OVERWRITE
.search .btn_search {
margin: (20px 6px 0 0),
right: null
}
*/
.other a.parent {
@include topnav-mainsearch((
'.search .btn_search': (
margin: (20px 6px 0 0),
right: null
)
));
}
/**********************************
VARIATION 4: DEEP EXTENSION
* both are extended
* duplicate selector enabled with underscore prefix
* star-hack possible with quoted value
*/
@include topnav-mainsearch((
"input.search": (
padding: (6px 0 6px 10px),
width: 1px,
'_width': '3px\\9 /*ie-hack*/',
'*width': 2px,
border-color: $primary
),
'.search .btn_search': (
margin: (8px 6px 0 0)
)
));
/**********************************
VARIATION 1: PARAMETERLESS
*/
input.search {
padding: 30px 0 10px;
margin-top: 2px;
outline: none;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.search .btn_search {
position: absolute;
top: 0;
right: 0;
}
/**********************************
VARIATION 2: KILLING A SELECTOR
'null' removes .search .btn_search {...}
*/
input.search {
padding: 30px 0 10px;
margin-top: 2px;
outline: none;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
/**********************************
VARIATION 3: PARTIAL OVERWRITE
.search .btn_search {
margin: (20px 6px 0 0),
right: null
}
*/
.other a.parent input.search {
padding: 30px 0 10px;
margin-top: 2px;
outline: none;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.other a.parent .search .btn_search {
position: absolute;
top: 0;
margin: 20px 6px 0 0;
}
/**********************************
VARIATION 4: DEEP EXTENSION
* both are extended
* duplicate selector enabled with underscore prefix
* star-hack possible with quoted value
*/
input.search {
padding: 6px 0 6px 10px;
width: 1px;
margin-top: 2px;
outline: none;
width: 3px\9 /*ie-hack*/;
*width: 2px;
border-color: #0072BC;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.search .btn_search {
position: absolute;
top: 0;
right: 0;
margin: 8px 6px 0 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment