2011-12-16 17 views
60

Próbuję użyć interpolacji ciąg na moim zmiennej odwołać innej zmiennej:Tworzenie lub przedstawieniu zmiennych dynamicznie w 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'); 

Ale kiedy to zrobić, pojawia się następujący błąd:

Undefined variable: "$foo-".

Czy Sass obsługuje zmienne zmiennych w stylu PHP?

Odpowiedz

31

Sass nie pozwala na dynamiczne tworzenie zmiennych ani uzyskiwanie do nich dostępu. Możesz jednak używać list dla podobnych zachowań.

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 jak to rozwiązało twój problem? Wpadam na bardzo podobny problem, w którym muszę pobrać wartość ciągu z listy i dodać do niego $ i użyć go jako zmiennej. – cmegown

3

Za każdym razem, gdy potrzebuję użyć wartości warunkowej, opieram się na funkcjach. Oto prosty przykład.

$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

Myślę, że dokładnie tego szukam. Zasadniczo bierze ona wartość przekazaną do mixina i uruchamia ją poprzez funkcję. Następnie, w zależności od serii instrukcji if, zwraca tę samą wartość ciągu jako zmienną. Czy byłoby to możliwe z potencjalnie nieskończoną liczbą wartości? Powiedzmy, że mamy listę wielu ciągów znaków, nie tylko foo czy bar. – cmegown

+3

To jest czysta zła praktyka, nie chcesz skończyć z niekończącym się łańcuchem warunków. Użyj map SASS z parami wartości kluczy i zamiast tego pobierz wartości z nich. – mystrdat

1

Aby zmienna dynamiczna nie jest możliwe w SASS od teraz będziesz dodawać/łączyć inny var, który musi zostać przeanalizowany raz, gdy uruchomisz polecenie sass.

Po uruchomieniu polecenia zostanie zgłoszony błąd dotyczący nieprawidłowego CSS, ponieważ wszystkie zadeklarowane zmienne będą podążać za podnoszeniem.

Po biegu, nie można ponownie zadeklarować zmienne w locie

Aby wiedzieć, że mam to rozumieć, prosimy podać, czy po to poprawne:

chcesz zadeklarować zmienne gdzie kolejna część (słowo) jest dynamiczna

coś

$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 
    } 
} 

Jeśli to, co chcesz, ja się boję, jak na razie, jest to niedozwolone

+0

Niestety to nie działa: błąd scss/components.scss (Linia 71: Nieprawidłowe CSS po "$ font-": expected ":", było "$ n: normal $ n 1 ...") –

+3

@castus, oops ! przepraszam za brak jasności - nie podaję rozwiązania, raczej wyjaśniam pytanie po raz kolejny –

+5

prawdopodobnie nie powinienem zamieszczać rozwiązania, które jest niedozwolone! – Rhyso

2

Oto kolejna opcja, jeśli pracujesz z szynami i ewentualnie w innych okolicznościach.

Jeśli dodasz .erb na końcu rozszerzenia pliku, Railsy przetworzą plik erb przed wysłaniem go do interpretera SASS. Daje to szansę na zrobienie tego, co chcesz w Ruby.

Na przykład: (plik: 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') %> 
} 

Wyniki w poniższej SCSS:

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

#target { 
    width: $foo-baz; 
} 

Które z grubej, wyniki w następujący CSS:

#target { 
    width: 20px; 
} 
51

To jest rzeczywiście możliwe do zrobienia przy użyciu SASS Mapy zamiast zmiennych. Oto krótki przykład:

Odwoływanie się dynamicznie:

$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); 
} 

Wyjścia jako:

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

Tworzenie dynamicznie:

@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); } 
    } 
} 

Wyjścia jako:

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

Należy zauważyć, że nadal nie są to "zmienne dynamiczne". To tylko odmiana listy list, z której korzystamy od zawsze. – cimmanon

+8

To faktycznie rozwija się na listach, które akceptują tylko numer indeksu jako zmienną określającą. Pozwala na wywoływanie zmiennych za pomocą dynamicznie generowanej nazwy, utworzonej przez konkatenację przekazanego łańcucha, który był żądaną funkcjonalnością. – dibbledeedoo

+2

To powinna być zaakceptowana odpowiedź. Chociaż nie jest całkowicie dynamiczny, najlepiej naśladuje żądaną funkcjonalność. – thomaux

Powiązane problemy