Sassで変数を動的に作成または参照する


91

私の変数で文字列補間を使用して別の変数を参照しようとしています:

// 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');

しかし、これを行うと、次のエラーが発生します。

未定義の変数: "$ foo-"。

SassはPHPスタイルの変数変数をサポートしていますか?

回答:


49

Sassでは、変数を動的に作成またはアクセスすることはできません。ただし、リストを使用して同様の動作を行うことができます。

scss:

$list: 20px 30px 40px;    
@mixin get-from-list($index) {
  width: nth($list, $index);
}

$item-number: 2;
#smth {
  @include get-from-list($item-number);
}

生成されたCSS:

#smth {
  width: 30px; 
}

9
@castusこれはあなたの問題をどのように解決しましたか?リストから文字列値を取得し、それに$を追加して変数として使用する必要があるという、非常によく似た問題が発生しています。
cmegown 2013

86

これは実際には、変数の代わりにSASSマップを使用して行うことができます。ここに簡単な例があります:

動的参照:

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

出力:

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

動的に作成する:

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

出力:

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

10
これはまだ「動的変数」ではないことに注意してください。これは、私たちが永遠に使用してきたリストのリストを使用したバリエーションです。
cimmanon

13
これは実際にはリストを拡張し、リスト番号を指定変数としてのみ受け入れます。これにより、要求された機能であった、渡された文字列の連結によって作成された動的に生成された名前で変数を呼び出すことができます。
dibbledeedoo 2015年

3
これは受け入れられる答えになるはずです。完全に動的ではありませんが、これは要求された機能を最もよく模倣しています。
thomaux

1
有用ではあるが、この例では、すべての任意の変数を作成していない
ithil

そうだね。opの質問のタイトルにもかかわらず、そのテキストは変数の作成を説明していなかったため、それについては触れませんでした。ただし、それを行うことに関連するセクションを追加しただけです(ただし、特異変数ではなく、マップを使用しています)。
dibbledeedoo 2017

5

条件値を使用する必要があるときはいつでも、関数に頼ります。簡単な例を示します。

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

これはまさに私が探しているものだと思います。これは基本的に、ミックスインに渡された値を受け取り、関数を介して実行します。次に、一連のifステートメントに応じて、変数と同じ文字列値を返します。潜在的に無限の数の値でこれを行うことは可能でしょうか?fooやbarだけでなく、多くの文字列のリストがあるとします。
cmegown 2013

3
これは純粋に悪い習慣です。あなたはif条件の無限の連鎖に終わりたくないでしょう。キーと値のペアでSASSマップを使用し、代わりに値をプルします。
mystrdat

これは主にこのショーケースでは冗長です-なぜあなたは単に電話しないの@include do-this($foo);ですか?...ただし、関数が実際に何かを実行した場合、これは理にかなっていますが、通過するだけです...
jave.web

2

レールを使用している場合、およびおそらく他の状況下での別のオプションを次に示します。

ファイル拡張子の最後に.erbを追加すると、Railsはファイルのerbを処理してからSASSインタープリターに送信します。これにより、Rubyでやりたいことができるチャンスが与えられます。

例:(ファイル: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') %>
}

次のscssの結果:

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

#target {
  width: $foo-baz;
}

どちらがおおまかに言えば、次のCSSになります。

#target {
  width: 20px;
}

0

最近、動的に色を参照する必要に出会いました。

すべてのプロジェクトに_colours.scssファイルがあり、すべての色を一度定義して、全体を通して変数として参照しています。

_forms.scssファイルで、使用可能な各色のボタンスタイルを設定したいと考えていました。通常、退屈な作業です。これにより、異なる色ごとに同じコードを記述する必要がなくなりました。

唯一の欠点は、実際のCSSを書き込む前に各色の名前と値をリストする必要があることです。

// $red, $blue - variables defined in _colours.scss
$colours: 
  'red' $red,
  'blue' $blue;

@each $name, $colour in $colours {
  .button.has-#{$name}-background-color:hover {
    background-color: lighten($colour, 15%);
  }
}

-2

SASSでは、sassコマンドを実行するときに一度解析する必要がある別の変数を追加/接続するため、動的変数を作成することは現在のところ不可能です。

コマンドが実行されるとすぐに、宣言されたすべての変数がホイストに従うため、無効なCSSに対してエラーがスローされます。

一度実行すると、その場で変数を再び宣言することはできません

私がこれを理解したことを知るために、以下が正しいかどうか親切に述べてください:

次の部分(単語)が動的である変数を宣言したい

何かのようなもの

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

これがあなたが望むものであるならば、私は今のところ恐れています、これは許可されていません


3
残念ながらこれは機能しません:エラーscss / components.scss(71行目: "$ font-"の後の無効なCSS:予期された ":"、 "$ n:通常の$ n 1 ..."でした)
Krzysztof Romanowski

4
@castus、おっと!はっきりしないことを申し訳ありません-私は解決策を与えていません。質問をもう一度説明します
Om Shankar 2012

15
おそらく許可されていないソリューションを投稿するべきではありません!
Rhyso

私はこれでうまくいきますが、sass経由で変数を作成できないようです?
v3nt 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.