mirror of
https://github.com/danog/sass-site.git
synced 2024-12-15 10:57:24 +01:00
334 lines
9.1 KiB
Plaintext
334 lines
9.1 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.
|
|
---
|
|
|
|
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]: style-rules/declarations
|
|
|
|
<% example do %>
|
|
$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
|
|
<% end %>
|
|
|
|
<% heads_up do %>
|
|
CSS has [variables of its own][], which are totally different than Sass
|
|
variables. Know the differences!
|
|
|
|
[variables of its own]: 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.
|
|
|
|
<% example do %>
|
|
$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
|
|
<% end %>
|
|
<% end %>
|
|
|
|
<% fun_fact do %>
|
|
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.
|
|
<% end %>
|
|
|
|
## 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`]: values/null
|
|
|
|
### Configuring Modules
|
|
|
|
<%= partial 'snippets/module-system-status' %>
|
|
|
|
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]: 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.
|
|
|
|
<%= partial '../code-snippets/example-use-with' %>
|
|
|
|
## Built-in Variables
|
|
|
|
Variables that are defined by a [built-in module] cannot be modified.
|
|
|
|
[built-in module]: modules
|
|
|
|
<% example(autogen_css: false) do %>
|
|
@use "sass:math" as math;
|
|
|
|
// This assignment will fail.
|
|
math.$pi: 0;
|
|
===
|
|
@use "sass:math" as math
|
|
|
|
// This assignment will fail.
|
|
math.$pi: 0
|
|
<% end %>
|
|
|
|
## 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.
|
|
|
|
<% example do %>
|
|
$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
|
|
<% end %>
|
|
|
|
### 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.
|
|
|
|
<% example do %>
|
|
$variable: global value;
|
|
|
|
.content {
|
|
$variable: local value;
|
|
value: $variable;
|
|
}
|
|
|
|
.sidebar {
|
|
value: $variable;
|
|
}
|
|
===
|
|
$variable: global value
|
|
|
|
.content
|
|
$variable: local value
|
|
value: $variable
|
|
|
|
|
|
.sidebar
|
|
value: $variable
|
|
<% end %>
|
|
|
|
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.
|
|
|
|
<% example do %>
|
|
$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
|
|
<% end %>
|
|
|
|
<% heads_up do %>
|
|
<% impl_status dart: '2.0.0', libsass: false, ruby: false do %>
|
|
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.
|
|
<% end %>
|
|
|
|
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.
|
|
|
|
<% end %>
|
|
|
|
### 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]: at-rules/control
|
|
|
|
<% example do %>
|
|
$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
|
|
<% end %>
|
|
|
|
<% heads_up do %>
|
|
Variables in flow control scope can assign to existing variables in the outer
|
|
scope, but they can't declare new variables there. Make sure the variable is
|
|
already declared before you assign to it, even if you need to declare it as
|
|
`null`.
|
|
<% end %>
|
|
|
|
## 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]: modules/meta#variable-exists
|
|
[`meta.global-variable-exists()` function]: modules/meta#global-variable-exists
|
|
|
|
<% heads_up do %>
|
|
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]: values/maps
|
|
|
|
<% example do %>
|
|
@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;
|
|
}
|
|
<% end %>
|
|
<% end %>
|