Inline scss variable as the name part in the evaluation of another scss variable

144 views Asked by At

Suppose I have the following scss variables:

$until-xs: "(max-width: 377px)";
$until-sm: "(max-width: 640px)";
...
$until-xl: "(max-width: 4000px)";

And based on them the following helper css classes are constructed:

.until-sm {
  display: none;
  @media #{$until-xs} {
    display: block !important;
  }
}

.until-md {
  display: none !important;
  @media #{$until-sm} {
    display: block !important;
  }
}

/* plus a lot of classes like this */

I am trying to create a mixin that would help me define those classes more easily by passing the $until-x variable as an input to the mixin, like so:

@mixin until($x) {
  display: none;
  @media #{'$until-'#{$x}} {
    display: block !important;
  }
}

Such that the classes above will be defined simply as:

.until-xs { @include until($until-xs); }

The problem is the media variable inlining part does not evaluate the way I wanted, like:

#{'$until-'#{$x}} (when x is 'xs') =>
#{'$until-xs'} =>
#{$until-xs} =>
(max-width: 377px)

Any way I can achieve this? Since this can be applied in multiple places in my project I am more interested in the possibility of inlining vars like this than the solution to the particular problem from the example.

1

There are 1 answers

1
hamid-davodi On

Instead of defining lots of variables like $until-xs, $until-sm and so on, you can define a map that contains information of your medias like the code below:

@use "sass:map";
$until-var: ("xs": "(max-width: 377px)", "sm": "(max-width: 620px)", "md": "(max-width: 807px)");

@mixin until($x) {
  display: none;
  @media #{map.get($until-var, $x)} {
    display: block !important;
  }
}
/* using that in your classes */
.until-xs { @include until("xs"); }

.until-sm { @include until("sm"); }

I'm not sure what you mean by inlining vars! But if you want a single mixin that works for different medias, I think that works.