Alexis Wollseifen
Alexis Wollseifen

Reputation: 471

SCSS : Mixin & multiple lists issue

I try to learn scss list with mixins.

I wrote a simple mixin which add a background-url regarding the variables in a list.

It's written in a _mixins.scss file :

 $path: "../images/";

 @mixin dynamic-bg($path, $type, $ext) {
   @each $source in $source-list {
     &[data-bg="#{$source}"] {
         background: url($path + $source + '_' + $type + '.' + $ext) no-repeat;
     }
   }
 }

I call it in another file, and "describe" the list content just before :

 a {
    $source-list: "alpha", "beta", "gamma"

    @include dynamic-bg($path, "logo", "png");
 }

It should result in CSS like this :

 a[data-bg="alpha"] {
    background: url("../images/alpha_logo.png") no-repeat;
 }
 a[data-bg="beta"] {
    background: url("../images/beta_logo.png") no-repeat;
 }
 a[data-bg="gamma"] {
    background: url("../images/gamma_logo.png") no-repeat;
 }

But I get this error : Undefined variable: "$source-list"

It works fine if I add the list content before the mixin in _mixins.scss, but if so I can't re-use it over and over just by modifying the list's content.

Am I missing something?

Thanks in advance,

AW

Upvotes: 0

Views: 170

Answers (1)

Marvin
Marvin

Reputation: 10122

It works fine if I add the list content before the mixin in _mixins.scss, but if so I can't re-use it over and over just by modifying the list's content.

When calling the mixin your list is out of scope, because you defined it within the a { ... } part. To make the list visible to your mixin you would have to define the list outside (not necessarily before the mixin, but at least before you call the mixin).

$path: "../images/";

@mixin dynamic-bg($path, $type, $ext) {
 @each $source in $source-list {
   &[data-bg="#{$source}"] {
       background: url($path + $source + '_' + $type + '.' + $ext) no-repeat;
   }
 }
}

$source-list: "alpha", "beta", "gamma";

a {
  @include dynamic-bg($path, "logo", "png");
}

$source-list: "new1", "new2";

strong {
 @include dynamic-bg($path, "logo", "png");
}

compiles to:

a[data-bg="alpha"] {
  background: url("../images/alpha_logo.png") no-repeat;
}
a[data-bg="beta"] {
  background: url("../images/beta_logo.png") no-repeat;
}
a[data-bg="gamma"] {
  background: url("../images/gamma_logo.png") no-repeat;
}

strong[data-bg="new1"] {
  background: url("../images/new1_logo.png") no-repeat;
}
strong[data-bg="new2"] {
  background: url("../images/new2_logo.png") no-repeat;
}

If you put the list inside of the a for the reason that no other definition should be able to make use of it, you'd better go for an additional (optional) mixin parameter:

@mixin dynamic-bg($path, $type, $ext, $sources: $source-list) {
 @each $source in $sources {
   &[data-bg="#{$source}"] {
       background: url($path + $source + '_' + $type + '.' + $ext) no-repeat;
   }
 }
}

$source-list: "default-1", "default-2";

a {
  $source-list: "alpha", "beta", "gamma";
  @include dynamic-bg($path, "logo", "png", $source-list);
}

strong {
  @include dynamic-bg($path, "logo", "png");
}

compiles to:

a[data-bg="alpha"] {
  background: url("../images/alpha_logo.png") no-repeat;
}
a[data-bg="beta"] {
  /* ... */

strong[data-bg="default-1"] {
  background: url("../images/default-1_logo.png") no-repeat;
}
strong[data-bg="default-2"] {
  /* ... */

or just like the following with a required parameter and no additional $source-list variable:

@mixin dynamic-bg($path, $type, $ext, $source-list) {
 @each $source in $source-list {
   &[data-bg="#{$source}"] {
       background: url($path + $source + '_' + $type + '.' + $ext) no-repeat;
   }
 }
}

a {
  @include dynamic-bg($path, "logo", "png", ("alpha", "beta", "gamma"));
}

strong {
  @include dynamic-bg($path, "logo", "png", ("strong-1", "strong-2"));
}

Upvotes: 1

Related Questions