1

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?

a7dc
  • 3,323
  • 7
  • 32
  • 50
  • Does this answer your question? [How to define a dynamic mixin or function name in SASS?](https://stackoverflow.com/questions/15748937/how-to-define-a-dynamic-mixin-or-function-name-in-sass) – ReSedano Nov 15 '19 at 12:18
  • I think this is more the thing I'm looking for: https://gist.github.com/jacurtis/30da4bf9a6c9b9b5cc0aebac512ca7c9 – a7dc Nov 15 '19 at 12:45
  • @A7DC Below I have mentioned two methods. It may be helpful. Thanks – VSM Nov 18 '19 at 04:33

2 Answers2

3

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};
  }

}
Zuber
  • 3,393
  • 1
  • 19
  • 34
1

You are not allowed to generate mixins dynamically in Sassbut CSS classes can be created dynamically.

reference - Read this thread


Method 1

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
);

Method 2

Here in second method, I have used only values 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};
 }
}

Method 3

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 :)

VSM
  • 1,765
  • 8
  • 18