2011-12-16 6 views
60

Estoy tratando de utilizar la interpolación de cadenas en mi variable para hacer referencia a otra variable:Creación o hacer referencia a las variables de forma dinámica en Sass

// Set up variable and mixin 
$foo-baz: 20px; 

@mixin do-this($bar) { 
    width: $foo-#{$bar}; 
} 

// Use mixin by passing 'baz' string as a param for use $foo-baz variable in the mixin 
@include do-this('baz'); 

Pero cuando hago esto, me sale el siguiente error:

Undefined variable: "$foo-".

¿Soporta Sass variables variables de estilo PHP?

Respuesta

31

Sass no permite la creación o acceso dinámico de variables. Sin embargo, puede usar listas para un comportamiento similar.

SCSS:

$medium: 2; 

$width: 20px 30px 40px; 

@mixin do-this($bar) { 
    width: nth($width, $bar); 
} 

#smth { 
    @include do-this($medium); 
} 

css:

#smth { 
    width: 30px; } 
+7

@castus ¿cómo resolvió esto tu problema? Me encuentro con un problema muy similar en el que necesito tomar un valor de cadena de una lista y agregarle un $ y usarlo como una variable. – cmegown

3

Cada vez que necesito usar un valor condicional, me apoyo en las funciones. Aquí hay un ejemplo simple.

$foo: 2em; 
$bar: 1.5em; 

@function foo-or-bar($value) { 
    @if $value == "foo" { 
    @return $foo; 
    } 
    @else { 
    @return $bar; 
    } 
} 

@mixin do-this($thing) { 
    width: foo-or-bar($thing); 
} 
+0

Creo que esto es exactamente lo que estoy buscando. Esto es esencialmente tomar el valor pasado a la mezcla y ejecutarlo a través de la función. Luego, dependiendo de una serie de sentencias if, devuelve el mismo valor de cadena como una variable. ¿Sería posible hacer esto con un número potencialmente infinito de valores? Digamos que tenemos una lista de muchas cadenas, no solo foo o bar. – cmegown

+3

Esto es pura mala práctica, no quiere terminar con una cadena interminable de condiciones. Use mapas SASS con pares de valores clave y extraiga los valores de este en su lugar. – mystrdat

1

Para realizar una variable dinámica no es posible en SASS a partir de ahora, ya que agregará/conectará otra var que necesita ser analizada una vez cuando ejecute el comando sass.

Tan pronto como se ejecute el comando, arrojará un error de CSS inválido, ya que todas las variables declaradas seguirán el levantamiento.

Una vez ejecutado, no se puede declarar variables de nuevo sobre la marcha

saber que yo he entendido esto, la amabilidad de indicar si el siguiente es correcta:

desea declarar variables en las que la siguiente parte (palabra) es dinámica

algo así como

$list: 100 200 300; 

@each $n in $list { 
    $font-$n: normal $n 12px/1 Arial; 
} 

// should result in something like 

$font-100: normal 100 12px/1 Arial; 
$font-200: normal 200 12px/1 Arial; 
$font-300: normal 300 12px/1 Arial; 

// So that we can use it as follows when needed 

.span { 
    font: $font-200; 
    p { 
     font: $font-100 
    } 
} 

Si esto es lo que quiere, me temo que a partir de ahora, esto es no permitido

+0

Desafortunadamente esto no funciona: error scss/components.scss (Línea 71: CSS no válido después de "$ font-": expected ":", era "$ n: normal $ n 1 ...") –

+3

@castus, oops ! lo siento por no ser claro - No estoy dando una solución, en lugar de explicar la pregunta una vez más –

+5

¡probablemente no debería publicar una solución que no está permitida! – Rhyso

2

Aquí hay otra opción si está trabajando con rieles, y posiblemente en otras circunstancias.

Si agrega .erb al final de la extensión de archivo, Rails procesará erb en el archivo antes de enviarlo al intérprete SASS. Esto te da la oportunidad de hacer lo que quieras en Ruby.

Por ejemplo: (Archivo: foo.css.scss.erb)

// Set up variable and mixin 
$foo-baz: 20px; // variable 

<% 
def do_this(bar) 
    "width: $foo-#{bar};" 
end 
%> 

#target { 
    <%= do_this('baz') %> 
} 

resultados en las siguientes SCSS:

// Set up variable and mixin 
$foo-baz: 20px; // variable 

#target { 
    width: $foo-baz; 
} 

cual, por gruesa, se obtiene la siguiente CSS:

#target { 
    width: 20px; 
} 
51

Esto es realmente posible hacer uso de mapas SASS vez de variables Aquí está un ejemplo rápido:

Hacer referencia dinámica:

$colors: (
    blue: #007dc6, 
    blue-hover: #3da1e0 
); 

@mixin colorSet($colorName) { 
    color: map-get($colors, $colorName); 
    &:hover { 
     color: map-get($colors, $colorName#{-hover}); 
    } 
} 
a { 
    @include colorSet(blue); 
} 

salidas como:

a { color:#007dc6 } 
a:hover { color:#3da1e0 } 

la creación dinámica:

@function addColorSet($colorName, $colorValue, $colorHoverValue: null) { 
    $colorHoverValue: if($colorHoverValue == null, darken($colorValue, 10%), $colorHoverValue); 

    $colors: map-merge($colors, (
    $colorName: $colorValue, 
    $colorName#{-hover}: $colorHoverValue 
)); 

    @return $colors; 
} 

@each $color in blue, red { 
    @if not map-has-key($colors, $color) { 
    $colors: addColorSet($color, $color); 
    } 
    a { 
    &.#{$color} { @include colorSet($color); } 
    } 
} 

salidas como:

a.blue { color: #007dc6; } 
a.blue:hover { color: #3da1e0; } 
a.red { color: red; } 
a.red:hover { color: #cc0000; } 
+4

Tenga en cuenta que esto todavía no es "variables dinámicas". Esto es solo una variación del uso de una lista de listas que hemos estado usando desde siempre. – cimmanon

+8

Esto realmente expande las listas, que solo aceptan un número de índice como la variable que especifica. Permite invocar las variables con un nombre generado dinámicamente, creado mediante la concatenación de una cadena pasada, que era la funcionalidad solicitada. – dibbledeedoo

+2

Esta debería ser la respuesta aceptada. Aunque no es completamente dinámico, esto imita mejor la funcionalidad solicitada. – thomaux

Cuestiones relacionadas