Reputation: 3265
I have a sass mixin for box-shadow which looks like this:
@mixin box-shadow($hLength, $vLength, $blur, $spread, $colour, $type:""){
@if $type != "" {
-webkit-box-shadow:$type $hLength $vLength $blur $spread $colour;
-moz-box-shadow:$type $hLength $vLength $blur $spread $colour;
box-shadow:$type $hLength $vLength $blur $spread $colour;
}
}
This has worked fine for most of my application.
However I now need to modify my method somehow.
I have list items which can have one of 11 classes, this class controls the colour and icon of the list item.
Examples of my variables:
$channel1: #19BC9C;
$channel2: #F1C40E;
$channel3: #9B59B6;
$channel4: #3398DB;
And my sass for the list items looks like this:
li {
&.channel1 {
@include box-shadow(-3px, 0px, 0px, 0px, $channel1, inset);
}
&.channel2 {
@include box-shadow(-3px, 0px, 0px, 0px, $channel2, inset);
}
}
The problem is that the px values and inset are the same for each class element. However there is no property for box-shadow-color, so I cannot split the parameters up.
I was hoping I could store -3px, 0px, 0px, 0px in a separate variable and pass that in.
@include box-shadow($channelBorder, $channel1, inset);
etc, but this does not work.
Does anyone know if there is a decent solution, I would rather keep my mixin as it is, as much as possible.
Upvotes: 0
Views: 4337
Reputation: 68309
One would typically solve this problem by using default values on a mixin and only specifying the exact values you wish to modify:
$default-hLength: -3px !default;
$default-vLength: 0 !default;
$default-blur: 0 !default;
$default-spread: null !default;
$default-colour: null !default;
$default-type: null !default;
@mixin box-shadow($hLength: $default-hLength, $vLength: $default-vLength, $blur: $default-blur, $spread: $default-spread, $colour: $default-colour, $type: $default-type){
-webkit-box-shadow: $type $hLength $vLength $blur $spread $colour;
-moz-box-shadow: $type $hLength $vLength $blur $spread $colour;
box-shadow: $type $hLength $vLength $blur $spread $colour;
}
li {
&.channel1 {
@include box-shadow($colour: $channel1, $type: inset);
}
&.channel2 {
@include box-shadow($colour: $channel2, $type: inset);
}
}
Alternately, you can store portions of your arguments as a list and expand them when calling your mixin:
li {
$vals1: -3px 0 0 0;
$vals3: -3px 0 0 0 black inset;
&.channel1 {
// option 1
@include box-shadow($vals1..., $colour: $channel1, $type: inset);
// option 2
@include box-shadow(join($vals1, ($channel1, inset))...);
// option 3
@include box-shadow(set-nth($vals3, 5, $channel1)...);
}
&.channel2 {
// option 1
@include box-shadow($vals1..., $colour: $channel2, $type: inset);
// option 2
@include box-shadow(join($vals1, ($channel2, inset))...);
// option 3
@include box-shadow(set-nth($vals3, 5, $channel2)...);
}
}
However, you're never going to be satisfied with a mixin like that because it only assumes that you're going to have a single box-shadow, but the property allows for multiples.
It would be by far simpler for you in the long run if you could loop through the values you want and call a more robust mixin:
@mixin box-shadow($values...) {
-webkit-box-shadow: $values;
-moz-box-shadow: $values;
box-shadow: $values;
}
li {
$colours: $channel1, $channel2, $channel3, $channel4;
@for $i from 1 through length($colours) {
&.channel#{$i} {
@include box-shadow(inset -3px 0 0 0 nth($colours, $i));
}
}
}
Upvotes: 1