raghuveer999
raghuveer999

Reputation: 709

SASS Customize Class Names with Variables

Is there any way to customize the variables in SASS? For example:

.m-b-{$number} {
    margin-bottom: $number;
}

If I give class="m-b-50" to an element, it should take margin-bottom 50. I just want to know if it is possible with SASS.

Upvotes: 7

Views: 10447

Answers (3)

xr280xr
xr280xr

Reputation: 13302

The answer is: no it is not possible. SASS is just a language to pre-generate CSS for you. There is no on-demand, dynamic creation of classes triggered by the contents of your HTML markup. When it comes time for the browser to render your HTML and apply your specified classes, it is still just using CSS. I.e. if you assign class="m-b-50" to an element, the class .m-b-50 must already be explicitly defined somewhere. As noted in the other answers, SASS can make it easier to generate a bunch of pre-defined classes but you must know which values you want to support up front.

Now, you could generate classes for some very large, all-inclusive range like -1000 to 1000 to effectively support all values you might ever try to use and it would seem to do what you wanted, but you would be forcing your users to download a larger CSS file with, most likely, a large percentage of it being unused CSS which is wasteful and can be inconsiderate in a world of paid & limited data plans.

Upvotes: 0

Pawan Kumar
Pawan Kumar

Reputation: 1374

Yes it is possible with the help of variable interpolation or variable substitution which uses #{} for variable substitution in SASS and mixins which is a block of code just like function.

Interpolation is the process of evaluating an expression or a string containing one or more variables, yielding a result in which the variables are replaced with their corresponding values.

Simple example of interpolation and set values to the css property in SASS:

$number:60;
$n: 20px;

.m-b-#{$number}{
  margin-bottom: #{$number}px;
  margin-top: $n;
}

To create customize class names, will use mixins:

@mixin margin-class($side, $number) {
  $firstLetter: str-slice($side, 0, 1);
  .m-#{$firstLetter}-#{$number}{
     margin-#{$side}: #{$number}px;
  }
}

$margins: (10, 20);
$sides: ("top", "right", "bottom", "left");
@mixin generate-margin(){
   @each $margin in $margins{
      @each $side in $sides{
        @include margin-class($side, $margin);
      }
   }
}

@include generate-margin();

Here, generate-margin() will get executed which will call margin-class() for each $margins and $sides, and will generate the below CSS classes:

.m-t-10 {
  margin-top: 10px;
}

.m-r-10 {
  margin-right: 10px;
}

.m-b-10 {
  margin-bottom: 10px;
}

.m-l-10 {
  margin-left: 10px;
}

.m-t-20 {
  margin-top: 20px;
}

.m-r-20 {
  margin-right: 20px;
}

.m-b-20 {
  margin-bottom: 20px;
}

.m-l-20 {
  margin-left: 20px;
}

That's the one way when you want only for specific values, but if you want to create margin class for 0-20, you can loop thru 0 to 20 as shown below:

@mixin generate-margin(){
  @for $margin from 1 through 20{
    @each $side in $sides{
      @include margin-class($side, $margin);
    }
  }
}

Upvotes: 9

kks1
kks1

Reputation: 171

For anyone else facing this issue, here is how one can achieve this:-

@for $i from 1 through 10 {
  .mb-#{$i} {
     margin-bottom: #{$i}rem;
  }
}

Upvotes: 5

Related Questions