[Sass] Interpolation of variable names

6,004 views
Skip to first unread message

Christian Peters

unread,
May 25, 2011, 1:54:42 PM5/25/11
to Sass
Hey,

I was looking forward to the new Sass 3.1 features in order to dry up
my style definitions.

unDRY code:

a
.outlet &
color: $outlet-color
.community &
color: $community-color
.men &
color: $men-color
.women &
color: $women-color

My preferred solution (does not work):

a
@each $context in outlet, community, men, women
.#{$context} &
color: $#{$context}-color

This is a syntax error - invalid expression: "$#{$context}-color"

Is there a possibility to interpolate Sass variables?
If not... do you see another solution?

In the next step, I would have liked to put these 3 lines into a mixin
and make the css attribute customizable (color, border-bottom-color,
background-color, ...).

Christian

Nathan Weizenbaum

unread,
May 25, 2011, 3:55:00 PM5/25/11
to sass...@googlegroups.com
Interpolating within variable names is one step of indirection farther than I think it's necessary to go. It's easy enough to use nested lists to keep this reasonably DRY, as in

a
 @each $context in outlet $outlet-color, community $community-color, men $men-color, women $women-color
   .#{nth($context, 1)} &
     color: nth($context, 2)

You could even write some Sass functions to make a lookup table out of lists, if you want.


--
You received this message because you are subscribed to the Google Groups "Sass" group.
To post to this group, send email to sass...@googlegroups.com.
To unsubscribe from this group, send email to sass-lang+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/sass-lang?hl=en.


Christian Peters

unread,
May 26, 2011, 9:14:36 AM5/26/11
to Sass
Thank you for your quick response!

I solved it this way:

// Mapping function
@function accent-color($context)
@if $context == outlet
@return $outlet-color
@if $context == community
@return $community-color
@if $context == men
@return $men-color
@if $context == women
@return $women-color
@else
@return $women-color

// Generate context-specific accentuations
@mixin accentuate($selector, $attribute: color)
@each $context in outlet, community, men, women
.#{$context} #{$selector}
#{$attribute}: accent-color($context)

// Simple usage in specific stylesheets
a
+accentuate('&')


I would still prefer "metaprogramming" possibilities in Sass but this
is okay for now. :)

Christian

Eric Artzt

unread,
May 27, 2011, 12:58:39 PM5/27/11
to Sass
Somewhat related, I am looking at sprite generation and the use of
SASS mixins to easily incorporate background positions in various CSS
defs. We are using the "sprite" gem (https://github.com/merbjedi/
sprite) and its output is something like the following (mirroring
Christian's solution above). Our generated mixin, as it has to include
all sprite files in our very large web app, is 1100+ lines long.
Clearly there are some organizational things we can do, but am
wondering whether there might be some way to generate key/value tables
that would allow e.g. a command

+sprite("groupname", "spritename")

to reference a string/value table in order to access values or even a
SASS list. This string/value table would be generated using the sprite
generation tool. Thoughts?

Thanks,
Eric

= sprite(!group_name, !image_name, !offset=0)
@if !group_name == "profile" and !image_name == "add"
background: url('/images/sprites/profile.png?1305666298') no-
repeat 0px #{0+!offset}px
width: 59px
height: 24px
@else if !group_name == "profile" and !image_name == "add_disabled"
background: url('/images/sprites/profile.png?1305666298') no-
repeat 0px #{-44+!offset}px
width: 59px
height: 24px
@else if !group_name == "profile" and !image_name == "contract"
background: url('/images/sprites/profile.png?1305666298') no-
repeat 0px #{-88+!offset}px
width: 10px
height: 10px
@else if !group_name == "profile" and !image_name == "expand"
background: url('/images/sprites/profile.png?1305666298') no-
repeat 0px #{-118+!offset}px
width: 10px
height: 10px


On May 26, 6:14 am, Christian Peters <crispy....@googlemail.com>
wrote:

iGbanam

unread,
May 28, 2011, 10:51:22 PM5/28/11
to sass...@googlegroups.com
You should checkout the gem 'lemonade'. I used this sometime back when I had to work with sprites.

Cheers,
Iggy

Brandon Mathis

unread,
May 29, 2011, 10:11:36 AM5/29/11
to sass...@googlegroups.com
Don't bother with lemonade. Lemonade is officially deprecated: http://nh.io/kTp54I
Read this: http://nh.io/muOh8m

- Brandon Mathis (via iPhone)

Chris Eppstein

unread,
May 29, 2011, 1:35:13 PM5/29/11
to sass...@googlegroups.com
I have just pushed some commits (https://github.com/nex3/sass/commits/stable) that add two new functions for working with lists: zip and index.

Using these new built-in functions together with a custom sass function it should be much easier to emulate lookup tables.

$border-names: a, b, c;
$border-widths: 1px, 1px, 2px;
$border-styles: solid, dashed, solid;
$border-colors: red, green, blue;
$borders: zip($border-widths, $border-styles, $border-colors);

@function border-for($name) {
   @return nth($borders, index($border-names, $name))
}

@each $name in $border-names {
  .border-#{$name} {
    border: border-for($name);
  }
}

Would generate:

.border-a { border: 1px solid red; }
.border-b { border: 1px dashed green; }
.border-c { border: 2px solid blue; }

While, the performance will not be great for very long lists like the one you are working with, it will likely be better than you are currently experiencing.

Chris

Christian Peters

unread,
Jun 2, 2011, 11:27:49 AM6/2/11
to Sass
I am glad that you are turning these discussions into new features,
Chris! :)

But.. hmmm... do you really believe that it is manageable to maintain
lookup tables with zip and index?

If you have about 20 elements...

$border-names: jhfazsgefhasd fsd sgd fsad fgsdgn vnsadgvfsev gvdcn
vghv dsg svcnbvgv sgvd nsavd gnvasdgv nsd ghfgdsa asdhgae faeszgfa
faesfas duzli zjksd fasd eas oliea feoafa iappol
$border-widths: 1px 4px 2px 3px 2px 1px 1px 2px 1px 4px 2px 3px 2px
1px 1px 2px 1px 4px 2px 3px 2px 1px 1px 2px
$border-styles: solid dashed solid solid dashed solid solid dashed
solid solid dashed solid solid dashed solid solid dashed solid solid
dashed solid solid

... and have to change e.g. gnvasdgv ... you would do better with a
long list of @if .. @else if's.

Besides, this method implies a 1:1:1 relationship.

My lookup function has grown to this:

@function accent-color($context: false)
@if $context == male-user or $context == men-area or $context == men
or $context == male
@return $men-color
@else if $context == female-user or $context == women-area or
$context == women or $context == female
@return $women-color
@else if $context == outlet-area or $context == outlet
@return $outlet-color
@else if $context == community-area or $context == community
@return $community-color
@else if $context == brands-area or $context == brands
@return $grey
@else
@return $women-color

Cheers,
Christian
Reply all
Reply to author
Forward
0 new messages