Reputation: 3416
Say you have a bunch of variables like so:
/* spacing */
$spacing-extra-small: 0.25rem;
$spacing-small: 0.5rem;
$spacing-medium: 1rem;
$spacing-large: 2rem;
$spacing-extra-large: 4rem;
And you wanna create a bunch of functional mixins which do one thing, e.g setting the padding-right
to those values, like:
@mixin pr0 {
padding-right: 0;
}
@mixin pr1 {
padding-right: $spacing-extra-small;
}
@mixin pr2 {
padding-right: $spacing-small;
}
@mixin pr3 {
padding-right: $spacing-medium;
}
@mixin pr4 {
padding-right: $spacing-large;
}
@mixin pr5 {
padding-right: $spacing-extra-large;
}
Is there a way to write this as a loop or something, to make generating these mixins easier?
Upvotes: 1
Views: 2290
Reputation: 1785
You are not allowed to generate mixins dynamically in Sass
but CSS
classes can be created dynamically.
reference - Read this thread
In first method, I have used "key": value
pair to define a Sass map and from that we can easily set the name and value you prefer to mention as class name and it's property value.
$spacing-extra-small: 0.25rem;
$spacing-small: 0.5rem;
$spacing-medium: 1rem;
$spacing-large: 2rem;
$spacing-extra-large: 4rem;
$paddings: (
"pr0": 0,
"pr1": $spacing-extra-small,
"pr2": $spacing-small,
"pr3": $spacing-medium,
"pr4": $spacing-large,
"pr5": $spacing-extra-large
);
@each $padding, $value in $paddings {
.#{$padding} {
padding-right: #{$value};
}
}
Note - Instead of variables I have added in $padding
map, you can apply absolute pixel values directly as shown below.
$paddings: (
"pr0": 0,
"pr1": 0.25rem,
"pr2": 0.5rem,
"pr3": 1rem,
"pr4": 2rem,
"pr5": 4rem
);
Here in second method, I have used only value
s to define a Sass map and it's class name is generated dynamically using index
of map value
.
Not like in JavaScript
array
object, initial Index
of map is started from number 1. So I have perform a calculation by subtracting 1
value from the current index of map value
and match to your individual mixin names mentioned above.
$spacing-extra-small: 0.25rem;
$spacing-small: 0.5rem;
$spacing-medium: 1rem;
$spacing-large: 2rem;
$spacing-extra-large: 4rem;
$paddings: ( 0, $spacing-extra-small, $spacing-small, $spacing-medium, $spacing-large, $spacing-extra-large );
@each $padding in $paddings {
.pr#{index(($paddings), ($padding)) - 1} {
padding-right: #{$padding};
}
}
Here I have made it bit simplify by reducing to 1 mixin
and 5 variables. This mixin
can be included inside any css
class with a preferred padding variable.
HTML
<div class="box">
set a padding value here
</div>
SCSS
$spacing-extra-small: 0.25rem;
$spacing-small: 0.5rem;
$spacing-medium: 1rem;
$spacing-large: 2rem;
$spacing-extra-large: 4rem;
$pr0 : 0px;
$pr1 : $spacing-extra-small;
$pr2 : $spacing-small;
$pr3 : $spacing-medium;
$pr4 : $spacing-large;
$pr5 : $spacing-extra-large;
@mixin set-padding ($pr){
@if($pr){
padding-right: $pr;
}
}
/*Apply set-padding mixin to .box class*/
.box {
background-color: #ccc;
@include set-padding($pr2);
}
All three methods will be helpful to solve your problem. Thanks :)
Upvotes: 2
Reputation: 3473
You can create a loop and than define different values in variable $spacer
like this. no need to create mixins
every time.
$spacer: (0, 5px, 10px, 15px); // Add your values here
@each $size in $spacer {
.p-#{$size} {
padding: #{$size};
}
.pl-#{$size},
.px-#{$size} {
padding-left: #{$size};
}
.pr-#{$size},
.px-#{$size} {
padding-right: #{$size};
}
.pt-#{$size},
.py-#{$size} {
padding-top: #{$size};
}
.pb-#{$size},
.py-#{$size} {
padding-bottom: #{$size};
}
}
try to run this code in http://beautifytools.com/scss-compiler.php and you will see the output. this solution is not limited to padding-right
. if you need solution only for padding-right
than below is the solution.
$spacer: (0, 5px, 10px, 15px);
@each $size in $spacer {
.pr-#{$size} {
padding-right: #{$size};
}
}
Upvotes: 3