mirror of
https://github.com/danog/sass-site.git
synced 2024-11-30 04:29:17 +01:00
358 lines
9.6 KiB
Plaintext
358 lines
9.6 KiB
Plaintext
---
|
|
title: Variables
|
|
table_of_contents: true
|
|
introduction: >
|
|
Sass variables are simple: you assign a value to a name that begins with `$`,
|
|
and then you can refer to that name instead of the value itself. But despite
|
|
their simplicity, they're one of the most useful tools Sass brings to the
|
|
table. Variables make it possible to reduce repetition, do complex math,
|
|
configure libraries, and much more.
|
|
---
|
|
|
|
{% markdown %}
|
|
A variable declaration looks a lot like a [property declaration][]: it's written
|
|
`<variable>: <expression>`. Unlike a property, which can only be declared in a
|
|
style rule or at-rule, variables can be declared anywhere you want. To use a
|
|
variable, just include it in a value.
|
|
|
|
[property declaration]: /documentation/style-rules/declarations
|
|
{% endmarkdown %}
|
|
|
|
{% codeExample 'variable' %}
|
|
$base-color: #c6538c;
|
|
$border-dark: rgba($base-color, 0.88);
|
|
|
|
.alert {
|
|
border: 1px solid $border-dark;
|
|
}
|
|
===
|
|
$base-color: #c6538c
|
|
$border-dark: rgba($base-color, 0.88)
|
|
|
|
.alert
|
|
border: 1px solid $border-dark
|
|
{% endcodeExample %}
|
|
|
|
{% headsUp false %}
|
|
{% markdown %}
|
|
CSS has [variables of its own][], which are totally different than Sass
|
|
variables. Know the differences!
|
|
|
|
[variables of its own]: /documentation/style-rules/declarations#custom-properties
|
|
|
|
* Sass variables are all compiled away by Sass. CSS variables are included in
|
|
the CSS output.
|
|
|
|
* CSS variables can have different values for different elements, but Sass
|
|
variables only have one value at a time.
|
|
|
|
* Sass variables are *imperative*, which means if you use a variable and then
|
|
change its value, the earlier use will stay the same. CSS variables are
|
|
*declarative*, which means if you change the value, it'll affect both earlier
|
|
uses and later uses.
|
|
{% endmarkdown %}
|
|
|
|
{% codeExample 'variable-heads-up' %}
|
|
$variable: value 1;
|
|
.rule-1 {
|
|
value: $variable;
|
|
}
|
|
|
|
$variable: value 2;
|
|
.rule-2 {
|
|
value: $variable;
|
|
}
|
|
===
|
|
$variable: value 1
|
|
.rule-1
|
|
value: $variable
|
|
|
|
|
|
$variable: value 2
|
|
.rule-2
|
|
value: $variable
|
|
{% endcodeExample %}
|
|
{% endheadsUp %}
|
|
|
|
{% funFact %}
|
|
Sass variables, like all Sass identifiers, treat hyphens and underscores as
|
|
identical. This means that `$font-size` and `$font_size` both refer to the same
|
|
variable. This is a historical holdover from the very early days of Sass, when
|
|
it *only* allowed underscores in identifier names. Once Sass added support for
|
|
hyphens to match CSS's syntax, the two were made equivalent to make migration
|
|
easier.
|
|
{% endfunFact %}
|
|
|
|
{% markdown %}
|
|
## Default Values
|
|
|
|
Normally when you assign a value to a variable, if that variable already had a
|
|
value, its old value is overwritten. But if you're writing a Sass library, you
|
|
might want to allow your users to configure your library's variables before you
|
|
use them to generate CSS.
|
|
|
|
To make this possible, Sass provides the `!default` flag. This assigns a value
|
|
to a variable *only if* that variable isn't defined or its value is [`null`][].
|
|
Otherwise, the existing value will be used.
|
|
|
|
[`null`]: /documentation/values/null
|
|
{% endmarkdown %}
|
|
|
|
{{ '### Configuring Modules' | markdown }}
|
|
|
|
{% render 'documentation/snippets/module-system-status' %}
|
|
|
|
{% markdown %}
|
|
Variables defined with `!default` can be configured when loading a module with
|
|
the [`@use` rule][]. Sass libraries often use `!default` variables to allow
|
|
their users to configure the library's CSS.
|
|
|
|
[`@use` rule]: /documentation/at-rules/use
|
|
|
|
To load a module with configuration, write `@use <url> with (<variable>:
|
|
<value>, <variable>: <value>)`. The configured values will override the
|
|
variables' default values. Only variables written at the top level of the
|
|
stylesheet with a `!default` flag can be configured.
|
|
{% endmarkdown %}
|
|
|
|
{% render 'code-snippets/example-use-with' %}
|
|
|
|
{% markdown %}
|
|
## Built-in Variables
|
|
|
|
Variables that are defined by a [built-in module] cannot be modified.
|
|
|
|
[built-in module]: /documentation/modules
|
|
{% endmarkdown %}
|
|
|
|
{% codeExample 'built-in-variables', false %}
|
|
@use "sass:math" as math;
|
|
|
|
// This assignment will fail.
|
|
math.$pi: 0;
|
|
===
|
|
@use "sass:math" as math
|
|
|
|
// This assignment will fail.
|
|
math.$pi: 0
|
|
{% endcodeExample %}
|
|
|
|
{% markdown %}
|
|
## Scope
|
|
|
|
Variables declared at the top level of a stylesheet are *global*. This means
|
|
that they can be accessed anywhere in their module after they've been declared.
|
|
But that's not true for all variables. Those declared in blocks (curly braces in
|
|
SCSS or indented code in Sass) are usually *local*, and can only be accessed
|
|
within the block they were declared.
|
|
{% endmarkdown %}
|
|
|
|
{% codeExample 'scope' %}
|
|
$global-variable: global value;
|
|
|
|
.content {
|
|
$local-variable: local value;
|
|
global: $global-variable;
|
|
local: $local-variable;
|
|
}
|
|
|
|
.sidebar {
|
|
global: $global-variable;
|
|
|
|
// This would fail, because $local-variable isn't in scope:
|
|
// local: $local-variable;
|
|
}
|
|
===
|
|
$global-variable: global value
|
|
|
|
.content
|
|
$local-variable: local value
|
|
global: $global-variable
|
|
local: $local-variable
|
|
|
|
|
|
.sidebar
|
|
global: $global-variable
|
|
|
|
// This would fail, because $local-variable isn't in scope:
|
|
// local: $local-variable
|
|
{% endcodeExample %}
|
|
|
|
{% markdown %}
|
|
### Shadowing
|
|
|
|
Local variables can even be declared with the same name as a global variable. If
|
|
this happens, there are actually two different variables with the same name: one
|
|
local and one global. This helps ensure that an author writing a local variable
|
|
doesn't accidentally change the value of a global variable they aren't even
|
|
aware of.
|
|
{% endmarkdown %}
|
|
|
|
{% codeExample 'shadowing' %}
|
|
$variable: global value;
|
|
|
|
.content {
|
|
$variable: local value;
|
|
value: $variable;
|
|
}
|
|
|
|
.sidebar {
|
|
value: $variable;
|
|
}
|
|
===
|
|
$variable: global value
|
|
|
|
.content
|
|
$variable: local value
|
|
value: $variable
|
|
|
|
|
|
.sidebar
|
|
value: $variable
|
|
{% endcodeExample %}
|
|
|
|
{% markdown %}
|
|
If you need to set a global variable's value from within a local scope (such as
|
|
in a mixin), you can use the `!global` flag. A variable declaration flagged as
|
|
`!global` will *always* assign to the global scope.
|
|
{% endmarkdown %}
|
|
|
|
{% codeExample 'global-variable' %}
|
|
$variable: first global value;
|
|
|
|
.content {
|
|
$variable: second global value !global;
|
|
value: $variable;
|
|
}
|
|
|
|
.sidebar {
|
|
value: $variable;
|
|
}
|
|
===
|
|
$variable: first global value
|
|
|
|
.content
|
|
$variable: second global value !global
|
|
value: $variable
|
|
|
|
|
|
.sidebar
|
|
value: $variable
|
|
{% endcodeExample %}
|
|
|
|
{% headsUp false %}
|
|
{% # Arguments are (in order): `dart`, `libsass`, `node`, `ruby`, optional feature name, additional details within %}
|
|
{% compatibility "2.0.0", false, null, false %}
|
|
Older Sass versions allowed `!global` to be used for a variable that doesn't
|
|
exist yet. This behavior was deprecated to make sure each stylesheet declares
|
|
the same variables no matter how it's executed.
|
|
{% endcompatibility %}
|
|
|
|
{% markdown %}
|
|
The `!global` flag may only be used to set a variable that has already been
|
|
declared at the top level of a file. It *may not* be used to declare a new
|
|
variable.
|
|
{% endmarkdown %}
|
|
{% endheadsUp %}
|
|
|
|
{% markdown %}
|
|
### Flow Control Scope
|
|
|
|
Variables declared in [flow control rules][] have special scoping rules: they
|
|
don't shadow variables at the same level as the flow control rule. Instead, they
|
|
just assign to those variables. This makes it much easier to conditionally
|
|
assign a value to a variable, or build up a value as part of a loop.
|
|
|
|
[flow control rules]: /documentation/at-rules/control
|
|
{% endmarkdown %}
|
|
|
|
{% codeExample 'flow-control' %}
|
|
$dark-theme: true !default;
|
|
$primary-color: #f8bbd0 !default;
|
|
$accent-color: #6a1b9a !default;
|
|
|
|
@if $dark-theme {
|
|
$primary-color: darken($primary-color, 60%);
|
|
$accent-color: lighten($accent-color, 60%);
|
|
}
|
|
|
|
.button {
|
|
background-color: $primary-color;
|
|
border: 1px solid $accent-color;
|
|
border-radius: 3px;
|
|
}
|
|
===
|
|
$dark-theme: true !default
|
|
$primary-color: #f8bbd0 !default
|
|
$accent-color: #6a1b9a !default
|
|
|
|
@if $dark-theme
|
|
$primary-color: darken($primary-color, 60%)
|
|
$accent-color: lighten($accent-color, 60%)
|
|
|
|
|
|
.button
|
|
background-color: $primary-color
|
|
border: 1px solid $accent-color
|
|
border-radius: 3px
|
|
{% endcodeExample %}
|
|
|
|
{% headsUp %}
|
|
Variables in flow control scope can assign to existing variables in the outer
|
|
scope, but new variables declared in flow control scope won't be accessible in
|
|
the outer scope. Make sure the variable is already declared before you assign to
|
|
it, even if you need to declare it as `null`.
|
|
{% endheadsUp %}
|
|
|
|
{% markdown %}
|
|
## Advanced Variable Functions
|
|
|
|
The Sass core library provides a couple advanced functions for working with
|
|
variables. The [`meta.variable-exists()` function][] returns whether a variable
|
|
with the given name exists in the current scope, and the
|
|
[`meta.global-variable-exists()` function][] does the same but only for the
|
|
global scope.
|
|
|
|
[`meta.variable-exists()` function]: /documentation/modules/meta#variable-exists
|
|
[`meta.global-variable-exists()` function]: /documentation/modules/meta#global-variable-exists
|
|
{% endmarkdown %}
|
|
|
|
{% headsUp false %}
|
|
{% markdown %}
|
|
Users occasionally want to use interpolation to define a variable name based on
|
|
another variable. Sass doesn't allow this, because it makes it much harder to
|
|
tell at a glance which variables are defined where. What you *can* do, though,
|
|
is define a [map][] from names to values that you can then access using
|
|
variables.
|
|
|
|
[map]: /documentation/values/maps
|
|
{% endmarkdown %}
|
|
|
|
{% codeExample 'advanced-variable-functions' %}
|
|
@use "sass:map";
|
|
|
|
$theme-colors: (
|
|
"success": #28a745,
|
|
"info": #17a2b8,
|
|
"warning": #ffc107,
|
|
);
|
|
|
|
.alert {
|
|
// Instead of $theme-color-#{warning}
|
|
background-color: map.get($theme-colors, "warning");
|
|
}
|
|
===
|
|
@use "sass:map"
|
|
|
|
$theme-colors: ("success": #28a745, "info": #17a2b8, "warning": #ffc107)
|
|
|
|
.alert
|
|
// Instead of $theme-color-#{warning}
|
|
background-color: map.get($theme-colors, "warning")
|
|
===
|
|
.alert {
|
|
background-color: #ffc107;
|
|
}
|
|
{% endcodeExample %}
|
|
{% endheadsUp %}
|