Reputation:
I wanted to use a Scss solution to easily modify styles on a website with multiple branded sub sites. My aim was to get arrays for elements (classes, ids, tags) which share styling properties and just have those arrays to be edited when adjusting brand styles.
I came up with the following solution which works fine, however... Couldn't the following be done in a smarter way? i.e. less chunks of "$array... + $all.. + @each"? Hope you know what I mean when you see my current syntax:
// All elements with background colors
$arrayElementsWithBackgroundColor: (
'.example-1',
'.example-2' // etc.
);
$allElementsWithBackgroundColor: ();
@each $item in $arrayElementsWithBackgroundColor {
$allElementsWithBackgroundColor: append($allElementsWithBackgroundColor, unquote('#{$item}'), 'comma');
};
// All elements with background gradients
$arrayElementsWithBackgroundColorGradient: (
'.example-3',
'.example-4' // etc.
);
$allElementsWithBackgroundColorGradient: ();
@each $item in $arrayElementsWithBackgroundColorGradient {
$allElementsWithBackgroundColorGradient: append($allElementsWithBackgroundColorGradient, unquote('#{$item}'), 'comma');
};
// All elements with semi-transparent background colors
$arrayElementsWithBackgroundColorSemiTransparent: (
'.example-5',
'.example-6' // etc.
);
$allElementsWithBackgroundColorSemiTransparent: ();
@each $item in $arrayElementsWithBackgroundColorSemiTransparent {
$allElementsWithBackgroundColorSemiTransparent: append($allElementsWithBackgroundColorSemiTransparent, unquote('#{$item}'), 'comma');
};
// All elements with border colors
$arrayElementsWithBorderColor: (
'.example-7',
'.example-8' // etc.
);
$allElementsWithBorderColor: ();
@each $item in $arrayElementsWithBorderColor {
$allElementsWithBorderColor: append($allElementsWithBorderColor, unquote('#{$item}'), 'comma');
};
// All elements with text colors
$arrayElementsWithTextColor: (
'.example-9',
'.example-10' // etc.
);
$allElementsWithTextColor: ();
@each $item in $arrayElementsWithTextColor {
$allElementsWithTextColor: append($allElementsWithTextColor, unquote('#{$item}'), 'comma');
};
Those chunks are where I collect my arrays of elements to be branded. Afterwards I'm using those like this:
body {
@at-root #{&}.brand-1 {
#{$allElementsWithBackgroundColor} { background: $brand-1; }
#{$allElementsWithBackgroundColorGradient} { background: $brand-1-gradient; }
#{$allElementsWithBackgroundColorSemiTransparent} { background: rgba($brand-1,0.8); }
#{$allElementsWithBorderColor} { border-color: $brand-1; }
#{$allElementsWithTextColor} { color: $brand-1; }
}
@at-root #{&}.brand-2 {
#{$allElementsWithBackgroundColor} { background: $$brand-2; }
#{$allElementsWithBackgroundColorGradient} { background: $$brand-2-gradient; }
#{$allElementsWithBackgroundColorSemiTransparent} { background: rgba($$brand-2,0.8); }
#{$allElementsWithBorderColor} { border-color: $$brand-2; }
#{$allElementsWithTextColor} { color: $$brand-2; }
}
@at-root #{&}.brand-3 {
#{$allElementsWithBackgroundColor} { background: $brand-3; }
#{$allElementsWithBackgroundColorGradient} { background: $brand-3-gradient; }
#{$allElementsWithBackgroundColorSemiTransparent} { background: rgba($brand-3,0.8); }
#{$allElementsWithBorderColor} { border-color: $brand-3; }
#{$allElementsWithTextColor} { color: $brand-3; }
}
@at-root #{&}.brand-4 {
#{$allElementsWithBackgroundColor} { background: $brand-4; }
#{$allElementsWithBackgroundColorGradient} { background: $brand-4-gradient; }
#{$allElementsWithBackgroundColorSemiTransparent} { background: rgba($brand-4-alt,0.8); }
#{$allElementsWithBorderColor} { border-color: $brand-4; }
#{$allElementsWithTextColor} { color: $brand-4; }
}
}
Upvotes: 0
Views: 97
Reputation: 4936
You could consider using maps – like:
// _brands.scss
$brand-1: red;
$brand-2: green;
$brand-3: orange;
$brand-4: blue;
$brand-1-gradient: linear-gradient(to top, red, red);
$brand-2-gradient: linear-gradient(to top, green, green);
$brand-3-gradient: linear-gradient(to top, orange, orange);
$brand-4-gradient: linear-gradient(to top, blue, blue);
$brands: (
brand-1 : (
// note! you can add more properties to each style map
'.example-1, .example-2': (background: $brand-1, color: magenta ),
'.example-3, .example-4': (background: $brand-1-gradient ),
'.example-5, .example-6': (background: rgba($brand-1, 0.8) ),
'.example-7, .example-8': (border-color: $brand-1 ),
'.example-9, .example-10': (color: $brand-1 )
),
brand-2 : (
'.example-1, .example-2': (background: $brand-2 ),
'.example-3, .example-4': (background: $brand-2-gradient ),
'.example-5, .example-6': (background: rgba($brand-2, 0.8) ),
'.example-7, .example-8': (border-color: $brand-2 ),
'.example-9, .example-10': (color: $brand-2 )
),
brand-3 : (
'.example-1, .example-2': (background: $brand-3 ),
'.example-3, .example-4': (background: $brand-4-gradient ),
'.example-5, .example-6': (background: rgba($brand-3, 0.8) ),
'.example-7, .example-8': (border-color: $brand-3 ),
'.example-9, .example-10': (color: $brand-3 )
),
brand-4 : (
'.example-1, .example-2': (background: $brand-4 ),
'.example-3, .example-4': (background: $brand-4-gradient ),
'.example-5, .example-6': (background: rgba($brand-4, 0.8) ),
'.example-7, .example-8': (border-color: $brand-4 ),
'.example-9, .example-10': (color: $brand-4 )
)
);
// brands.scss
@import '_brands.scss'
body {
@each $brand, $selectors in $brands {
@at-root #{&}.#{$brand} {
@each $selector, $style in $selectors {
#{$selector}{
@each $property, $value in $style {
#{$property}: $value;
}
}
}
}
}
}
You could also chose to split each brand into individual stylesheets using a mixin
// add to _brand.scss
@mixin brand($brand-name) {
body {
@at-root #{&}.#{$brand-name} {
@each $selector, $style in map-get($brands, $brand-name) {
#{$selector}{
@each $property, $value in $style {
#{$property}: $value;
}
}
}
}
}
}
// brand1.scss
@import '_brands.scss';
@include brand(brand-1);
// brand2.scss
@import '_brands.scss';
@include brand(brand-2);
// brand3.scss
@import '_brands.scss';
@include brand(brand-3);
// brand4.scss
@import '_brands.scss';
@include brand(brand-4);
Upvotes: 1