mirror of
https://github.com/danog/sass-site.git
synced 2024-12-02 09:27:59 +01:00
Convert remainder of docs to md
This commit is contained in:
parent
69ee85ae0d
commit
9ac3302fd0
@ -24,15 +24,13 @@ introduction: >
|
|||||||
border-radius: $size * 0.5
|
border-radius: $size * 0.5
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
## Interpolation
|
||||||
## Interpolation
|
|
||||||
|
|
||||||
A property's name can include [interpolation][], which makes it possible to
|
A property's name can include [interpolation][], which makes it possible to
|
||||||
dynamically generate properties as needed. You can even interpolate the entire
|
dynamically generate properties as needed. You can even interpolate the entire
|
||||||
property name!
|
property name!
|
||||||
|
|
||||||
[interpolation]: /documentation/interpolation
|
[interpolation]: /documentation/interpolation
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'interpolation' %}
|
{% codeExample 'interpolation' %}
|
||||||
@mixin prefix($property, $value, $prefixes) {
|
@mixin prefix($property, $value, $prefixes) {
|
||||||
@ -57,15 +55,13 @@ introduction: >
|
|||||||
@include prefix(filter, grayscale(50%), moz webkit)
|
@include prefix(filter, grayscale(50%), moz webkit)
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
## Nesting
|
||||||
## Nesting
|
|
||||||
|
|
||||||
Many CSS properties start with the same prefix that acts as a kind of
|
Many CSS properties start with the same prefix that acts as a kind of namespace.
|
||||||
namespace. For example, `font-family`, `font-size`, and `font-weight` all
|
For example, `font-family`, `font-size`, and `font-weight` all start with
|
||||||
start with `font-`. Sass makes this easier and less redundant by allowing
|
`font-`. Sass makes this easier and less redundant by allowing property
|
||||||
property declarations to be nested. The outer property names are added to the
|
declarations to be nested. The outer property names are added to the inner,
|
||||||
inner, separated by a hyphen.
|
separated by a hyphen.
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'nesting' %}
|
{% codeExample 'nesting' %}
|
||||||
.enlarge {
|
.enlarge {
|
||||||
@ -90,11 +86,9 @@ introduction: >
|
|||||||
font-size: 36px
|
font-size: 36px
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
Some of these CSS properties have shorthand versions that use the namespace as
|
||||||
Some of these CSS properties have shorthand versions that use the namespace as
|
the property name. For these, you can write both the shorthand value *and* the
|
||||||
the property name. For these, you can write both the shorthand value *and* the
|
more explicit nested versions.
|
||||||
more explicit nested versions.
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'nesting-shorthand' %}
|
{% codeExample 'nesting-shorthand' %}
|
||||||
.info-page {
|
.info-page {
|
||||||
@ -110,16 +104,14 @@ introduction: >
|
|||||||
top: 2px
|
top: 2px
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
## Hidden Declarations
|
||||||
## Hidden Declarations
|
|
||||||
|
|
||||||
Sometimes you only want a property declaration to show up some of the time. If
|
Sometimes you only want a property declaration to show up some of the time. If a
|
||||||
a declaration's value is [`null`][] or an empty [unquoted string][], Sass
|
declaration's value is [`null`][] or an empty [unquoted string][], Sass won't
|
||||||
won't compile that declaration to CSS at all.
|
compile that declaration to CSS at all.
|
||||||
|
|
||||||
[`null`]: /documentation/values/null
|
[`null`]: /documentation/values/null
|
||||||
[unquoted string]: /documentation/values/strings#unquoted
|
[unquoted string]: /documentation/values/strings#unquoted
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'hidden-declarations' %}
|
{% codeExample 'hidden-declarations' %}
|
||||||
$rounded-corners: false;
|
$rounded-corners: false;
|
||||||
@ -136,37 +128,34 @@ introduction: >
|
|||||||
border-radius: if($rounded-corners, 5px, null)
|
border-radius: if($rounded-corners, 5px, null)
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
## Custom Properties
|
||||||
## Custom Properties
|
|
||||||
|
|
||||||
{% compatibility 'dart: true', 'libsass: "3.5.0"', 'ruby: "3.5.0"', 'feature: "SassScript Syntax"' %}
|
{% compatibility 'dart: true', 'libsass: "3.5.0"', 'ruby: "3.5.0"', 'feature: "SassScript Syntax"' %}
|
||||||
Older versions of LibSass and Ruby Sass parsed custom property declarations
|
Older versions of LibSass and Ruby Sass parsed custom property declarations
|
||||||
just like any other property declaration, allowing the full range of
|
just like any other property declaration, allowing the full range of
|
||||||
SassScript expressions as values. Even when using these versions, it's
|
SassScript expressions as values. Even when using these versions, it's
|
||||||
recommended that you use interpolation to inject SassScript values for
|
recommended that you use interpolation to inject SassScript values for
|
||||||
forwards-compatibility.
|
forwards-compatibility.
|
||||||
|
|
||||||
See [the breaking change page][] for more details.
|
See [the breaking change page][] for more details.
|
||||||
|
|
||||||
[the breaking change page]: /documentation/breaking-changes/css-vars
|
[the breaking change page]: /documentation/breaking-changes/css-vars
|
||||||
{% endcompatibility %}
|
{% endcompatibility %}
|
||||||
|
|
||||||
[CSS custom properties][], also known as CSS variables, have an unusual
|
[CSS custom properties][], also known as CSS variables, have an unusual
|
||||||
declaration syntax: they allow almost any text at all in their declaration
|
declaration syntax: they allow almost any text at all in their declaration
|
||||||
values. What's more, those values are accessible to JavaScript, so any value
|
values. What's more, those values are accessible to JavaScript, so any value
|
||||||
might potentially be relevant to the user. This includes values that would
|
might potentially be relevant to the user. This includes values that would
|
||||||
normally be parsed as SassScript.
|
normally be parsed as SassScript.
|
||||||
|
|
||||||
[CSS Custom Properties]: https://developer.mozilla.org/en-US/docs/Web/CSS/--*
|
[CSS Custom Properties]: https://developer.mozilla.org/en-US/docs/Web/CSS/--*
|
||||||
|
|
||||||
Because of this, Sass parses custom property declarations differently than
|
Because of this, Sass parses custom property declarations differently than other
|
||||||
other property declarations. All tokens, including those that look like
|
property declarations. All tokens, including those that look like SassScript,
|
||||||
SassScript, are passed through to CSS as-is. The only exception is
|
are passed through to CSS as-is. The only exception is [interpolation][], which
|
||||||
[interpolation][], which is the only way to inject dynamic values into a
|
is the only way to inject dynamic values into a custom property.
|
||||||
custom property.
|
|
||||||
|
|
||||||
[interpolation]: /documentation/interpolation
|
[interpolation]: /documentation/interpolation
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'custom-properties' %}
|
{% codeExample 'custom-properties' %}
|
||||||
$primary: #81899b;
|
$primary: #81899b;
|
||||||
@ -197,16 +186,14 @@ introduction: >
|
|||||||
--consumed-by-js: $primary
|
--consumed-by-js: $primary
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% headsUp false %}
|
{% headsUp %}
|
||||||
{% markdown %}
|
Unfortunately, [interpolation][] removes quotes from strings, which makes it
|
||||||
Unfortunately, [interpolation][] removes quotes from strings, which makes it
|
difficult to use quoted strings as values for custom properties when they come
|
||||||
difficult to use quoted strings as values for custom properties when they
|
from Sass variables. As a workaround, you can use the [`meta.inspect()`
|
||||||
come from Sass variables. As a workaround, you can use the [`meta.inspect()`
|
function][] to preserve the quotes.
|
||||||
function][] to preserve the quotes.
|
|
||||||
|
|
||||||
[interpolation]: /documentation/interpolation
|
[interpolation]: /documentation/interpolation
|
||||||
[`meta.inspect()` function]: /documentation/modules/meta#inspect
|
[`meta.inspect()` function]: /documentation/modules/meta#inspect
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'custom-properties-strings-meta' %}
|
{% codeExample 'custom-properties-strings-meta' %}
|
||||||
@use "sass:meta";
|
@use "sass:meta";
|
@ -23,14 +23,11 @@ introduction: >
|
|||||||
border: 1px solid #e1e4e8
|
border: 1px solid #e1e4e8
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
## Nesting
|
||||||
## Nesting
|
|
||||||
|
|
||||||
But Sass wants to make your life easier. Rather than repeating the same
|
But Sass wants to make your life easier. Rather than repeating the same
|
||||||
selectors over and over again, you can write one style rules inside another.
|
selectors over and over again, you can write one style rules inside another.
|
||||||
Sass will automatically combine the outer rule's selector with the inner
|
Sass will automatically combine the outer rule's selector with the inner rule's.
|
||||||
rule's.
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% render 'code_snippets/example-nesting' %}
|
{% render 'code_snippets/example-nesting' %}
|
||||||
|
|
||||||
@ -41,14 +38,11 @@ introduction: >
|
|||||||
render it. Keep those selectors shallow!
|
render it. Keep those selectors shallow!
|
||||||
{% endheadsUp %}
|
{% endheadsUp %}
|
||||||
|
|
||||||
{% markdown %}
|
### Selector Lists
|
||||||
### Selector Lists
|
|
||||||
|
|
||||||
Nested rules are clever about handling selector lists (that is,
|
Nested rules are clever about handling selector lists (that is, comma-separated
|
||||||
comma-separated selectors). Each complex selector (the ones between the
|
selectors). Each complex selector (the ones between the commas) is nested
|
||||||
commas) is nested separately, and then they're combined back into a selector
|
separately, and then they're combined back into a selector list.
|
||||||
list.
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'selector-lists' %}
|
{% codeExample 'selector-lists' %}
|
||||||
.alert, .warning {
|
.alert, .warning {
|
||||||
@ -66,15 +60,13 @@ introduction: >
|
|||||||
padding-bottom: 0
|
padding-bottom: 0
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
### Selector Combinators
|
||||||
### Selector Combinators
|
|
||||||
|
|
||||||
You can nest selectors that use [combinators][] as well. You can put the
|
You can nest selectors that use [combinators][] as well. You can put the
|
||||||
combinator at the end of the outer selector, at the beginning of the inner
|
combinator at the end of the outer selector, at the beginning of the inner
|
||||||
selector, or even all on its own in between the two.
|
selector, or even all on its own in between the two.
|
||||||
|
|
||||||
[combinators]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors#Combinators#Combinators
|
[combinators]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors#Combinators#Combinators
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'selector-combinators' %}
|
{% codeExample 'selector-combinators' %}
|
||||||
ul > {
|
ul > {
|
||||||
@ -115,27 +107,24 @@ introduction: >
|
|||||||
opacity: 0.8
|
opacity: 0.8
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
### Advanced Nesting
|
||||||
### Advanced Nesting
|
|
||||||
|
|
||||||
If you want to do more with your nested style rules than just combine them in
|
If you want to do more with your nested style rules than just combine them in
|
||||||
order with the descendant combinator (that is, a plain space) separating them,
|
order with the descendant combinator (that is, a plain space) separating them,
|
||||||
Sass has your back. See the [parent selector documentation][] for more
|
Sass has your back. See the [parent selector documentation][] for more details.
|
||||||
details.
|
|
||||||
|
|
||||||
[parent selector documentation]: /documentation/style-rules/parent-selector
|
[parent selector documentation]: /documentation/style-rules/parent-selector
|
||||||
|
|
||||||
## Interpolation
|
## Interpolation
|
||||||
|
|
||||||
You can use [interpolation][] to inject values from [expressions][] like
|
You can use [interpolation][] to inject values from [expressions][] like
|
||||||
variables and function calls into your selectors. This is particularly useful
|
variables and function calls into your selectors. This is particularly useful
|
||||||
when you're writing [mixins][], since it allows you to create selectors from
|
when you're writing [mixins][], since it allows you to create selectors from
|
||||||
parameters your users pass in.
|
parameters your users pass in.
|
||||||
|
|
||||||
[interpolation]: /documentation/interpolation
|
[interpolation]: /documentation/interpolation
|
||||||
[expressions]: /documentation/syntax/structure#expressions
|
[expressions]: /documentation/syntax/structure#expressions
|
||||||
[mixins]: /documentation/at-rules/mixin
|
[mixins]: /documentation/at-rules/mixin
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'interpolation' %}
|
{% codeExample 'interpolation' %}
|
||||||
@mixin define-emoji($name, $glyph) {
|
@mixin define-emoji($name, $glyph) {
|
||||||
@ -167,13 +156,11 @@ introduction: >
|
|||||||
worrying that it won't parse.
|
worrying that it won't parse.
|
||||||
{% endfunFact %}
|
{% endfunFact %}
|
||||||
|
|
||||||
{% markdown %}
|
You can combine interpolation with the parent selector `&`, the [`@at-root`
|
||||||
You can combine interpolation with the parent selector `&`, the [`@at-root`
|
rule][], and [selector functions][] to wield some serious power when dynamically
|
||||||
rule][], and [selector functions][] to wield some serious power when
|
generating selectors. For more information, see the [parent selector
|
||||||
dynamically generating selectors. For more information, see the [parent
|
documentation][].
|
||||||
selector documentation][].
|
|
||||||
|
|
||||||
[`@at-root` rule]: /documentation/at-rules/at-root
|
[`@at-root` rule]: /documentation/at-rules/at-root
|
||||||
[selector functions]: /documentation/modules/selector
|
[selector functions]: /documentation/modules/selector
|
||||||
[parent selector documentation]: /documentation/style-rules/parent-selector
|
[parent selector documentation]: /documentation/style-rules/parent-selector
|
||||||
{% endmarkdown %}
|
|
@ -9,11 +9,9 @@ introduction: >
|
|||||||
or adding a selector *before* the parent.
|
or adding a selector *before* the parent.
|
||||||
---
|
---
|
||||||
|
|
||||||
{% markdown %}
|
When a parent selector is used in an inner selector, it's replaced with the
|
||||||
When a parent selector is used in an inner selector, it's replaced with the
|
corresponding outer selector. This happens instead of the normal nesting
|
||||||
corresponding outer selector. This happens instead of the normal nesting
|
behavior.
|
||||||
behavior.
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'parent-selector' %}
|
{% codeExample 'parent-selector' %}
|
||||||
.alert {
|
.alert {
|
||||||
@ -66,17 +64,15 @@ introduction: >
|
|||||||
[this GitHub issue]: https://github.com/sass/sass/issues/1425
|
[this GitHub issue]: https://github.com/sass/sass/issues/1425
|
||||||
{% endheadsUp %}
|
{% endheadsUp %}
|
||||||
|
|
||||||
{% markdown %}
|
## Adding Suffixes
|
||||||
## Adding Suffixes
|
|
||||||
|
|
||||||
You can also use the parent selector to add extra suffixes to the outer
|
You can also use the parent selector to add extra suffixes to the outer
|
||||||
selector. This is particularly useful when using a methodology like [BEM][]
|
selector. This is particularly useful when using a methodology like [BEM][] that
|
||||||
that uses highly structured class names. As long as the outer selector ends
|
uses highly structured class names. As long as the outer selector ends with an
|
||||||
with an alphanumeric name (like class, ID, and element selectors), you can use
|
alphanumeric name (like class, ID, and element selectors), you can use the
|
||||||
the parent selector to append additional text.
|
parent selector to append additional text.
|
||||||
|
|
||||||
[BEM]: http://getbem.com/
|
[BEM]: http://getbem.com/
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'parent-selector-suffixes' %}
|
{% codeExample 'parent-selector-suffixes' %}
|
||||||
.accordion {
|
.accordion {
|
||||||
@ -119,17 +115,15 @@ introduction: >
|
|||||||
display: block
|
display: block
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
## In SassScript
|
||||||
## In SassScript
|
|
||||||
|
|
||||||
The parent selector can also be used within SassScript. It's a special
|
The parent selector can also be used within SassScript. It's a special
|
||||||
expression that returns the current parent selector in the same format used by
|
expression that returns the current parent selector in the same format used by
|
||||||
[selector functions][]: a comma-separated list (the selector list) that
|
[selector functions][]: a comma-separated list (the selector list) that contains
|
||||||
contains space-separated lists (the complex selectors) that contain unquoted
|
space-separated lists (the complex selectors) that contain unquoted strings (the
|
||||||
strings (the compound selectors).
|
compound selectors).
|
||||||
|
|
||||||
[selector functions]: /documentation/modules/selector#selector-values
|
[selector functions]: /documentation/modules/selector#selector-values
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'parent-selector-sassscript' %}
|
{% codeExample 'parent-selector-sassscript' %}
|
||||||
.main aside:hover,
|
.main aside:hover,
|
||||||
@ -146,27 +140,23 @@ introduction: >
|
|||||||
// (unquote(".sidebar") unquote("p")))
|
// (unquote(".sidebar") unquote("p")))
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
If the `&` expression is used outside any style rules, it returns `null`. Since
|
||||||
If the `&` expression is used outside any style rules, it returns `null`.
|
`null` is [falsey][], this means you can easily use it to determine whether a
|
||||||
Since `null` is [falsey][], this means you can easily use it to determine
|
mixin is being called in a style rule or not.
|
||||||
whether a mixin is being called in a style rule or not.
|
|
||||||
|
|
||||||
[falsey]: /documentation/at-rules/control/if#truthiness-and-falsiness
|
[falsey]: /documentation/at-rules/control/if#truthiness-and-falsiness
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% render 'code_snippets/example-if-parent-selector' %}
|
{% render 'code_snippets/example-if-parent-selector' %}
|
||||||
|
|
||||||
{% markdown %}
|
### Advanced Nesting
|
||||||
### Advanced Nesting
|
|
||||||
|
|
||||||
You can use `&` as a normal SassScript expression, which means you can pass it
|
You can use `&` as a normal SassScript expression, which means you can pass it
|
||||||
to functions or include it in interpolation—even in other selectors! Using it
|
to functions or include it in interpolation—even in other selectors! Using it in
|
||||||
in combination with [selector functions][] and the [`@at-root` rule][] allows
|
combination with [selector functions][] and the [`@at-root` rule][] allows you
|
||||||
you to nest selectors in very powerful ways.
|
to nest selectors in very powerful ways.
|
||||||
|
|
||||||
[selector functions]: /documentation/modules/selector#selector-values
|
[selector functions]: /documentation/modules/selector#selector-values
|
||||||
[`@at-root` rule]: /documentation/at-rules/at-root
|
[`@at-root` rule]: /documentation/at-rules/at-root
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% render 'code_snippets/example-advanced-nesting' %}
|
{% render 'code_snippets/example-advanced-nesting' %}
|
||||||
|
|
@ -10,14 +10,12 @@ introduction: >
|
|||||||
|
|
||||||
{% render 'code_snippets/example-placeholder' %}
|
{% render 'code_snippets/example-placeholder' %}
|
||||||
|
|
||||||
{% markdown %}
|
What's the use of a selector that isn't emitted? It can still be [extended][]!
|
||||||
What's the use of a selector that isn't emitted? It can still be [extended][]!
|
Unlike class selectors, placeholders don't clutter up the CSS if they aren't
|
||||||
Unlike class selectors, placeholders don't clutter up the CSS if they aren't
|
extended and they don't mandate that users of a library use specific class names
|
||||||
extended and they don't mandate that users of a library use specific class
|
for their HTML.
|
||||||
names for their HTML.
|
|
||||||
|
|
||||||
[extended]: /documentation/at-rules/extend
|
[extended]: /documentation/at-rules/extend
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'extended-selector' %}
|
{% codeExample 'extended-selector' %}
|
||||||
%toolbelt {
|
%toolbelt {
|
||||||
@ -58,9 +56,7 @@ introduction: >
|
|||||||
color: #cddc39
|
color: #cddc39
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
Placeholder selectors are useful when writing a Sass library where each style
|
||||||
Placeholder selectors are useful when writing a Sass library where each style
|
rule may or may not be used. As a rule of thumb, if you're writing a stylesheet
|
||||||
rule may or may not be used. As a rule of thumb, if you're writing a
|
just for your own app, it's often better to just extend a class selector if one
|
||||||
stylesheet just for your own app, it's often better to just extend a class
|
is available.
|
||||||
selector if one is available.
|
|
||||||
{% endmarkdown %}
|
|
@ -1,141 +0,0 @@
|
|||||||
---
|
|
||||||
title: Comments
|
|
||||||
introduction: >
|
|
||||||
The way Sass comments work differs substantially between SCSS and the indented
|
|
||||||
syntax. Both syntaxes support two types of comments: comments defined using
|
|
||||||
`/* */` that are (usually) compiled to CSS, and comments defined using `//`
|
|
||||||
that are not.
|
|
||||||
---
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
## In SCSS
|
|
||||||
|
|
||||||
Comments in SCSS work similarly to comments in other languages like
|
|
||||||
JavaScript. **Single-line comments** start with `//`, and go until the end of
|
|
||||||
the line. Nothing in a single-line comment is emitted as CSS; as far as Sass
|
|
||||||
is concerned, they may as well not exist. They're also called **silent
|
|
||||||
comments**, because they don't produce any CSS.
|
|
||||||
|
|
||||||
**Multi-line comments** start with `/*` and end at the next `*/`. If a
|
|
||||||
multi-line comment is written somewhere that a [statement][] is allowed, it's
|
|
||||||
compiled to a CSS comment. They're also called **loud comment**, by contrast
|
|
||||||
with silent comments. A multi-line comment that's compiled to CSS may contain
|
|
||||||
[interpolation][], which will be evaluated before the comment is compiled.
|
|
||||||
|
|
||||||
By default, multi-line comments will be stripped from the compiled CSS in
|
|
||||||
[compressed mode][]. If a comment begins with `/*!`, though, it will always be
|
|
||||||
included in the CSS output.
|
|
||||||
|
|
||||||
[statement]: /documentation/syntax/structure#statements
|
|
||||||
[interpolation]: /documentation/interpolation
|
|
||||||
[compressed mode]: /documentation/cli/dart-sass/#style
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'scss-comment', true, 'scss' %}
|
|
||||||
// This comment won't be included in the CSS.
|
|
||||||
|
|
||||||
/* But this comment will, except in compressed mode. */
|
|
||||||
|
|
||||||
/* It can also contain interpolation:
|
|
||||||
* 1 + 1 = #{1 + 1} */
|
|
||||||
|
|
||||||
/*! This comment will be included even in compressed mode. */
|
|
||||||
|
|
||||||
p /* Multi-line comments can be written anywhere
|
|
||||||
* whitespace is allowed. */ .sans {
|
|
||||||
font: Helvetica, // So can single-line comments.
|
|
||||||
sans-serif;
|
|
||||||
}
|
|
||||||
{% endcodeExample %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
## In Sass
|
|
||||||
|
|
||||||
Comments in the indented syntax work a little differently: they're
|
|
||||||
indentation-based, just like the rest of the syntax. Like SCSS, silent
|
|
||||||
comments written with `//` are never emitted as CSS, but unlike SCSS
|
|
||||||
everything indented beneath the opening `//` is also commented out.
|
|
||||||
|
|
||||||
Indented syntax comments that start with `/*` work with indentation the same
|
|
||||||
way, except that they are compiled to CSS. Because the extent of the comment
|
|
||||||
is based on indentation, the closing `*/` is optional. Also like SCSS, `/*`
|
|
||||||
comments can contain [interpolation][] and can start with `/*!` to avoid being
|
|
||||||
stripped in compressed mode.
|
|
||||||
|
|
||||||
Comments can also be used within [expressions][] in the indented syntax. In
|
|
||||||
this case, they have exactly the same syntax as they do in SCSS.
|
|
||||||
|
|
||||||
[interpolation]: /documentation/interpolation
|
|
||||||
[expressions]: /documentation/syntax/structure#expressions
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'sass-comment', true, 'sass' %}
|
|
||||||
// This comment won't be included in the CSS.
|
|
||||||
This is also commented out.
|
|
||||||
|
|
||||||
/* But this comment will, except in compressed mode.
|
|
||||||
|
|
||||||
/* It can also contain interpolation:
|
|
||||||
1 + 1 = #{1 + 1}
|
|
||||||
|
|
||||||
/*! This comment will be included even in compressed mode.
|
|
||||||
|
|
||||||
p .sans
|
|
||||||
font: Helvetica, /* Inline comments must be closed. */ sans-serif
|
|
||||||
{% endcodeExample %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
## Documentation Comments
|
|
||||||
|
|
||||||
When writing style libraries using Sass, you can use comments to document the
|
|
||||||
[mixins][], [functions][], [variables][], and [placeholder selectors][] that
|
|
||||||
your library provides, as well as the library itself. These comments are read
|
|
||||||
by the [SassDoc][] tool, which uses them to generate beautiful documentation.
|
|
||||||
Check out [the Susy grid engine][susy]'s documentation to see it in action!
|
|
||||||
|
|
||||||
[mixins]: /documentation/at-rules/mixin
|
|
||||||
[functions]: /documentation/at-rules/function
|
|
||||||
[variables]: /documentation/variables
|
|
||||||
[placeholder selectors]: /documentation/style-rules/placeholder-selectors
|
|
||||||
[SassDoc]: http://sassdoc.com
|
|
||||||
[susy]: http://oddbird.net/susy/docs/index.html
|
|
||||||
|
|
||||||
Documentation comments are silent comments, written with three slashes (`///`)
|
|
||||||
directly above the thing you're documenting. SassDoc parses text in the
|
|
||||||
comments as [Markdown][], and supports many useful [annotations][] to describe
|
|
||||||
it in detail.
|
|
||||||
|
|
||||||
[Markdown]: https://www.markdownguide.org/getting-started
|
|
||||||
[annotations]: http://sassdoc.com/annotations/
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'documentation-comment' %}
|
|
||||||
/// Computes an exponent.
|
|
||||||
///
|
|
||||||
/// @param {number} $base
|
|
||||||
/// The number to multiply by itself.
|
|
||||||
/// @param {integer (unitless)} $exponent
|
|
||||||
/// The number of `$base`s to multiply together.
|
|
||||||
/// @return {number} `$base` to the power of `$exponent`.
|
|
||||||
@function pow($base, $exponent) {
|
|
||||||
$result: 1;
|
|
||||||
@for $_ from 1 through $exponent {
|
|
||||||
$result: $result * $base;
|
|
||||||
}
|
|
||||||
@return $result;
|
|
||||||
}
|
|
||||||
===
|
|
||||||
/// Computes an exponent.
|
|
||||||
///
|
|
||||||
/// @param {number} $base
|
|
||||||
/// The number to multiply by itself.
|
|
||||||
/// @param {integer (unitless)} $exponent
|
|
||||||
/// The number of `$base`s to multiply together.
|
|
||||||
/// @return {number} `$base` to the power of `$exponent`.
|
|
||||||
@function pow($base, $exponent)
|
|
||||||
$result: 1
|
|
||||||
@for $_ from 1 through $exponent
|
|
||||||
$result: $result * $base
|
|
||||||
|
|
||||||
@return $result
|
|
||||||
{% endcodeExample %}
|
|
135
source/documentation/syntax/comments.md
Normal file
135
source/documentation/syntax/comments.md
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
---
|
||||||
|
title: Comments
|
||||||
|
introduction: >
|
||||||
|
The way Sass comments work differs substantially between SCSS and the indented
|
||||||
|
syntax. Both syntaxes support two types of comments: comments defined using
|
||||||
|
`/* */` that are (usually) compiled to CSS, and comments defined using `//`
|
||||||
|
that are not.
|
||||||
|
---
|
||||||
|
|
||||||
|
## In SCSS
|
||||||
|
|
||||||
|
Comments in SCSS work similarly to comments in other languages like JavaScript.
|
||||||
|
**Single-line comments** start with `//`, and go until the end of the line.
|
||||||
|
Nothing in a single-line comment is emitted as CSS; as far as Sass is concerned,
|
||||||
|
they may as well not exist. They're also called **silent comments**, because
|
||||||
|
they don't produce any CSS.
|
||||||
|
|
||||||
|
**Multi-line comments** start with `/*` and end at the next `*/`. If a
|
||||||
|
multi-line comment is written somewhere that a [statement][] is allowed, it's
|
||||||
|
compiled to a CSS comment. They're also called **loud comment**, by contrast
|
||||||
|
with silent comments. A multi-line comment that's compiled to CSS may contain
|
||||||
|
[interpolation][], which will be evaluated before the comment is compiled.
|
||||||
|
|
||||||
|
By default, multi-line comments will be stripped from the compiled CSS in
|
||||||
|
[compressed mode][]. If a comment begins with `/*!`, though, it will always be
|
||||||
|
included in the CSS output.
|
||||||
|
|
||||||
|
[statement]: /documentation/syntax/structure#statements
|
||||||
|
[interpolation]: /documentation/interpolation
|
||||||
|
[compressed mode]: /documentation/cli/dart-sass/#style
|
||||||
|
|
||||||
|
{% codeExample 'scss-comment', true, 'scss' %}
|
||||||
|
// This comment won't be included in the CSS.
|
||||||
|
|
||||||
|
/* But this comment will, except in compressed mode. */
|
||||||
|
|
||||||
|
/* It can also contain interpolation:
|
||||||
|
* 1 + 1 = #{1 + 1} */
|
||||||
|
|
||||||
|
/*! This comment will be included even in compressed mode. */
|
||||||
|
|
||||||
|
p /* Multi-line comments can be written anywhere
|
||||||
|
* whitespace is allowed. */ .sans {
|
||||||
|
font: Helvetica, // So can single-line comments.
|
||||||
|
sans-serif;
|
||||||
|
}
|
||||||
|
{% endcodeExample %}
|
||||||
|
|
||||||
|
## In Sass
|
||||||
|
|
||||||
|
Comments in the indented syntax work a little differently: they're
|
||||||
|
indentation-based, just like the rest of the syntax. Like SCSS, silent comments
|
||||||
|
written with `//` are never emitted as CSS, but unlike SCSS everything indented
|
||||||
|
beneath the opening `//` is also commented out.
|
||||||
|
|
||||||
|
Indented syntax comments that start with `/*` work with indentation the same
|
||||||
|
way, except that they are compiled to CSS. Because the extent of the comment is
|
||||||
|
based on indentation, the closing `*/` is optional. Also like SCSS, `/*`
|
||||||
|
comments can contain [interpolation][] and can start with `/*!` to avoid being
|
||||||
|
stripped in compressed mode.
|
||||||
|
|
||||||
|
Comments can also be used within [expressions][] in the indented syntax. In this
|
||||||
|
case, they have exactly the same syntax as they do in SCSS.
|
||||||
|
|
||||||
|
[interpolation]: /documentation/interpolation
|
||||||
|
[expressions]: /documentation/syntax/structure#expressions
|
||||||
|
|
||||||
|
{% codeExample 'sass-comment', true, 'sass' %}
|
||||||
|
// This comment won't be included in the CSS.
|
||||||
|
This is also commented out.
|
||||||
|
|
||||||
|
/* But this comment will, except in compressed mode.
|
||||||
|
|
||||||
|
/* It can also contain interpolation:
|
||||||
|
1 + 1 = #{1 + 1}
|
||||||
|
|
||||||
|
/*! This comment will be included even in compressed mode.
|
||||||
|
|
||||||
|
p .sans
|
||||||
|
font: Helvetica, /* Inline comments must be closed. */ sans-serif
|
||||||
|
{% endcodeExample %}
|
||||||
|
|
||||||
|
## Documentation Comments
|
||||||
|
|
||||||
|
When writing style libraries using Sass, you can use comments to document the
|
||||||
|
[mixins][], [functions][], [variables][], and [placeholder selectors][] that
|
||||||
|
your library provides, as well as the library itself. These comments are read by
|
||||||
|
the [SassDoc][] tool, which uses them to generate beautiful documentation. Check
|
||||||
|
out [the Susy grid engine][susy]'s documentation to see it in action!
|
||||||
|
|
||||||
|
[mixins]: /documentation/at-rules/mixin
|
||||||
|
[functions]: /documentation/at-rules/function
|
||||||
|
[variables]: /documentation/variables
|
||||||
|
[placeholder selectors]: /documentation/style-rules/placeholder-selectors
|
||||||
|
[SassDoc]: http://sassdoc.com
|
||||||
|
[susy]: http://oddbird.net/susy/docs/index.html
|
||||||
|
|
||||||
|
Documentation comments are silent comments, written with three slashes (`///`)
|
||||||
|
directly above the thing you're documenting. SassDoc parses text in the comments
|
||||||
|
as [Markdown][], and supports many useful [annotations][] to describe it in
|
||||||
|
detail.
|
||||||
|
|
||||||
|
[Markdown]: https://www.markdownguide.org/getting-started
|
||||||
|
[annotations]: http://sassdoc.com/annotations/
|
||||||
|
|
||||||
|
{% codeExample 'documentation-comment' %}
|
||||||
|
/// Computes an exponent.
|
||||||
|
///
|
||||||
|
/// @param {number} $base
|
||||||
|
/// The number to multiply by itself.
|
||||||
|
/// @param {integer (unitless)} $exponent
|
||||||
|
/// The number of `$base`s to multiply together.
|
||||||
|
/// @return {number} `$base` to the power of `$exponent`.
|
||||||
|
@function pow($base, $exponent) {
|
||||||
|
$result: 1;
|
||||||
|
@for $_ from 1 through $exponent {
|
||||||
|
$result: $result * $base;
|
||||||
|
}
|
||||||
|
@return $result;
|
||||||
|
}
|
||||||
|
===
|
||||||
|
/// Computes an exponent.
|
||||||
|
///
|
||||||
|
/// @param {number} $base
|
||||||
|
/// The number to multiply by itself.
|
||||||
|
/// @param {integer (unitless)} $exponent
|
||||||
|
/// The number of `$base`s to multiply together.
|
||||||
|
/// @return {number} `$base` to the power of `$exponent`.
|
||||||
|
@function pow($base, $exponent)
|
||||||
|
$result: 1
|
||||||
|
@for $_ from 1 through $exponent
|
||||||
|
$result: $result * $base
|
||||||
|
|
||||||
|
@return $result
|
||||||
|
{% endcodeExample %}
|
@ -1,148 +0,0 @@
|
|||||||
---
|
|
||||||
title: Special Functions
|
|
||||||
table_of_contents: true
|
|
||||||
introduction: >
|
|
||||||
CSS defines many functions, and most of them work just fine with Sass’s normal
|
|
||||||
function syntax. They’re parsed as function calls, resolved to [plain CSS
|
|
||||||
functions](/documentation/at-rules/function/#plain-css-functions), and compiled
|
|
||||||
as-is to CSS. There are a few exceptions, though, which have special syntax
|
|
||||||
that can’t just be parsed as a [SassScript
|
|
||||||
expression](/documentation/syntax/structure#expressions). All special function
|
|
||||||
calls return [unquoted strings](/documentation/values/strings#unquoted).
|
|
||||||
---
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
## `url()`
|
|
||||||
|
|
||||||
The [`url()` function][] is commonly used in CSS, but its syntax is different
|
|
||||||
than other functions: it can take either a quoted *or* unquoted URL. Because
|
|
||||||
an unquoted URL isn't a valid SassScript expression, Sass needs special logic
|
|
||||||
to parse it.
|
|
||||||
|
|
||||||
[`url()` function]: https://developer.mozilla.org/en-US/docs/Web/CSS/url
|
|
||||||
|
|
||||||
If the `url()`'s argument is a valid unquoted URL, Sass parses it as-is,
|
|
||||||
although [interpolation][] may also be used to inject SassScript values. If
|
|
||||||
it's not a valid unquoted URL—for example, if it contains [variables][] or
|
|
||||||
[function calls][]—it's parsed as a normal [plain CSS function call][].
|
|
||||||
|
|
||||||
[interpolation]: /documentation/interpolation
|
|
||||||
[variables]: /documentation/variables
|
|
||||||
[function calls]: /documentation/at-rules/function
|
|
||||||
[plain CSS function call]: /documentation/at-rules/function/#plain-css-functions
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'url' %}
|
|
||||||
$roboto-font-path: "../fonts/roboto";
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
// This is parsed as a normal function call that takes a quoted string.
|
|
||||||
src: url("#{$roboto-font-path}/Roboto-Thin.woff2") format("woff2");
|
|
||||||
|
|
||||||
font-family: "Roboto";
|
|
||||||
font-weight: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
// This is parsed as a normal function call that takes an arithmetic
|
|
||||||
// expression.
|
|
||||||
src: url($roboto-font-path + "/Roboto-Light.woff2") format("woff2");
|
|
||||||
|
|
||||||
font-family: "Roboto";
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
// This is parsed as an interpolated special function.
|
|
||||||
src: url(#{$roboto-font-path}/Roboto-Regular.woff2) format("woff2");
|
|
||||||
|
|
||||||
font-family: "Roboto";
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
===
|
|
||||||
$roboto-font-path: "../fonts/roboto"
|
|
||||||
|
|
||||||
@font-face
|
|
||||||
// This is parsed as a normal function call that takes a quoted string.
|
|
||||||
src: url("#{$roboto-font-path}/Roboto-Thin.woff2") format("woff2")
|
|
||||||
|
|
||||||
font-family: "Roboto"
|
|
||||||
font-weight: 100
|
|
||||||
|
|
||||||
|
|
||||||
@font-face
|
|
||||||
// This is parsed as a normal function call that takes an arithmetic
|
|
||||||
// expression.
|
|
||||||
src: url($roboto-font-path + "/Roboto-Light.woff2") format("woff2")
|
|
||||||
|
|
||||||
font-family: "Roboto"
|
|
||||||
font-weight: 300
|
|
||||||
|
|
||||||
|
|
||||||
@font-face
|
|
||||||
// This is parsed as an interpolated special function.
|
|
||||||
src: url(#{$roboto-font-path}/Roboto-Regular.woff2) format("woff2")
|
|
||||||
|
|
||||||
font-family: "Roboto"
|
|
||||||
font-weight: 400
|
|
||||||
{% endcodeExample %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
## `element()`, `progid:...()`, and `expression()`
|
|
||||||
|
|
||||||
{% compatibility 'dart: "<1.40.0"', 'libsass: false', 'ruby: false', 'feature: "calc()"' %}
|
|
||||||
LibSass, Ruby Sass, and versions of Dart Sass prior to 1.40.0 parse `calc()`
|
|
||||||
as special syntactic function like `element()`.
|
|
||||||
|
|
||||||
Dart Sass versions 1.40.0 and later parse `calc()` as a [calculation].
|
|
||||||
|
|
||||||
[calculation]: /documentation/values/calculations
|
|
||||||
{% endcompatibility %}
|
|
||||||
|
|
||||||
{% compatibility 'dart: ">=1.31.0 <1.40.0"', 'libsass: false', 'ruby: false', 'feature: "clamp()"' %}
|
|
||||||
LibSass, Ruby Sass, and versions of Dart Sass prior to 1.31.0 parse
|
|
||||||
`clamp()` as a [plain CSS function] rather than supporting special syntax
|
|
||||||
within it.
|
|
||||||
|
|
||||||
[plain CSS function]: /documentation/at-rules/function/#plain-css-functions
|
|
||||||
|
|
||||||
Dart Sass versions between 1.31.0 and 1.40.0 parse `clamp()` as special
|
|
||||||
syntactic function like `element()`.
|
|
||||||
|
|
||||||
Dart Sass versions 1.40.0 and later parse `clamp()` as a [calculation].
|
|
||||||
|
|
||||||
[calculation]: /documentation/values/calculations
|
|
||||||
{% endcompatibility %}
|
|
||||||
|
|
||||||
The [`element()`] function is defined in the CSS spec, and because its IDs
|
|
||||||
could be parsed as colors, they need special parsing.
|
|
||||||
|
|
||||||
[`element()`]: https://developer.mozilla.org/en-US/docs/Web/CSS/element
|
|
||||||
|
|
||||||
[`expression()`][] and functions beginning with [`progid:`][] are legacy
|
|
||||||
Internet Explorer features that use non-standard syntax. Although they're no
|
|
||||||
longer supported by recent browsers, Sass continues to parse them for
|
|
||||||
backwards compatibility.
|
|
||||||
|
|
||||||
[`expression()`]: https://blogs.msdn.microsoft.com/ie/2008/10/16/ending-expressions/
|
|
||||||
[`progid:`]: https://blogs.msdn.microsoft.com/ie/2009/02/19/the-css-corner-using-filters-in-ie8/
|
|
||||||
|
|
||||||
Sass allows *any text* in these function calls, including nested parentheses.
|
|
||||||
Nothing is interpreted as a SassScript expression, with the exception that
|
|
||||||
[interpolation][] can be used to inject dynamic values.
|
|
||||||
|
|
||||||
[interpolation]: /documentation/interpolation
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'element' %}
|
|
||||||
$logo-element: logo-bg;
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
background: element(##{$logo-element});
|
|
||||||
}
|
|
||||||
===
|
|
||||||
$logo-element: logo-bg
|
|
||||||
|
|
||||||
.logo
|
|
||||||
background: element(##{$logo-element})
|
|
||||||
{% endcodeExample %}
|
|
145
source/documentation/syntax/special-functions.md
Normal file
145
source/documentation/syntax/special-functions.md
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
---
|
||||||
|
title: Special Functions
|
||||||
|
table_of_contents: true
|
||||||
|
introduction: >
|
||||||
|
CSS defines many functions, and most of them work just fine with Sass’s normal
|
||||||
|
function syntax. They’re parsed as function calls, resolved to [plain CSS
|
||||||
|
functions](/documentation/at-rules/function/#plain-css-functions), and compiled
|
||||||
|
as-is to CSS. There are a few exceptions, though, which have special syntax
|
||||||
|
that can’t just be parsed as a [SassScript
|
||||||
|
expression](/documentation/syntax/structure#expressions). All special function
|
||||||
|
calls return [unquoted strings](/documentation/values/strings#unquoted).
|
||||||
|
---
|
||||||
|
|
||||||
|
## `url()`
|
||||||
|
|
||||||
|
The [`url()` function][] is commonly used in CSS, but its syntax is different
|
||||||
|
than other functions: it can take either a quoted *or* unquoted URL. Because an
|
||||||
|
unquoted URL isn't a valid SassScript expression, Sass needs special logic to
|
||||||
|
parse it.
|
||||||
|
|
||||||
|
[`url()` function]: https://developer.mozilla.org/en-US/docs/Web/CSS/url
|
||||||
|
|
||||||
|
If the `url()`'s argument is a valid unquoted URL, Sass parses it as-is,
|
||||||
|
although [interpolation][] may also be used to inject SassScript values. If it's
|
||||||
|
not a valid unquoted URL—for example, if it contains [variables][] or [function
|
||||||
|
calls][]—it's parsed as a normal [plain CSS function call][].
|
||||||
|
|
||||||
|
[interpolation]: /documentation/interpolation
|
||||||
|
[variables]: /documentation/variables
|
||||||
|
[function calls]: /documentation/at-rules/function
|
||||||
|
[plain CSS function call]: /documentation/at-rules/function/#plain-css-functions
|
||||||
|
|
||||||
|
{% codeExample 'url' %}
|
||||||
|
$roboto-font-path: "../fonts/roboto";
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
// This is parsed as a normal function call that takes a quoted string.
|
||||||
|
src: url("#{$roboto-font-path}/Roboto-Thin.woff2") format("woff2");
|
||||||
|
|
||||||
|
font-family: "Roboto";
|
||||||
|
font-weight: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
// This is parsed as a normal function call that takes an arithmetic
|
||||||
|
// expression.
|
||||||
|
src: url($roboto-font-path + "/Roboto-Light.woff2") format("woff2");
|
||||||
|
|
||||||
|
font-family: "Roboto";
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
// This is parsed as an interpolated special function.
|
||||||
|
src: url(#{$roboto-font-path}/Roboto-Regular.woff2) format("woff2");
|
||||||
|
|
||||||
|
font-family: "Roboto";
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
===
|
||||||
|
$roboto-font-path: "../fonts/roboto"
|
||||||
|
|
||||||
|
@font-face
|
||||||
|
// This is parsed as a normal function call that takes a quoted string.
|
||||||
|
src: url("#{$roboto-font-path}/Roboto-Thin.woff2") format("woff2")
|
||||||
|
|
||||||
|
font-family: "Roboto"
|
||||||
|
font-weight: 100
|
||||||
|
|
||||||
|
|
||||||
|
@font-face
|
||||||
|
// This is parsed as a normal function call that takes an arithmetic
|
||||||
|
// expression.
|
||||||
|
src: url($roboto-font-path + "/Roboto-Light.woff2") format("woff2")
|
||||||
|
|
||||||
|
font-family: "Roboto"
|
||||||
|
font-weight: 300
|
||||||
|
|
||||||
|
|
||||||
|
@font-face
|
||||||
|
// This is parsed as an interpolated special function.
|
||||||
|
src: url(#{$roboto-font-path}/Roboto-Regular.woff2) format("woff2")
|
||||||
|
|
||||||
|
font-family: "Roboto"
|
||||||
|
font-weight: 400
|
||||||
|
{% endcodeExample %}
|
||||||
|
|
||||||
|
## `element()`, `progid:...()`, and `expression()`
|
||||||
|
|
||||||
|
{% compatibility 'dart: "<1.40.0"', 'libsass: false', 'ruby: false', 'feature: "calc()"' %}
|
||||||
|
LibSass, Ruby Sass, and versions of Dart Sass prior to 1.40.0 parse `calc()`
|
||||||
|
as special syntactic function like `element()`.
|
||||||
|
|
||||||
|
Dart Sass versions 1.40.0 and later parse `calc()` as a [calculation].
|
||||||
|
|
||||||
|
[calculation]: /documentation/values/calculations
|
||||||
|
{% endcompatibility %}
|
||||||
|
|
||||||
|
{% compatibility 'dart: ">=1.31.0 <1.40.0"', 'libsass: false', 'ruby: false', 'feature: "clamp()"' %}
|
||||||
|
LibSass, Ruby Sass, and versions of Dart Sass prior to 1.31.0 parse `clamp()`
|
||||||
|
as a [plain CSS function] rather than supporting special syntax within it.
|
||||||
|
|
||||||
|
[plain CSS function]: /documentation/at-rules/function/#plain-css-functions
|
||||||
|
|
||||||
|
Dart Sass versions between 1.31.0 and 1.40.0 parse `clamp()` as special
|
||||||
|
syntactic function like `element()`.
|
||||||
|
|
||||||
|
Dart Sass versions 1.40.0 and later parse `clamp()` as a [calculation].
|
||||||
|
|
||||||
|
[calculation]: /documentation/values/calculations
|
||||||
|
{% endcompatibility %}
|
||||||
|
|
||||||
|
The [`element()`] function is defined in the CSS spec, and because its IDs could
|
||||||
|
be parsed as colors, they need special parsing.
|
||||||
|
|
||||||
|
[`element()`]: https://developer.mozilla.org/en-US/docs/Web/CSS/element
|
||||||
|
|
||||||
|
[`expression()`][] and functions beginning with [`progid:`][] are legacy
|
||||||
|
Internet Explorer features that use non-standard syntax. Although they're no
|
||||||
|
longer supported by recent browsers, Sass continues to parse them for backwards
|
||||||
|
compatibility.
|
||||||
|
|
||||||
|
[`expression()`]:
|
||||||
|
https://blogs.msdn.microsoft.com/ie/2008/10/16/ending-expressions/
|
||||||
|
[`progid:`]:
|
||||||
|
https://blogs.msdn.microsoft.com/ie/2009/02/19/the-css-corner-using-filters-in-ie8/
|
||||||
|
|
||||||
|
Sass allows *any text* in these function calls, including nested parentheses.
|
||||||
|
Nothing is interpreted as a SassScript expression, with the exception that
|
||||||
|
[interpolation][] can be used to inject dynamic values.
|
||||||
|
|
||||||
|
[interpolation]: /documentation/interpolation
|
||||||
|
|
||||||
|
{% codeExample 'element' %}
|
||||||
|
$logo-element: logo-bg;
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
background: element(##{$logo-element});
|
||||||
|
}
|
||||||
|
===
|
||||||
|
$logo-element: logo-bg
|
||||||
|
|
||||||
|
.logo
|
||||||
|
background: element(##{$logo-element})
|
||||||
|
{% endcodeExample %}
|
@ -25,14 +25,12 @@ introduction: >
|
|||||||
@debug math.comparable(100px, 3in) // true
|
@debug math.comparable(100px, 3in) // true
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
You can work with booleans using [boolean operators][]. The `and` operator
|
||||||
You can work with booleans using [boolean operators][]. The `and` operator
|
returns `true` if *both* sides are `true`, and the `or` operator returns `true`
|
||||||
returns `true` if *both* sides are `true`, and the `or` operator returns
|
if *either* side is `true`. The `not` operator returns the opposite of a single
|
||||||
`true` if *either* side is `true`. The `not` operator returns the opposite of
|
boolean value.
|
||||||
a single boolean value.
|
|
||||||
|
|
||||||
[boolean operators]: /documentation/operators/boolean
|
[boolean operators]: /documentation/operators/boolean
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'boolean-operators', false %}
|
{% codeExample 'boolean-operators', false %}
|
||||||
@debug true and true; // true
|
@debug true and true; // true
|
||||||
@ -54,23 +52,19 @@ introduction: >
|
|||||||
@debug not false // true
|
@debug not false // true
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
## Using Booleans
|
||||||
## Using Booleans
|
|
||||||
|
|
||||||
You can use booleans to choose whether or not to do various things in Sass.
|
You can use booleans to choose whether or not to do various things in Sass. The
|
||||||
The [`@if` rule][] evaluates a block of styles if its argument is `true`:
|
[`@if` rule][] evaluates a block of styles if its argument is `true`:
|
||||||
|
|
||||||
[`@if` rule]: /documentation/at-rules/control/if
|
[`@if` rule]: /documentation/at-rules/control/if
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% render 'code_snippets/example-if' %}
|
{% render 'code_snippets/example-if' %}
|
||||||
|
|
||||||
{% markdown %}
|
The [`if()` function][] returns one value if its argument is `true` and another
|
||||||
The [`if()` function][] returns one value if its argument is `true` and
|
if its argument is `false`:
|
||||||
another if its argument is `false`:
|
|
||||||
|
|
||||||
[`if()` function]: /documentation/modules#if
|
[`if()` function]: /documentation/modules#if
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'if-function', false %}
|
{% codeExample 'if-function', false %}
|
||||||
@debug if(true, 10px, 30px); // 10px
|
@debug if(true, 10px, 30px); // 10px
|
@ -1,253 +0,0 @@
|
|||||||
---
|
|
||||||
title: Calculations
|
|
||||||
introduction: >
|
|
||||||
Calculations are how Sass represents the `calc()` function, as well as similar
|
|
||||||
functions like `clamp()`, `min()`, and `max()`. Sass will simplify these as
|
|
||||||
much as possible, even if they're combined with one another.
|
|
||||||
---
|
|
||||||
|
|
||||||
{% compatibility 'dart: "1.40.0"', 'libsass: false', 'ruby: false' %}
|
|
||||||
LibSass, Ruby Sass, and versions of Dart Sass prior to 1.40.0 parse `calc()`
|
|
||||||
as a [special function] like `element()`.
|
|
||||||
|
|
||||||
[special function]: /documentation/syntax/special-functions#element-progid-and-expression
|
|
||||||
|
|
||||||
LibSass, Ruby Sass, and versions of Dart Sass prior to 1.31.0 parse `clamp()`
|
|
||||||
as a [plain CSS function] rather than supporting special syntax within it.
|
|
||||||
Versions of Dart Sass between 1.31.0 and 1.40.0 parse `clamp()` as a [special
|
|
||||||
function] like `element()`.
|
|
||||||
|
|
||||||
[plain CSS function]: /documentation/at-rules/function/#plain-css-functions
|
|
||||||
{% endcompatibility %}
|
|
||||||
|
|
||||||
{% codeExample 'calculations', false %}
|
|
||||||
@debug calc(400px + 10%); // calc(400px + 10%)
|
|
||||||
@debug calc(400px / 2); // 200px
|
|
||||||
@debug min(100px, calc(1rem + 10%)); // min(100px, 1rem + 10%)
|
|
||||||
===
|
|
||||||
@debug calc(400px + 10%) // calc(400px + 10%)
|
|
||||||
@debug calc(400px / 2) // 200px
|
|
||||||
@debug min(100px, calc(1rem + 10%) ; // min(100px, 1rem + 10%)
|
|
||||||
{% endcodeExample %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
Calculations use a special syntax that's different from normal SassScript.
|
|
||||||
It's the same syntax as the CSS `calc()`, but with the additional ability to
|
|
||||||
use [Sass variables] and call [Sass functions]. This means that `/` is always
|
|
||||||
a division operator within a calculation!
|
|
||||||
|
|
||||||
[Sass variables]: /documentation/variables
|
|
||||||
[Sass functions]: /documentation/modules
|
|
||||||
|
|
||||||
{% funFact %}
|
|
||||||
The arguments to a Sass function call use the normal Sass syntax, rather
|
|
||||||
than the special calculation syntax!
|
|
||||||
{% endfunFact %}
|
|
||||||
|
|
||||||
You can also use [interpolation] in a calculation. However, if you do, nothing
|
|
||||||
in the parentheses that surround that interpolation will be simplified or
|
|
||||||
type-checked, so it's easy to end up with extra verbose or even invalid CSS.
|
|
||||||
Rather than writing `calc(10px + #{$var})`, just write `calc(10px + $var)`!
|
|
||||||
|
|
||||||
[interpolation]: /documentation/interpolation
|
|
||||||
|
|
||||||
## Simplification
|
|
||||||
|
|
||||||
Sass will simplify adjacent operations in calculations if they use units that
|
|
||||||
can be combined at compile-time, such as `1in + 10px` or `5s * 2`. If
|
|
||||||
possible, it'll even simplify the whole calculation to a single number—for
|
|
||||||
example, `clamp(0px, 30px, 20px)` will return `20px`.
|
|
||||||
|
|
||||||
{% headsUp %}
|
|
||||||
This means that a calculation expression won't necessarily always return a
|
|
||||||
calculation! If you're writing a Sass library, you can always use the
|
|
||||||
[`meta.type-of()`] function to determine what type you're dealing with.
|
|
||||||
|
|
||||||
[`meta.type-of()`]: /documentation/modules/meta#type-of
|
|
||||||
{% endheadsUp %}
|
|
||||||
|
|
||||||
Calculations will also be simplified within other calculations. In particular,
|
|
||||||
if a `calc()` end up inside any other calculation, the function call will be
|
|
||||||
removed and it'll be replaced by a plain old operation.
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'simplification' %}
|
|
||||||
$width: calc(400px + 10%);
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
width: $width;
|
|
||||||
padding-left: calc($width / 4);
|
|
||||||
}
|
|
||||||
===
|
|
||||||
$width: calc(400px + 10%)
|
|
||||||
|
|
||||||
.sidebar
|
|
||||||
width: $width
|
|
||||||
padding-left: calc($width / 4)
|
|
||||||
{% endcodeExample %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
## Operations
|
|
||||||
|
|
||||||
You can't use calculations with normal SassScript operations like `+` and `*`.
|
|
||||||
If you want to write some math functions that allow calculations just write
|
|
||||||
them within their own `calc()` expressions—if they're passed a bunch of
|
|
||||||
numbers with compatible units, they'll return plain numbers as well, and if
|
|
||||||
they're passed calculations they'll return calculations.
|
|
||||||
|
|
||||||
This restriction is in place to make sure that if calculations *aren't*
|
|
||||||
wanted, they throw an error as soon as possible. Calculations can't be used
|
|
||||||
everywhere plain numbers can: they can't be injected into CSS identifiers
|
|
||||||
(such as `.item-#{$n}`), for example, and they can't be passed to Sass's
|
|
||||||
built-in [math functions]. Reserving SassScript operations for plain numbers
|
|
||||||
makes it clear exactly where calculations are allowed and where they aren't.
|
|
||||||
|
|
||||||
[math functions]: /documentation/modules/math
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'calc-operations', false %}
|
|
||||||
$width: calc(100% + 10px);
|
|
||||||
@debug $width * 2; // Error!
|
|
||||||
@debug calc($width * 2); // calc((100% + 10px) * 2);
|
|
||||||
===
|
|
||||||
$width: calc(100% + 10px);
|
|
||||||
@debug $width * 2; // Error!
|
|
||||||
@debug calc($width * 2); // calc((100% + 10px) * 2);
|
|
||||||
{% endcodeExample %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
## Constants
|
|
||||||
|
|
||||||
{% compatibility 'dart: "1.60.0"','libsass: false', 'ruby: false' %}{% endcompatibility %}
|
|
||||||
|
|
||||||
Calculations can also contain constants, which are written as CSS identifiers.
|
|
||||||
For forwards-compatibility with future CSS specs, *all* identifiers are
|
|
||||||
allowed, and by default they're just treated as unquoted strings that are
|
|
||||||
passed-through as-is.
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'calc-constants', false %}
|
|
||||||
@debug calc(h + 30deg); // calc(h + 30deg);
|
|
||||||
===
|
|
||||||
@debug calc(h + 30deg) // calc(h + 30deg);
|
|
||||||
{% endcodeExample %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
Sass automatically resolves a few special constant names that are specified in
|
|
||||||
CSS to unitless numbers:
|
|
||||||
|
|
||||||
* `pi` is a shorthand for the [mathematical constant *π*].
|
|
||||||
|
|
||||||
[mathematical constant *π*]: https://en.wikipedia.org/wiki/Pi
|
|
||||||
|
|
||||||
* `e` is a shorthand for the [mathematical constant *e*].
|
|
||||||
|
|
||||||
[mathematical constant *e*]: https://en.wikipedia.org/wiki/E_(mathematical_constant)
|
|
||||||
|
|
||||||
* `infinity`, `-infinity`, and `NaN` represent the corresponding
|
|
||||||
floating-point values.
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'unitless-numbers', false %}
|
|
||||||
@use 'sass:math';
|
|
||||||
|
|
||||||
@debug calc(pi); // 3.1415926536
|
|
||||||
@debug calc(e); // 2.7182818285
|
|
||||||
@debug calc(infinity) > math.$max-number; // true
|
|
||||||
@debug calc(-infinity) < math.$min-number; // true
|
|
||||||
===
|
|
||||||
@use 'sass:math'
|
|
||||||
|
|
||||||
@debug calc(pi) // 3.1415926536
|
|
||||||
@debug calc(e) // 2.7182818285
|
|
||||||
@debug calc(infinity) > math.$max-number // true
|
|
||||||
@debug calc(-infinity) < math.$min-number // true
|
|
||||||
{% endcodeExample %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
## `min()` and `max()`
|
|
||||||
|
|
||||||
{% compatibility 'dart: ">=1.11.0 <1.42.0"', 'libsass: false', 'ruby: false', 'feature: "Special function syntax"' %}
|
|
||||||
LibSass, Ruby Sass, and versions of Dart Sass prior to 1.11.0 *always* parse
|
|
||||||
`min()` and `max()` as Sass functions. To create a plain CSS `min()` or
|
|
||||||
`max()` call for those implementations, you can write something like
|
|
||||||
`unquote("min(#{$padding}, env(safe-area-inset-left))")` instead.
|
|
||||||
|
|
||||||
Versions of Dart Sass between 1.11.0 and 1.40.0, and between 1.40.1 and
|
|
||||||
1.42.0 parse `min()` and `max()` functions as [special functions] if they're
|
|
||||||
valid plain CSS, but parse them as Sass functions if they contain Sass
|
|
||||||
features other than interpolation, like variables or function calls.
|
|
||||||
|
|
||||||
Dart Sass 1.41.0 parses `min()` and `max()` functions as calculations, but
|
|
||||||
doesn't allow unitless numbers to be combined with numbers with units. This
|
|
||||||
was backwards-incompatible with the global `min()` and `max()` functions, so
|
|
||||||
that behavior was reverted.
|
|
||||||
|
|
||||||
[special functions]: /documentation/syntax/special-functions
|
|
||||||
{% endcompatibility %}
|
|
||||||
|
|
||||||
CSS added support for [`min()` and `max()` functions] in Values and Units
|
|
||||||
Level 4, from where they were quickly adopted by Safari [to support the
|
|
||||||
iPhoneX]. But Sass supported its own [`min()`] and [`max()`] functions long
|
|
||||||
before this, and it needed to be backwards-compatible with all those existing
|
|
||||||
stylesheets. This led to the need for extra-special syntactic cleverness.
|
|
||||||
|
|
||||||
[`min()` and `max()` functions]: https://drafts.csswg.org/css-values-4/#calc-notation
|
|
||||||
[to support the iPhoneX]: https://webkit.org/blog/7929/designing-websites-for-iphone-x/
|
|
||||||
[`min()`]: /documentation/modules/math#min
|
|
||||||
[`max()`]: /documentation/modules/math#max
|
|
||||||
|
|
||||||
If a `min()` or `max()` function call is a valid calculation expression, it
|
|
||||||
will be parsed as a calculation. But as soon as any part of the call contains
|
|
||||||
a SassScript feature that isn't supported in a calculation, like the [modulo
|
|
||||||
operator], it's parsed as a call to Sass's core `min()` or `max()` function
|
|
||||||
instead.
|
|
||||||
|
|
||||||
Since calculations are simplified to numbers when possible anyway, the only
|
|
||||||
substantive difference is that the Sass functions only support units that can
|
|
||||||
be combined at build time, so `min(12px % 10, 10%)` will throw an error.
|
|
||||||
|
|
||||||
[modulo operator]: /documentation/operators/numeric
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% headsUp %}
|
|
||||||
Other calculations don't allow unitless numbers to be added to, subtracted
|
|
||||||
from, or compared to numbers with units. `min()` and `max()` are different,
|
|
||||||
though: for backwards-compatibility with the global Sass `min()` and `max()`
|
|
||||||
functions which allow unit/unitless mixing for historical reasons, these units
|
|
||||||
can be mixed as long as they're contained directly within a `min()` or `max()`
|
|
||||||
calculation.
|
|
||||||
{% endheadsUp %}
|
|
||||||
|
|
||||||
{% codeExample 'min-max' %}
|
|
||||||
$padding: 12px;
|
|
||||||
|
|
||||||
.post {
|
|
||||||
// Since these max() calls are valid calculation expressions, they're
|
|
||||||
// parsed as calculations.
|
|
||||||
padding-left: max($padding, env(safe-area-inset-left));
|
|
||||||
padding-right: max($padding, env(safe-area-inset-right));
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
// Since these use the SassScript-only modulo operator, they're parsed as
|
|
||||||
// SassScript function calls.
|
|
||||||
padding-left: max($padding % 10, 20px);
|
|
||||||
padding-right: max($padding % 10, 20px);
|
|
||||||
}
|
|
||||||
===
|
|
||||||
$padding: 12px
|
|
||||||
|
|
||||||
.post
|
|
||||||
// Since these max() calls are valid calculation expressions, they're
|
|
||||||
// parsed as calculations.
|
|
||||||
padding-left: max($padding, env(safe-area-inset-left))
|
|
||||||
padding-right: max($padding, env(safe-area-inset-right))
|
|
||||||
|
|
||||||
|
|
||||||
.sidebar
|
|
||||||
// Since these use the SassScript-only modulo operator, they're parsed as
|
|
||||||
// SassScript function calls.
|
|
||||||
padding-left: max($padding % 10, 20px)
|
|
||||||
padding-right: max($padding % 10, 20px)
|
|
||||||
{% endcodeExample %}
|
|
243
source/documentation/values/calculations.md
Normal file
243
source/documentation/values/calculations.md
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
---
|
||||||
|
title: Calculations
|
||||||
|
introduction: >
|
||||||
|
Calculations are how Sass represents the `calc()` function, as well as similar
|
||||||
|
functions like `clamp()`, `min()`, and `max()`. Sass will simplify these as
|
||||||
|
much as possible, even if they're combined with one another.
|
||||||
|
---
|
||||||
|
|
||||||
|
{% compatibility 'dart: "1.40.0"', 'libsass: false', 'ruby: false' %}
|
||||||
|
LibSass, Ruby Sass, and versions of Dart Sass prior to 1.40.0 parse `calc()`
|
||||||
|
as a [special function] like `element()`.
|
||||||
|
|
||||||
|
[special function]: /documentation/syntax/special-functions#element-progid-and-expression
|
||||||
|
|
||||||
|
LibSass, Ruby Sass, and versions of Dart Sass prior to 1.31.0 parse `clamp()`
|
||||||
|
as a [plain CSS function] rather than supporting special syntax within it.
|
||||||
|
Versions of Dart Sass between 1.31.0 and 1.40.0 parse `clamp()` as a [special
|
||||||
|
function] like `element()`.
|
||||||
|
|
||||||
|
[plain CSS function]: /documentation/at-rules/function/#plain-css-functions
|
||||||
|
{% endcompatibility %}
|
||||||
|
|
||||||
|
{% codeExample 'calculations', false %}
|
||||||
|
@debug calc(400px + 10%); // calc(400px + 10%)
|
||||||
|
@debug calc(400px / 2); // 200px
|
||||||
|
@debug min(100px, calc(1rem + 10%)); // min(100px, 1rem + 10%)
|
||||||
|
===
|
||||||
|
@debug calc(400px + 10%) // calc(400px + 10%)
|
||||||
|
@debug calc(400px / 2) // 200px
|
||||||
|
@debug min(100px, calc(1rem + 10%) ; // min(100px, 1rem + 10%)
|
||||||
|
{% endcodeExample %}
|
||||||
|
|
||||||
|
Calculations use a special syntax that's different from normal SassScript. It's
|
||||||
|
the same syntax as the CSS `calc()`, but with the additional ability to use
|
||||||
|
[Sass variables] and call [Sass functions]. This means that `/` is always a
|
||||||
|
division operator within a calculation!
|
||||||
|
|
||||||
|
[Sass variables]: /documentation/variables
|
||||||
|
[Sass functions]: /documentation/modules
|
||||||
|
|
||||||
|
{% funFact %}
|
||||||
|
The arguments to a Sass function call use the normal Sass syntax, rather than
|
||||||
|
the special calculation syntax!
|
||||||
|
{% endfunFact %}
|
||||||
|
|
||||||
|
You can also use [interpolation] in a calculation. However, if you do, nothing
|
||||||
|
in the parentheses that surround that interpolation will be simplified or
|
||||||
|
type-checked, so it's easy to end up with extra verbose or even invalid CSS.
|
||||||
|
Rather than writing `calc(10px + #{$var})`, just write `calc(10px + $var)`!
|
||||||
|
|
||||||
|
[interpolation]: /documentation/interpolation
|
||||||
|
|
||||||
|
## Simplification
|
||||||
|
|
||||||
|
Sass will simplify adjacent operations in calculations if they use units that
|
||||||
|
can be combined at compile-time, such as `1in + 10px` or `5s * 2`. If possible,
|
||||||
|
it'll even simplify the whole calculation to a single number—for example,
|
||||||
|
`clamp(0px, 30px, 20px)` will return `20px`.
|
||||||
|
|
||||||
|
{% headsUp %}
|
||||||
|
This means that a calculation expression won't necessarily always return a
|
||||||
|
calculation! If you're writing a Sass library, you can always use the
|
||||||
|
[`meta.type-of()`] function to determine what type you're dealing with.
|
||||||
|
|
||||||
|
[`meta.type-of()`]: /documentation/modules/meta#type-of
|
||||||
|
{% endheadsUp %}
|
||||||
|
|
||||||
|
Calculations will also be simplified within other calculations. In particular,
|
||||||
|
if a `calc()` end up inside any other calculation, the function call will be
|
||||||
|
removed and it'll be replaced by a plain old operation.
|
||||||
|
|
||||||
|
{% codeExample 'simplification' %}
|
||||||
|
$width: calc(400px + 10%);
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
width: $width;
|
||||||
|
padding-left: calc($width / 4);
|
||||||
|
}
|
||||||
|
===
|
||||||
|
$width: calc(400px + 10%)
|
||||||
|
|
||||||
|
.sidebar
|
||||||
|
width: $width
|
||||||
|
padding-left: calc($width / 4)
|
||||||
|
{% endcodeExample %}
|
||||||
|
|
||||||
|
## Operations
|
||||||
|
|
||||||
|
You can't use calculations with normal SassScript operations like `+` and `*`.
|
||||||
|
If you want to write some math functions that allow calculations just write them
|
||||||
|
within their own `calc()` expressions—if they're passed a bunch of numbers with
|
||||||
|
compatible units, they'll return plain numbers as well, and if they're passed
|
||||||
|
calculations they'll return calculations.
|
||||||
|
|
||||||
|
This restriction is in place to make sure that if calculations *aren't* wanted,
|
||||||
|
they throw an error as soon as possible. Calculations can't be used everywhere
|
||||||
|
plain numbers can: they can't be injected into CSS identifiers (such as
|
||||||
|
`.item-#{$n}`), for example, and they can't be passed to Sass's built-in [math
|
||||||
|
functions]. Reserving SassScript operations for plain numbers makes it clear
|
||||||
|
exactly where calculations are allowed and where they aren't.
|
||||||
|
|
||||||
|
[math functions]: /documentation/modules/math
|
||||||
|
|
||||||
|
{% codeExample 'calc-operations', false %}
|
||||||
|
$width: calc(100% + 10px);
|
||||||
|
@debug $width * 2; // Error!
|
||||||
|
@debug calc($width * 2); // calc((100% + 10px) * 2);
|
||||||
|
===
|
||||||
|
$width: calc(100% + 10px);
|
||||||
|
@debug $width * 2; // Error!
|
||||||
|
@debug calc($width * 2); // calc((100% + 10px) * 2);
|
||||||
|
{% endcodeExample %}
|
||||||
|
|
||||||
|
## Constants
|
||||||
|
|
||||||
|
{% compatibility 'dart: "1.60.0"','libsass: false', 'ruby: false' %}{% endcompatibility %}
|
||||||
|
|
||||||
|
Calculations can also contain constants, which are written as CSS identifiers.
|
||||||
|
For forwards-compatibility with future CSS specs, *all* identifiers are allowed,
|
||||||
|
and by default they're just treated as unquoted strings that are passed-through
|
||||||
|
as-is.
|
||||||
|
|
||||||
|
{% codeExample 'calc-constants', false %}
|
||||||
|
@debug calc(h + 30deg); // calc(h + 30deg);
|
||||||
|
===
|
||||||
|
@debug calc(h + 30deg) // calc(h + 30deg);
|
||||||
|
{% endcodeExample %}
|
||||||
|
|
||||||
|
Sass automatically resolves a few special constant names that are specified in
|
||||||
|
CSS to unitless numbers:
|
||||||
|
|
||||||
|
* `pi` is a shorthand for the [mathematical constant *π*].
|
||||||
|
|
||||||
|
[mathematical constant *π*]: https://en.wikipedia.org/wiki/Pi
|
||||||
|
|
||||||
|
* `e` is a shorthand for the [mathematical constant *e*].
|
||||||
|
|
||||||
|
[mathematical constant *e*]: https://en.wikipedia.org/wiki/E_(mathematical_constant)
|
||||||
|
|
||||||
|
* `infinity`, `-infinity`, and `NaN` represent the corresponding floating-point
|
||||||
|
values.
|
||||||
|
|
||||||
|
{% codeExample 'unitless-numbers', false %}
|
||||||
|
@use 'sass:math';
|
||||||
|
|
||||||
|
@debug calc(pi); // 3.1415926536
|
||||||
|
@debug calc(e); // 2.7182818285
|
||||||
|
@debug calc(infinity) > math.$max-number; // true
|
||||||
|
@debug calc(-infinity) < math.$min-number; // true
|
||||||
|
===
|
||||||
|
@use 'sass:math'
|
||||||
|
|
||||||
|
@debug calc(pi) // 3.1415926536
|
||||||
|
@debug calc(e) // 2.7182818285
|
||||||
|
@debug calc(infinity) > math.$max-number // true
|
||||||
|
@debug calc(-infinity) < math.$min-number // true
|
||||||
|
{% endcodeExample %}
|
||||||
|
|
||||||
|
## `min()` and `max()`
|
||||||
|
|
||||||
|
{% compatibility 'dart: ">=1.11.0 <1.42.0"', 'libsass: false', 'ruby: false', 'feature: "Special function syntax"' %}
|
||||||
|
LibSass, Ruby Sass, and versions of Dart Sass prior to 1.11.0 *always* parse
|
||||||
|
`min()` and `max()` as Sass functions. To create a plain CSS `min()` or
|
||||||
|
`max()` call for those implementations, you can write something like
|
||||||
|
`unquote("min(#{$padding}, env(safe-area-inset-left))")` instead.
|
||||||
|
|
||||||
|
Versions of Dart Sass between 1.11.0 and 1.40.0, and between 1.40.1 and 1.42.0
|
||||||
|
parse `min()` and `max()` functions as [special functions] if they're valid
|
||||||
|
plain CSS, but parse them as Sass functions if they contain Sass features
|
||||||
|
other than interpolation, like variables or function calls.
|
||||||
|
|
||||||
|
Dart Sass 1.41.0 parses `min()` and `max()` functions as calculations, but
|
||||||
|
doesn't allow unitless numbers to be combined with numbers with units. This
|
||||||
|
was backwards-incompatible with the global `min()` and `max()` functions, so
|
||||||
|
that behavior was reverted.
|
||||||
|
|
||||||
|
[special functions]: /documentation/syntax/special-functions
|
||||||
|
{% endcompatibility %}
|
||||||
|
|
||||||
|
CSS added support for [`min()` and `max()` functions] in Values and Units Level
|
||||||
|
4, from where they were quickly adopted by Safari [to support the iPhoneX]. But
|
||||||
|
Sass supported its own [`min()`] and [`max()`] functions long before this, and
|
||||||
|
it needed to be backwards-compatible with all those existing stylesheets. This
|
||||||
|
led to the need for extra-special syntactic cleverness.
|
||||||
|
|
||||||
|
[`min()` and `max()` functions]: https://drafts.csswg.org/css-values-4/#calc-notation
|
||||||
|
[to support the iPhoneX]: https://webkit.org/blog/7929/designing-websites-for-iphone-x/
|
||||||
|
[`min()`]: /documentation/modules/math#min
|
||||||
|
[`max()`]: /documentation/modules/math#max
|
||||||
|
|
||||||
|
If a `min()` or `max()` function call is a valid calculation expression, it will
|
||||||
|
be parsed as a calculation. But as soon as any part of the call contains a
|
||||||
|
SassScript feature that isn't supported in a calculation, like the [modulo
|
||||||
|
operator], it's parsed as a call to Sass's core `min()` or `max()` function
|
||||||
|
instead.
|
||||||
|
|
||||||
|
Since calculations are simplified to numbers when possible anyway, the only
|
||||||
|
substantive difference is that the Sass functions only support units that can be
|
||||||
|
combined at build time, so `min(12px % 10, 10%)` will throw an error.
|
||||||
|
|
||||||
|
[modulo operator]: /documentation/operators/numeric
|
||||||
|
|
||||||
|
{% headsUp %}
|
||||||
|
Other calculations don't allow unitless numbers to be added to, subtracted
|
||||||
|
from, or compared to numbers with units. `min()` and `max()` are different,
|
||||||
|
though: for backwards-compatibility with the global Sass `min()` and `max()`
|
||||||
|
functions which allow unit/unitless mixing for historical reasons, these units
|
||||||
|
can be mixed as long as they're contained directly within a `min()` or `max()`
|
||||||
|
calculation.
|
||||||
|
{% endheadsUp %}
|
||||||
|
|
||||||
|
{% codeExample 'min-max' %}
|
||||||
|
$padding: 12px;
|
||||||
|
|
||||||
|
.post {
|
||||||
|
// Since these max() calls are valid calculation expressions, they're
|
||||||
|
// parsed as calculations.
|
||||||
|
padding-left: max($padding, env(safe-area-inset-left));
|
||||||
|
padding-right: max($padding, env(safe-area-inset-right));
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
// Since these use the SassScript-only modulo operator, they're parsed as
|
||||||
|
// SassScript function calls.
|
||||||
|
padding-left: max($padding % 10, 20px);
|
||||||
|
padding-right: max($padding % 10, 20px);
|
||||||
|
}
|
||||||
|
===
|
||||||
|
$padding: 12px
|
||||||
|
|
||||||
|
.post
|
||||||
|
// Since these max() calls are valid calculation expressions, they're
|
||||||
|
// parsed as calculations.
|
||||||
|
padding-left: max($padding, env(safe-area-inset-left))
|
||||||
|
padding-right: max($padding, env(safe-area-inset-right))
|
||||||
|
|
||||||
|
|
||||||
|
.sidebar
|
||||||
|
// Since these use the SassScript-only modulo operator, they're parsed as
|
||||||
|
// SassScript function calls.
|
||||||
|
padding-left: max($padding % 10, 20px)
|
||||||
|
padding-right: max($padding % 10, 20px)
|
||||||
|
{% endcodeExample %}
|
@ -1,81 +0,0 @@
|
|||||||
---
|
|
||||||
title: Colors
|
|
||||||
---
|
|
||||||
|
|
||||||
{% compatibility 'dart: "1.14.0"', 'libsass: "3.6.0"', 'ruby: "3.6.0"', 'feature: "Level 4 Syntax"' %}
|
|
||||||
LibSass and older versions of Dart or Ruby Sass don't support [hex colors with
|
|
||||||
an alpha channel][].
|
|
||||||
|
|
||||||
[hex colors with an alpha channel]: https://drafts.csswg.org/css-color/#hex-notation
|
|
||||||
{% endcompatibility %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
Sass has built-in support for color values. Just like CSS colors, they
|
|
||||||
represent points in the [sRGB color space][], although many Sass [color
|
|
||||||
functions][] operate using [HSL coordinates][] (which are just another way of
|
|
||||||
expressing sRGB colors). Sass colors can be written as hex codes (`#f2ece4` or
|
|
||||||
`#b37399aa`), [CSS color names][] (`midnightblue`, `transparent`), or the
|
|
||||||
functions [`rgb()`][], [`rgba()`][], [`hsl()`][], and [`hsla()`][].
|
|
||||||
|
|
||||||
[sRGB color space]: https://en.wikipedia.org/wiki/SRGB
|
|
||||||
[color functions]: /documentation/modules/color
|
|
||||||
[HSL coordinates]: https://en.wikipedia.org/wiki/HSL_and_HSV
|
|
||||||
[CSS color names]: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords
|
|
||||||
[`rgb()`]: /documentation/modules#rgb
|
|
||||||
[`rgba()`]: /documentation/modules#rgba
|
|
||||||
[`hsl()`]: /documentation/modules#hsl
|
|
||||||
[`hsla()`]: /documentation/modules#hsla
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'colors', false %}
|
|
||||||
@debug #f2ece4; // #f2ece4
|
|
||||||
@debug #b37399aa; // rgba(179, 115, 153, 67%)
|
|
||||||
@debug midnightblue; // #191970
|
|
||||||
@debug rgb(204, 102, 153); // #c69
|
|
||||||
@debug rgba(107, 113, 127, 0.8); // rgba(107, 113, 127, 0.8)
|
|
||||||
@debug hsl(228, 7%, 86%); // #dadbdf
|
|
||||||
@debug hsla(20, 20%, 85%, 0.7); // rgb(225, 215, 210, 0.7)
|
|
||||||
===
|
|
||||||
@debug #f2ece4 // #f2ece4
|
|
||||||
@debug #b37399aa // rgba(179, 115, 153, 67%)
|
|
||||||
@debug midnightblue // #191970
|
|
||||||
@debug rgb(204, 102, 153) // #c69
|
|
||||||
@debug rgba(107, 113, 127, 0.8) // rgba(107, 113, 127, 0.8)
|
|
||||||
@debug hsl(228, 7%, 86%) // #dadbdf
|
|
||||||
@debug hsla(20, 20%, 85%, 0.7) // rgb(225, 215, 210, 0.7)
|
|
||||||
{% endcodeExample %}
|
|
||||||
|
|
||||||
{% funFact %}
|
|
||||||
No matter how a Sass color is originally written, it can be used with both
|
|
||||||
HSL-based and RGB-based functions!
|
|
||||||
{% endfunFact %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
CSS supports many different formats that can all represent the same color: its
|
|
||||||
name, its hex code, and [functional notation][]. Which format Sass chooses to
|
|
||||||
compile a color to depends on the color itself, how it was written in the
|
|
||||||
original stylesheet, and the current output mode. Because it can vary so much,
|
|
||||||
stylesheet authors shouldn't rely on any particular output format for colors
|
|
||||||
they write.
|
|
||||||
|
|
||||||
[functional notation]: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value
|
|
||||||
|
|
||||||
Sass supports many useful [color functions][] that can be used to create new
|
|
||||||
colors based on existing ones by [mixing colors together][] or [scaling their
|
|
||||||
hue, saturation, or lightness][].
|
|
||||||
|
|
||||||
[mixing colors together]: /documentation/modules/color#mix
|
|
||||||
[scaling their hue, saturation, or lightness]: /documentation/modules/color#scale
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'color-formats', false %}
|
|
||||||
$venus: #998099;
|
|
||||||
|
|
||||||
@debug scale-color($venus, $lightness: +15%); // #a893a8
|
|
||||||
@debug mix($venus, midnightblue); // #594d85
|
|
||||||
===
|
|
||||||
$venus: #998099
|
|
||||||
|
|
||||||
@debug scale-color($venus, $lightness: +15%) // #a893a8
|
|
||||||
@debug mix($venus, midnightblue) // #594d85
|
|
||||||
{% endcodeExample %}
|
|
77
source/documentation/values/colors.md
Normal file
77
source/documentation/values/colors.md
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
---
|
||||||
|
title: Colors
|
||||||
|
---
|
||||||
|
|
||||||
|
{% compatibility 'dart: "1.14.0"', 'libsass: "3.6.0"', 'ruby: "3.6.0"', 'feature: "Level 4 Syntax"' %}
|
||||||
|
LibSass and older versions of Dart or Ruby Sass don't support [hex colors with
|
||||||
|
an alpha channel][].
|
||||||
|
|
||||||
|
[hex colors with an alpha channel]: https://drafts.csswg.org/css-color/#hex-notation
|
||||||
|
{% endcompatibility %}
|
||||||
|
|
||||||
|
Sass has built-in support for color values. Just like CSS colors, they represent
|
||||||
|
points in the [sRGB color space][], although many Sass [color functions][]
|
||||||
|
operate using [HSL coordinates][] (which are just another way of expressing sRGB
|
||||||
|
colors). Sass colors can be written as hex codes (`#f2ece4` or `#b37399aa`),
|
||||||
|
[CSS color names][] (`midnightblue`, `transparent`), or the functions
|
||||||
|
[`rgb()`][], [`rgba()`][], [`hsl()`][], and [`hsla()`][].
|
||||||
|
|
||||||
|
[sRGB color space]: https://en.wikipedia.org/wiki/SRGB
|
||||||
|
[color functions]: /documentation/modules/color
|
||||||
|
[HSL coordinates]: https://en.wikipedia.org/wiki/HSL_and_HSV
|
||||||
|
[CSS color names]: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords
|
||||||
|
[`rgb()`]: /documentation/modules#rgb
|
||||||
|
[`rgba()`]: /documentation/modules#rgba
|
||||||
|
[`hsl()`]: /documentation/modules#hsl
|
||||||
|
[`hsla()`]: /documentation/modules#hsla
|
||||||
|
|
||||||
|
{% codeExample 'colors', false %}
|
||||||
|
@debug #f2ece4; // #f2ece4
|
||||||
|
@debug #b37399aa; // rgba(179, 115, 153, 67%)
|
||||||
|
@debug midnightblue; // #191970
|
||||||
|
@debug rgb(204, 102, 153); // #c69
|
||||||
|
@debug rgba(107, 113, 127, 0.8); // rgba(107, 113, 127, 0.8)
|
||||||
|
@debug hsl(228, 7%, 86%); // #dadbdf
|
||||||
|
@debug hsla(20, 20%, 85%, 0.7); // rgb(225, 215, 210, 0.7)
|
||||||
|
===
|
||||||
|
@debug #f2ece4 // #f2ece4
|
||||||
|
@debug #b37399aa // rgba(179, 115, 153, 67%)
|
||||||
|
@debug midnightblue // #191970
|
||||||
|
@debug rgb(204, 102, 153) // #c69
|
||||||
|
@debug rgba(107, 113, 127, 0.8) // rgba(107, 113, 127, 0.8)
|
||||||
|
@debug hsl(228, 7%, 86%) // #dadbdf
|
||||||
|
@debug hsla(20, 20%, 85%, 0.7) // rgb(225, 215, 210, 0.7)
|
||||||
|
{% endcodeExample %}
|
||||||
|
|
||||||
|
{% funFact %}
|
||||||
|
No matter how a Sass color is originally written, it can be used with both
|
||||||
|
HSL-based and RGB-based functions!
|
||||||
|
{% endfunFact %}
|
||||||
|
|
||||||
|
CSS supports many different formats that can all represent the same color: its
|
||||||
|
name, its hex code, and [functional notation][]. Which format Sass chooses to
|
||||||
|
compile a color to depends on the color itself, how it was written in the
|
||||||
|
original stylesheet, and the current output mode. Because it can vary so much,
|
||||||
|
stylesheet authors shouldn't rely on any particular output format for colors
|
||||||
|
they write.
|
||||||
|
|
||||||
|
[functional notation]: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value
|
||||||
|
|
||||||
|
Sass supports many useful [color functions][] that can be used to create new
|
||||||
|
colors based on existing ones by [mixing colors together][] or [scaling their
|
||||||
|
hue, saturation, or lightness][].
|
||||||
|
|
||||||
|
[mixing colors together]: /documentation/modules/color#mix
|
||||||
|
[scaling their hue, saturation, or lightness]: /documentation/modules/color#scale
|
||||||
|
|
||||||
|
{% codeExample 'color-formats', false %}
|
||||||
|
$venus: #998099;
|
||||||
|
|
||||||
|
@debug scale-color($venus, $lightness: +15%); // #a893a8
|
||||||
|
@debug mix($venus, midnightblue); // #594d85
|
||||||
|
===
|
||||||
|
$venus: #998099
|
||||||
|
|
||||||
|
@debug scale-color($venus, $lightness: +15%) // #a893a8
|
||||||
|
@debug mix($venus, midnightblue) // #594d85
|
||||||
|
{% endcodeExample %}
|
@ -1,19 +0,0 @@
|
|||||||
---
|
|
||||||
title: Functions
|
|
||||||
---
|
|
||||||
|
|
||||||
{% render 'doc_snippets/call-impl-status' %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
[Functions][] can be values too! You can't directly write a function as a
|
|
||||||
value, but you can pass a function's name to the [`meta.get-function()`
|
|
||||||
function][] to get it as a value. Once you have a function value, you can pass
|
|
||||||
it to the [`meta.call()` function][] to call it. This is useful for writing
|
|
||||||
*higher-order functions* that call other functions.
|
|
||||||
|
|
||||||
[Functions]: /documentation/at-rules/function
|
|
||||||
[`meta.get-function()` function]: /documentation/modules/meta#get-function
|
|
||||||
[`meta.call()` function]: /documentation/modules/meta#call
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% render 'code_snippets/example-first-class-function' %}
|
|
17
source/documentation/values/functions.md
Normal file
17
source/documentation/values/functions.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
title: Functions
|
||||||
|
---
|
||||||
|
|
||||||
|
{% render 'doc_snippets/call-impl-status' %}
|
||||||
|
|
||||||
|
[Functions][] can be values too! You can't directly write a function as a value,
|
||||||
|
but you can pass a function's name to the [`meta.get-function()` function][] to
|
||||||
|
get it as a value. Once you have a function value, you can pass it to the
|
||||||
|
[`meta.call()` function][] to call it. This is useful for writing *higher-order
|
||||||
|
functions* that call other functions.
|
||||||
|
|
||||||
|
[Functions]: /documentation/at-rules/function
|
||||||
|
[`meta.get-function()` function]: /documentation/modules/meta#get-function
|
||||||
|
[`meta.call()` function]: /documentation/modules/meta#call
|
||||||
|
|
||||||
|
{% render 'code_snippets/example-first-class-function' %}
|
@ -1,222 +0,0 @@
|
|||||||
---
|
|
||||||
title: Lists
|
|
||||||
table_of_contents: true
|
|
||||||
---
|
|
||||||
|
|
||||||
{% compatibility 'dart: true', 'libsass: "3.5.0"', 'ruby: "3.5.0"', 'feature: "Square Brackets"' %}
|
|
||||||
Older implementations of LibSass and Ruby Sass didn't support lists with
|
|
||||||
square brackets.
|
|
||||||
{% endcompatibility %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
Lists contain a sequence of other values. In Sass, elements in lists can be
|
|
||||||
separated by commas (`Helvetica, Arial, sans-serif`), spaces (`10px 15px 0
|
|
||||||
0`), or [slashes] as long as it's consistent within the list. Unlike most
|
|
||||||
other languages, lists in Sass don't require special brackets; any
|
|
||||||
[expressions] separated with spaces or commas count as a list. However, you're
|
|
||||||
allowed to write lists with square brackets (`[line1 line2]`), which is useful
|
|
||||||
when using [`grid-template-columns`].
|
|
||||||
|
|
||||||
[slashes]: #slash-separated-lists
|
|
||||||
[expressions]: /documentation/syntax/structure#expressions
|
|
||||||
[`grid-template-columns`]: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns
|
|
||||||
|
|
||||||
Sass lists can contain one or even zero elements. A single-element list can be
|
|
||||||
written either `(<expression>,)` or `[<expression>]`, and a zero-element list
|
|
||||||
can be written either `()` or `[]`. Also, all [list functions][] will treat
|
|
||||||
individual values that aren't in lists as though they're lists containing that
|
|
||||||
value, which means you rarely need to explicitly create single-element lists.
|
|
||||||
|
|
||||||
[list functions]: /documentation/modules/list
|
|
||||||
|
|
||||||
{% headsUp %}
|
|
||||||
Empty lists without brackets aren't valid CSS, so Sass won't let you use one
|
|
||||||
in a property value.
|
|
||||||
{% endheadsUp %}
|
|
||||||
|
|
||||||
## Slash-Separated Lists
|
|
||||||
|
|
||||||
Lists in Sass can be separated by slashes, to represent values like the `font:
|
|
||||||
12px/30px` shorthand for setting `font-size` and `line-height` or the `hsl(80
|
|
||||||
100% 50% / 0.5)` syntax for creating a color with a given opacity value.
|
|
||||||
However, **slash-separated lists can't currently be written literally.** Sass
|
|
||||||
historically used the `/` character to indicate division, so while existing
|
|
||||||
stylesheets transition to using [`math.div()`] slash-separated lists can only
|
|
||||||
be written using [`list.slash()`].
|
|
||||||
|
|
||||||
[`math.div()`]: /documentation/modules/math#div
|
|
||||||
[`list.slash()`]: /documentation/modules/list#slash
|
|
||||||
|
|
||||||
For more details, see [Breaking Change: Slash as Division].
|
|
||||||
|
|
||||||
[Breaking Change: Slash as Division]: /documentation/breaking-changes/slash-div
|
|
||||||
|
|
||||||
## Using Lists
|
|
||||||
|
|
||||||
Sass provides a handful of [functions][] that make it possible to use lists to
|
|
||||||
write powerful style libraries, or to make your app's stylesheet cleaner and
|
|
||||||
more maintainable.
|
|
||||||
|
|
||||||
[functions]: /documentation/modules/list
|
|
||||||
|
|
||||||
### Indexes
|
|
||||||
|
|
||||||
Many of these functions take or return numbers, called *indexes*, that refer
|
|
||||||
to the elements in a list. The index 1 indicates the first element of the
|
|
||||||
list. Note that this is different than many programming languages where
|
|
||||||
indexes start at 0! Sass also makes it easy to refer to the end of a list. The
|
|
||||||
index -1 refers to the last element in a list, -2 refers to the
|
|
||||||
second-to-last, and so on.
|
|
||||||
|
|
||||||
### Access an Element
|
|
||||||
|
|
||||||
Lists aren't much use if you can't get values out of them. You can use the
|
|
||||||
[`list.nth($list, $n)` function][] to get the element at a given index in a
|
|
||||||
list. The first argument is the list itself, and the second is the index of
|
|
||||||
the value you want to get out.
|
|
||||||
|
|
||||||
[`list.nth($list, $n)` function]: /documentation/modules/list#nth
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% render 'code_snippets/example-list-nth' %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
### Do Something for Every Element
|
|
||||||
|
|
||||||
This doesn't actually use a function, but it's still one of the most common
|
|
||||||
ways to use lists. The [`@each` rule][] evaluates a block of styles for each
|
|
||||||
element in a list, and assigns that element to a variable.
|
|
||||||
|
|
||||||
[`@each` rule]: /documentation/at-rules/control/each
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% render 'code_snippets/example-each-list' %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
### Add to a List
|
|
||||||
|
|
||||||
It's also useful to add elements to a list. The [`list.append($list, $val)`
|
|
||||||
function][] takes a list and a value, and returns a copy of the list with the
|
|
||||||
value added to the end. Note that because Sass lists are [immutable][], it
|
|
||||||
doesn't modify the original list.
|
|
||||||
|
|
||||||
[`list.append($list, $val)` function]: /documentation/modules/list#append
|
|
||||||
[immutable]: #immutability
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'lists', false %}
|
|
||||||
@debug append(10px 12px 16px, 25px); // 10px 12px 16px 25px
|
|
||||||
@debug append([col1-line1], col1-line2); // [col1-line1, col1-line2]
|
|
||||||
===
|
|
||||||
@debug append(10px 12px 16px, 25px) // 10px 12px 16px 25px
|
|
||||||
@debug append([col1-line1], col1-line2) // [col1-line1, col1-line2]
|
|
||||||
{% endcodeExample %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
### Find an Element in a List
|
|
||||||
|
|
||||||
If you need to check if an element is in a list or figure out what index it's
|
|
||||||
at, use the [`list.index($list, $value)` function][]. This takes a list and a
|
|
||||||
value to locate in that list, and returns the index of that value.
|
|
||||||
|
|
||||||
[`list.index($list, $value)` function]: /documentation/modules/list#index
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% render 'code_snippets/example-list-index' %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
If the value isn't in the list at all, `list.index()` returns [`null`][].
|
|
||||||
Because `null` is [falsey][], you can use `list.index()` with [`@if`][] or
|
|
||||||
[`if()`][] to check whether a list does or doesn't contain a given value.
|
|
||||||
|
|
||||||
[`null`]: /documentation/values/null
|
|
||||||
[falsey]: /documentation/at-rules/control/if#truthiness-and-falsiness
|
|
||||||
[`@if`]: /documentation/at-rules/control/if
|
|
||||||
[`if()`]: /documentation/modules#if
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'list-index', false %}
|
|
||||||
@use "sass:list";
|
|
||||||
|
|
||||||
$valid-sides: top, bottom, left, right;
|
|
||||||
|
|
||||||
@mixin attach($side) {
|
|
||||||
@if not list.index($valid-sides, $side) {
|
|
||||||
@error "#{$side} is not a valid side. Expected one of #{$valid-sides}.";
|
|
||||||
}
|
|
||||||
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
===
|
|
||||||
@use "sass:list"
|
|
||||||
|
|
||||||
$valid-sides: top, bottom, left, right
|
|
||||||
|
|
||||||
@mixin attach($side)
|
|
||||||
@if not list.index($valid-sides, $side)
|
|
||||||
@error "#{$side} is not a valid side. Expected one of #{$valid-sides}."
|
|
||||||
|
|
||||||
|
|
||||||
// ...
|
|
||||||
{% endcodeExample %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
## Immutability
|
|
||||||
|
|
||||||
Lists in Sass are *immutable*, which means that the contents of a list value
|
|
||||||
never changes. Sass's list functions all return new lists rather than
|
|
||||||
modifying the originals. Immutability helps avoid lots of sneaky bugs that can
|
|
||||||
creep in when the same list is shared across different parts of the
|
|
||||||
stylesheet.
|
|
||||||
|
|
||||||
You can still update your state over time by assigning new lists to the same
|
|
||||||
variable, though. This is often used in functions and mixins to collect a
|
|
||||||
bunch of values into one list.
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'immutability', false %}
|
|
||||||
@use "sass:list";
|
|
||||||
@use "sass:map";
|
|
||||||
|
|
||||||
$prefixes-by-browser: ("firefox": moz, "safari": webkit, "ie": ms);
|
|
||||||
|
|
||||||
@function prefixes-for-browsers($browsers) {
|
|
||||||
$prefixes: ();
|
|
||||||
@each $browser in $browsers {
|
|
||||||
$prefixes: list.append($prefixes, map.get($prefixes-by-browser, $browser));
|
|
||||||
}
|
|
||||||
@return $prefixes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@debug prefixes-for-browsers("firefox" "ie"); // moz ms
|
|
||||||
===
|
|
||||||
@use "sass:list"
|
|
||||||
@use "sass:map"
|
|
||||||
|
|
||||||
$prefixes-by-browser: ("firefox": moz, "safari": webkit, "ie": ms)
|
|
||||||
|
|
||||||
@function prefixes-for-browsers($browsers)
|
|
||||||
$prefixes: ()
|
|
||||||
@each $browser in $browsers
|
|
||||||
$prefixes: list.append($prefixes, map.get($prefixes-by-browser, $browser))
|
|
||||||
|
|
||||||
@return $prefixes
|
|
||||||
|
|
||||||
|
|
||||||
@debug prefixes-for-browsers("firefox" "ie") // moz ms
|
|
||||||
{% endcodeExample %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
## Argument Lists
|
|
||||||
|
|
||||||
When you declare a mixin or function that takes [arbitrary arguments][], the
|
|
||||||
value you get is a special list known as an *argument list*. It acts just like
|
|
||||||
a list that contains all the arguments passed to the mixin or function, with
|
|
||||||
one extra feature: if the user passed keyword arguments, they can be accessed
|
|
||||||
as a map by passing the argument list to the [`meta.keywords()` function][].
|
|
||||||
|
|
||||||
[arbitrary arguments]: /documentation/at-rules/mixin#taking-arbitrary-arguments
|
|
||||||
[`meta.keywords()` function]: /documentation/modules/meta#keywords
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% render 'code_snippets/example-mixin-arbitrary-keyword-arguments' %}
|
|
206
source/documentation/values/lists.md
Normal file
206
source/documentation/values/lists.md
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
---
|
||||||
|
title: Lists
|
||||||
|
table_of_contents: true
|
||||||
|
---
|
||||||
|
|
||||||
|
{% compatibility 'dart: true', 'libsass: "3.5.0"', 'ruby: "3.5.0"', 'feature: "Square Brackets"' %}
|
||||||
|
Older implementations of LibSass and Ruby Sass didn't support lists with
|
||||||
|
square brackets.
|
||||||
|
{% endcompatibility %}
|
||||||
|
|
||||||
|
Lists contain a sequence of other values. In Sass, elements in lists can be
|
||||||
|
separated by commas (`Helvetica, Arial, sans-serif`), spaces (`10px 15px 0 0`),
|
||||||
|
or [slashes] as long as it's consistent within the list. Unlike most other
|
||||||
|
languages, lists in Sass don't require special brackets; any [expressions]
|
||||||
|
separated with spaces or commas count as a list. However, you're allowed to
|
||||||
|
write lists with square brackets (`[line1 line2]`), which is useful when using
|
||||||
|
[`grid-template-columns`].
|
||||||
|
|
||||||
|
[slashes]: #slash-separated-lists
|
||||||
|
[expressions]: /documentation/syntax/structure#expressions
|
||||||
|
[`grid-template-columns`]: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns
|
||||||
|
|
||||||
|
Sass lists can contain one or even zero elements. A single-element list can be
|
||||||
|
written either `(<expression>,)` or `[<expression>]`, and a zero-element list
|
||||||
|
can be written either `()` or `[]`. Also, all [list functions][] will treat
|
||||||
|
individual values that aren't in lists as though they're lists containing that
|
||||||
|
value, which means you rarely need to explicitly create single-element lists.
|
||||||
|
|
||||||
|
[list functions]: /documentation/modules/list
|
||||||
|
|
||||||
|
{% headsUp %}
|
||||||
|
Empty lists without brackets aren't valid CSS, so Sass won't let you use one
|
||||||
|
in a property value.
|
||||||
|
{% endheadsUp %}
|
||||||
|
|
||||||
|
## Slash-Separated Lists
|
||||||
|
|
||||||
|
Lists in Sass can be separated by slashes, to represent values like the `font:
|
||||||
|
12px/30px` shorthand for setting `font-size` and `line-height` or the `hsl(80
|
||||||
|
100% 50% / 0.5)` syntax for creating a color with a given opacity value.
|
||||||
|
However, **slash-separated lists can't currently be written literally.** Sass
|
||||||
|
historically used the `/` character to indicate division, so while existing
|
||||||
|
stylesheets transition to using [`math.div()`] slash-separated lists can only be
|
||||||
|
written using [`list.slash()`].
|
||||||
|
|
||||||
|
[`math.div()`]: /documentation/modules/math#div
|
||||||
|
[`list.slash()`]: /documentation/modules/list#slash
|
||||||
|
|
||||||
|
For more details, see [Breaking Change: Slash as Division].
|
||||||
|
|
||||||
|
[Breaking Change: Slash as Division]: /documentation/breaking-changes/slash-div
|
||||||
|
|
||||||
|
## Using Lists
|
||||||
|
|
||||||
|
Sass provides a handful of [functions][] that make it possible to use lists to
|
||||||
|
write powerful style libraries, or to make your app's stylesheet cleaner and
|
||||||
|
more maintainable.
|
||||||
|
|
||||||
|
[functions]: /documentation/modules/list
|
||||||
|
|
||||||
|
### Indexes
|
||||||
|
|
||||||
|
Many of these functions take or return numbers, called *indexes*, that refer to
|
||||||
|
the elements in a list. The index 1 indicates the first element of the list.
|
||||||
|
Note that this is different than many programming languages where indexes start
|
||||||
|
at 0! Sass also makes it easy to refer to the end of a list. The index -1 refers
|
||||||
|
to the last element in a list, -2 refers to the second-to-last, and so on.
|
||||||
|
|
||||||
|
### Access an Element
|
||||||
|
|
||||||
|
Lists aren't much use if you can't get values out of them. You can use the
|
||||||
|
[`list.nth($list, $n)` function][] to get the element at a given index in a
|
||||||
|
list. The first argument is the list itself, and the second is the index of the
|
||||||
|
value you want to get out.
|
||||||
|
|
||||||
|
[`list.nth($list, $n)` function]: /documentation/modules/list#nth
|
||||||
|
|
||||||
|
{% render 'code_snippets/example-list-nth' %}
|
||||||
|
|
||||||
|
### Do Something for Every Element
|
||||||
|
|
||||||
|
This doesn't actually use a function, but it's still one of the most common ways
|
||||||
|
to use lists. The [`@each` rule][] evaluates a block of styles for each element
|
||||||
|
in a list, and assigns that element to a variable.
|
||||||
|
|
||||||
|
[`@each` rule]: /documentation/at-rules/control/each
|
||||||
|
|
||||||
|
{% render 'code_snippets/example-each-list' %}
|
||||||
|
|
||||||
|
### Add to a List
|
||||||
|
|
||||||
|
It's also useful to add elements to a list. The [`list.append($list, $val)`
|
||||||
|
function][] takes a list and a value, and returns a copy of the list with the
|
||||||
|
value added to the end. Note that because Sass lists are [immutable][], it
|
||||||
|
doesn't modify the original list.
|
||||||
|
|
||||||
|
[`list.append($list, $val)` function]: /documentation/modules/list#append
|
||||||
|
[immutable]: #immutability
|
||||||
|
|
||||||
|
{% codeExample 'lists', false %}
|
||||||
|
@debug append(10px 12px 16px, 25px); // 10px 12px 16px 25px
|
||||||
|
@debug append([col1-line1], col1-line2); // [col1-line1, col1-line2]
|
||||||
|
===
|
||||||
|
@debug append(10px 12px 16px, 25px) // 10px 12px 16px 25px
|
||||||
|
@debug append([col1-line1], col1-line2) // [col1-line1, col1-line2]
|
||||||
|
{% endcodeExample %}
|
||||||
|
|
||||||
|
### Find an Element in a List
|
||||||
|
|
||||||
|
If you need to check if an element is in a list or figure out what index it's
|
||||||
|
at, use the [`list.index($list, $value)` function][]. This takes a list and a
|
||||||
|
value to locate in that list, and returns the index of that value.
|
||||||
|
|
||||||
|
[`list.index($list, $value)` function]: /documentation/modules/list#index
|
||||||
|
|
||||||
|
{% render 'code_snippets/example-list-index' %}
|
||||||
|
|
||||||
|
If the value isn't in the list at all, `list.index()` returns [`null`][].
|
||||||
|
Because `null` is [falsey][], you can use `list.index()` with [`@if`][] or
|
||||||
|
[`if()`][] to check whether a list does or doesn't contain a given value.
|
||||||
|
|
||||||
|
[`null`]: /documentation/values/null
|
||||||
|
[falsey]: /documentation/at-rules/control/if#truthiness-and-falsiness
|
||||||
|
[`@if`]: /documentation/at-rules/control/if
|
||||||
|
[`if()`]: /documentation/modules#if
|
||||||
|
|
||||||
|
{% codeExample 'list-index', false %}
|
||||||
|
@use "sass:list";
|
||||||
|
|
||||||
|
$valid-sides: top, bottom, left, right;
|
||||||
|
|
||||||
|
@mixin attach($side) {
|
||||||
|
@if not list.index($valid-sides, $side) {
|
||||||
|
@error "#{$side} is not a valid side. Expected one of #{$valid-sides}.";
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
===
|
||||||
|
@use "sass:list"
|
||||||
|
|
||||||
|
$valid-sides: top, bottom, left, right
|
||||||
|
|
||||||
|
@mixin attach($side)
|
||||||
|
@if not list.index($valid-sides, $side)
|
||||||
|
@error "#{$side} is not a valid side. Expected one of #{$valid-sides}."
|
||||||
|
|
||||||
|
|
||||||
|
// ...
|
||||||
|
{% endcodeExample %}
|
||||||
|
|
||||||
|
## Immutability
|
||||||
|
|
||||||
|
Lists in Sass are *immutable*, which means that the contents of a list value
|
||||||
|
never changes. Sass's list functions all return new lists rather than modifying
|
||||||
|
the originals. Immutability helps avoid lots of sneaky bugs that can creep in
|
||||||
|
when the same list is shared across different parts of the stylesheet.
|
||||||
|
|
||||||
|
You can still update your state over time by assigning new lists to the same
|
||||||
|
variable, though. This is often used in functions and mixins to collect a bunch
|
||||||
|
of values into one list.
|
||||||
|
|
||||||
|
{% codeExample 'immutability', false %}
|
||||||
|
@use "sass:list";
|
||||||
|
@use "sass:map";
|
||||||
|
|
||||||
|
$prefixes-by-browser: ("firefox": moz, "safari": webkit, "ie": ms);
|
||||||
|
|
||||||
|
@function prefixes-for-browsers($browsers) {
|
||||||
|
$prefixes: ();
|
||||||
|
@each $browser in $browsers {
|
||||||
|
$prefixes: list.append($prefixes, map.get($prefixes-by-browser, $browser));
|
||||||
|
}
|
||||||
|
@return $prefixes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@debug prefixes-for-browsers("firefox" "ie"); // moz ms
|
||||||
|
===
|
||||||
|
@use "sass:list"
|
||||||
|
@use "sass:map"
|
||||||
|
|
||||||
|
$prefixes-by-browser: ("firefox": moz, "safari": webkit, "ie": ms)
|
||||||
|
|
||||||
|
@function prefixes-for-browsers($browsers)
|
||||||
|
$prefixes: ()
|
||||||
|
@each $browser in $browsers
|
||||||
|
$prefixes: list.append($prefixes, map.get($prefixes-by-browser, $browser))
|
||||||
|
|
||||||
|
@return $prefixes
|
||||||
|
|
||||||
|
|
||||||
|
@debug prefixes-for-browsers("firefox" "ie") // moz ms
|
||||||
|
{% endcodeExample %}
|
||||||
|
|
||||||
|
## Argument Lists
|
||||||
|
|
||||||
|
When you declare a mixin or function that takes [arbitrary arguments][], the
|
||||||
|
value you get is a special list known as an *argument list*. It acts just like a
|
||||||
|
list that contains all the arguments passed to the mixin or function, with one
|
||||||
|
extra feature: if the user passed keyword arguments, they can be accessed as a
|
||||||
|
map by passing the argument list to the [`meta.keywords()` function][].
|
||||||
|
|
||||||
|
[arbitrary arguments]: /documentation/at-rules/mixin#taking-arbitrary-arguments
|
||||||
|
[`meta.keywords()` function]: /documentation/modules/meta#keywords
|
||||||
|
|
||||||
|
{% render 'code_snippets/example-mixin-arbitrary-keyword-arguments' %}
|
@ -1,191 +0,0 @@
|
|||||||
---
|
|
||||||
title: Maps
|
|
||||||
table_of_contents: true
|
|
||||||
---
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
Maps in Sass hold pairs of keys and values, and make it easy to look up a
|
|
||||||
value by its corresponding key. They're written `(<expression>: <expression>,
|
|
||||||
<expression>: <expression>)`. The
|
|
||||||
[expression](/documentation/syntax/structure#expressions) before the `:` is
|
|
||||||
the key, and the expression after is the value associated with that key. The
|
|
||||||
keys must be unique, but the values may be duplicated. Unlike
|
|
||||||
[lists](/documentation/values/lists), maps *must* be written with parentheses
|
|
||||||
around them. A map with no pairs is written `()`.
|
|
||||||
|
|
||||||
{% funFact %}
|
|
||||||
Astute readers may note that an empty map, `()`, is written the same as an
|
|
||||||
empty list. That's because it counts as both a map and a list. In fact,
|
|
||||||
*all* maps count as lists! Every map counts as a list that contains a
|
|
||||||
two-element list for each key/value pair. For example, `(1: 2, 3: 4)` counts
|
|
||||||
as `(1 2, 3 4)`.
|
|
||||||
{% endfunFact %}
|
|
||||||
|
|
||||||
Maps allow any Sass values to be used as their keys. The [`==` operator][] is
|
|
||||||
used to determine whether two keys are the same.
|
|
||||||
|
|
||||||
[`==` operator]: /documentation/operators/equality
|
|
||||||
|
|
||||||
{% headsUp %}
|
|
||||||
Most of the time, it's a good idea to use [quoted strings][] rather than
|
|
||||||
[unquoted strings][] for map keys. This is because some values, such as
|
|
||||||
color names, may *look* like unquoted strings but actually be other types.
|
|
||||||
To avoid confusing problems down the line, just use quotes!
|
|
||||||
|
|
||||||
[quoted strings]: /documentation/values/strings#quoted
|
|
||||||
[unquoted strings]: /documentation/values/strings#unquoted
|
|
||||||
{% endheadsUp %}
|
|
||||||
|
|
||||||
## Using Maps
|
|
||||||
|
|
||||||
Since maps aren't valid CSS values, they don't do much of anything on their
|
|
||||||
own. That's why Sass provides a bunch of [functions][] to create maps and
|
|
||||||
access the values they contain.
|
|
||||||
|
|
||||||
[functions]: /documentation/modules/map
|
|
||||||
|
|
||||||
### Look Up a Value
|
|
||||||
|
|
||||||
Maps are all about associating keys and values, so naturally there's a way to
|
|
||||||
get the value associated with a key: the [`map.get($map, $key)` function][]!
|
|
||||||
This function returns the value in the map associated with the given key. It
|
|
||||||
returns [`null`][] if the map doesn't contain the key.
|
|
||||||
|
|
||||||
[`map.get($map, $key)` function]: /documentation/modules/map#get
|
|
||||||
[`null`]: /documentation/values/null
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% render 'code_snippets/example-map-get' %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
### Do Something for Every Pair
|
|
||||||
|
|
||||||
This doesn't actually use a function, but it's still one of the most common
|
|
||||||
ways to use maps. The [`@each` rule][] evaluates a block of styles for each
|
|
||||||
key/value pair in a map. The key and the value are assigned to variables so
|
|
||||||
they can easily be accessed in the block.
|
|
||||||
|
|
||||||
[`@each` rule]: /documentation/at-rules/control/each
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% render 'code_snippets/example-each-map' %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
### Add to a Map
|
|
||||||
|
|
||||||
It's also useful to add new pairs to a map, or to replace the value for an
|
|
||||||
existing key. The [`map.set($map, $key, $value)` function][] does this: it
|
|
||||||
returns a copy of `$map` with the value at `$key` set to `$value`.
|
|
||||||
|
|
||||||
[`map.set($map, $key, $value)` function]: /documentation/modules/map#set
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'maps', false %}
|
|
||||||
@use "sass:map";
|
|
||||||
|
|
||||||
$font-weights: ("regular": 400, "medium": 500, "bold": 700);
|
|
||||||
|
|
||||||
@debug map.set($font-weights, "extra-bold", 900);
|
|
||||||
// ("regular": 400, "medium": 500, "bold": 700, "extra-bold": 900)
|
|
||||||
@debug map.set($font-weights, "bold", 900);
|
|
||||||
// ("regular": 400, "medium": 500, "bold": 900)
|
|
||||||
===
|
|
||||||
@use "sass:map"
|
|
||||||
|
|
||||||
$font-weights: ("regular": 400, "medium": 500, "bold": 700)
|
|
||||||
|
|
||||||
@debug map.set($font-weights, "extra-bold": 900)
|
|
||||||
// ("regular": 400, "medium": 500, "bold": 700, "extra-bold": 900)
|
|
||||||
@debug map.set($font-weights, "bold", 900)
|
|
||||||
// ("regular": 400, "medium": 500, "bold": 900)
|
|
||||||
{% endcodeExample %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
Instead of setting values one-by-one, you can also merge two existing maps
|
|
||||||
using [`map.merge($map1, $map2)`][].
|
|
||||||
|
|
||||||
[`map.merge($map1, $map2)`]: /documentation/modules/map#merge
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'map-merge', false %}
|
|
||||||
@use "sass:map";
|
|
||||||
|
|
||||||
$light-weights: ("lightest": 100, "light": 300);
|
|
||||||
$heavy-weights: ("medium": 500, "bold": 700);
|
|
||||||
|
|
||||||
@debug map.merge($light-weights, $heavy-weights);
|
|
||||||
// ("lightest": 100, "light": 300, "medium": 500, "bold": 700)
|
|
||||||
===
|
|
||||||
@use "sass:map"
|
|
||||||
|
|
||||||
$light-weights: ("lightest": 100, "light": 300)
|
|
||||||
$heavy-weights: ("medium": 500, "bold": 700)
|
|
||||||
|
|
||||||
@debug map.merge($light-weights, $heavy-weights)
|
|
||||||
// ("lightest": 100, "light": 300, "medium": 500, "bold": 700)
|
|
||||||
{% endcodeExample %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
If both maps have the same keys, the second map's values are used in the map
|
|
||||||
that gets returned.
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'map-same-keys', false %}
|
|
||||||
@use "sass:map";
|
|
||||||
|
|
||||||
$weights: ("light": 300, "medium": 500);
|
|
||||||
|
|
||||||
@debug map.merge($weights, ("medium": 700));
|
|
||||||
// ("light": 300, "medium": 700)
|
|
||||||
===
|
|
||||||
@use "sass:map";
|
|
||||||
|
|
||||||
$weights: ("light": 300, "medium": 500)
|
|
||||||
|
|
||||||
@debug map.merge($weights, ("medium": 700))
|
|
||||||
// ("light": 300, "medium": 700)
|
|
||||||
{% endcodeExample %}
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
Note that because Sass maps are [immutable][], `map.set()` and `map.merge()`
|
|
||||||
do not modify the original list.
|
|
||||||
|
|
||||||
[immutable]: #immutability
|
|
||||||
|
|
||||||
## Immutability
|
|
||||||
|
|
||||||
Maps in Sass are *immutable*, which means that the contents of a map value
|
|
||||||
never changes. Sass's map functions all return new maps rather than modifying
|
|
||||||
the originals. Immutability helps avoid lots of sneaky bugs that can creep in
|
|
||||||
when the same map is shared across different parts of the stylesheet.
|
|
||||||
|
|
||||||
You can still update your state over time by assigning new maps to the same
|
|
||||||
variable, though. This is often used in functions and mixins to track
|
|
||||||
configuration in a map.
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'immutability', false %}
|
|
||||||
@use "sass:map";
|
|
||||||
|
|
||||||
$prefixes-by-browser: ("firefox": moz, "safari": webkit, "ie": ms);
|
|
||||||
|
|
||||||
@mixin add-browser-prefix($browser, $prefix) {
|
|
||||||
$prefixes-by-browser: map.merge($prefixes-by-browser, ($browser: $prefix)) !global;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include add-browser-prefix("opera", o);
|
|
||||||
@debug $prefixes-by-browser;
|
|
||||||
// ("firefox": moz, "safari": webkit, "ie": ms, "opera": o)
|
|
||||||
===
|
|
||||||
@use "sass:map"
|
|
||||||
|
|
||||||
$prefixes-by-browser: ("firefox": moz, "safari": webkit, "ie": ms)
|
|
||||||
|
|
||||||
@mixin add-browser-prefix($browser, $prefix)
|
|
||||||
$prefixes-by-browser: map.merge($prefixes-by-browser, ($browser: $prefix)) !global
|
|
||||||
|
|
||||||
|
|
||||||
@include add-browser-prefix("opera", o)
|
|
||||||
@debug $prefixes-by-browser
|
|
||||||
// ("firefox": moz, "safari": webkit, "ie": ms, "opera": o)
|
|
||||||
{% endcodeExample %}
|
|
179
source/documentation/values/maps.md
Normal file
179
source/documentation/values/maps.md
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
---
|
||||||
|
title: Maps
|
||||||
|
table_of_contents: true
|
||||||
|
---
|
||||||
|
|
||||||
|
Maps in Sass hold pairs of keys and values, and make it easy to look up a value
|
||||||
|
by its corresponding key. They're written `(<expression>: <expression>,
|
||||||
|
<expression>: <expression>)`. The
|
||||||
|
[expression](/documentation/syntax/structure#expressions) before the `:` is the
|
||||||
|
key, and the expression after is the value associated with that key. The keys
|
||||||
|
must be unique, but the values may be duplicated. Unlike
|
||||||
|
[lists](/documentation/values/lists), maps *must* be written with parentheses
|
||||||
|
around them. A map with no pairs is written `()`.
|
||||||
|
|
||||||
|
{% funFact %}
|
||||||
|
Astute readers may note that an empty map, `()`, is written the same as an
|
||||||
|
empty list. That's because it counts as both a map and a list. In fact, *all*
|
||||||
|
maps count as lists! Every map counts as a list that contains a two-element
|
||||||
|
list for each key/value pair. For example, `(1: 2, 3: 4)` counts as `(1 2, 3
|
||||||
|
4)`.
|
||||||
|
{% endfunFact %}
|
||||||
|
|
||||||
|
Maps allow any Sass values to be used as their keys. The [`==` operator][] is
|
||||||
|
used to determine whether two keys are the same.
|
||||||
|
|
||||||
|
[`==` operator]: /documentation/operators/equality
|
||||||
|
|
||||||
|
{% headsUp %}
|
||||||
|
Most of the time, it's a good idea to use [quoted strings][] rather than
|
||||||
|
[unquoted strings][] for map keys. This is because some values, such as color
|
||||||
|
names, may *look* like unquoted strings but actually be other types. To avoid
|
||||||
|
confusing problems down the line, just use quotes!
|
||||||
|
|
||||||
|
[quoted strings]: /documentation/values/strings#quoted
|
||||||
|
[unquoted strings]: /documentation/values/strings#unquoted
|
||||||
|
{% endheadsUp %}
|
||||||
|
|
||||||
|
## Using Maps
|
||||||
|
|
||||||
|
Since maps aren't valid CSS values, they don't do much of anything on their own.
|
||||||
|
That's why Sass provides a bunch of [functions][] to create maps and access the
|
||||||
|
values they contain.
|
||||||
|
|
||||||
|
[functions]: /documentation/modules/map
|
||||||
|
|
||||||
|
### Look Up a Value
|
||||||
|
|
||||||
|
Maps are all about associating keys and values, so naturally there's a way to
|
||||||
|
get the value associated with a key: the [`map.get($map, $key)` function][]!
|
||||||
|
This function returns the value in the map associated with the given key. It
|
||||||
|
returns [`null`][] if the map doesn't contain the key.
|
||||||
|
|
||||||
|
[`map.get($map, $key)` function]: /documentation/modules/map#get
|
||||||
|
[`null`]: /documentation/values/null
|
||||||
|
|
||||||
|
{% render 'code_snippets/example-map-get' %}
|
||||||
|
|
||||||
|
### Do Something for Every Pair
|
||||||
|
|
||||||
|
This doesn't actually use a function, but it's still one of the most common ways
|
||||||
|
to use maps. The [`@each` rule][] evaluates a block of styles for each key/value
|
||||||
|
pair in a map. The key and the value are assigned to variables so they can
|
||||||
|
easily be accessed in the block.
|
||||||
|
|
||||||
|
[`@each` rule]: /documentation/at-rules/control/each
|
||||||
|
|
||||||
|
{% render 'code_snippets/example-each-map' %}
|
||||||
|
|
||||||
|
### Add to a Map
|
||||||
|
|
||||||
|
It's also useful to add new pairs to a map, or to replace the value for an
|
||||||
|
existing key. The [`map.set($map, $key, $value)` function][] does this: it
|
||||||
|
returns a copy of `$map` with the value at `$key` set to `$value`.
|
||||||
|
|
||||||
|
[`map.set($map, $key, $value)` function]: /documentation/modules/map#set
|
||||||
|
|
||||||
|
{% codeExample 'maps', false %}
|
||||||
|
@use "sass:map";
|
||||||
|
|
||||||
|
$font-weights: ("regular": 400, "medium": 500, "bold": 700);
|
||||||
|
|
||||||
|
@debug map.set($font-weights, "extra-bold", 900);
|
||||||
|
// ("regular": 400, "medium": 500, "bold": 700, "extra-bold": 900)
|
||||||
|
@debug map.set($font-weights, "bold", 900);
|
||||||
|
// ("regular": 400, "medium": 500, "bold": 900)
|
||||||
|
===
|
||||||
|
@use "sass:map"
|
||||||
|
|
||||||
|
$font-weights: ("regular": 400, "medium": 500, "bold": 700)
|
||||||
|
|
||||||
|
@debug map.set($font-weights, "extra-bold": 900)
|
||||||
|
// ("regular": 400, "medium": 500, "bold": 700, "extra-bold": 900)
|
||||||
|
@debug map.set($font-weights, "bold", 900)
|
||||||
|
// ("regular": 400, "medium": 500, "bold": 900)
|
||||||
|
{% endcodeExample %}
|
||||||
|
|
||||||
|
Instead of setting values one-by-one, you can also merge two existing maps using
|
||||||
|
[`map.merge($map1, $map2)`][].
|
||||||
|
|
||||||
|
[`map.merge($map1, $map2)`]: /documentation/modules/map#merge
|
||||||
|
|
||||||
|
{% codeExample 'map-merge', false %}
|
||||||
|
@use "sass:map";
|
||||||
|
|
||||||
|
$light-weights: ("lightest": 100, "light": 300);
|
||||||
|
$heavy-weights: ("medium": 500, "bold": 700);
|
||||||
|
|
||||||
|
@debug map.merge($light-weights, $heavy-weights);
|
||||||
|
// ("lightest": 100, "light": 300, "medium": 500, "bold": 700)
|
||||||
|
===
|
||||||
|
@use "sass:map"
|
||||||
|
|
||||||
|
$light-weights: ("lightest": 100, "light": 300)
|
||||||
|
$heavy-weights: ("medium": 500, "bold": 700)
|
||||||
|
|
||||||
|
@debug map.merge($light-weights, $heavy-weights)
|
||||||
|
// ("lightest": 100, "light": 300, "medium": 500, "bold": 700)
|
||||||
|
{% endcodeExample %}
|
||||||
|
|
||||||
|
If both maps have the same keys, the second map's values are used in the map
|
||||||
|
that gets returned.
|
||||||
|
|
||||||
|
{% codeExample 'map-same-keys', false %}
|
||||||
|
@use "sass:map";
|
||||||
|
|
||||||
|
$weights: ("light": 300, "medium": 500);
|
||||||
|
|
||||||
|
@debug map.merge($weights, ("medium": 700));
|
||||||
|
// ("light": 300, "medium": 700)
|
||||||
|
===
|
||||||
|
@use "sass:map";
|
||||||
|
|
||||||
|
$weights: ("light": 300, "medium": 500)
|
||||||
|
|
||||||
|
@debug map.merge($weights, ("medium": 700))
|
||||||
|
// ("light": 300, "medium": 700)
|
||||||
|
{% endcodeExample %}
|
||||||
|
|
||||||
|
Note that because Sass maps are [immutable][], `map.set()` and `map.merge()` do
|
||||||
|
not modify the original list.
|
||||||
|
|
||||||
|
[immutable]: #immutability
|
||||||
|
|
||||||
|
## Immutability
|
||||||
|
|
||||||
|
Maps in Sass are *immutable*, which means that the contents of a map value never
|
||||||
|
changes. Sass's map functions all return new maps rather than modifying the
|
||||||
|
originals. Immutability helps avoid lots of sneaky bugs that can creep in when
|
||||||
|
the same map is shared across different parts of the stylesheet.
|
||||||
|
|
||||||
|
You can still update your state over time by assigning new maps to the same
|
||||||
|
variable, though. This is often used in functions and mixins to track
|
||||||
|
configuration in a map.
|
||||||
|
|
||||||
|
{% codeExample 'immutability', false %}
|
||||||
|
@use "sass:map";
|
||||||
|
|
||||||
|
$prefixes-by-browser: ("firefox": moz, "safari": webkit, "ie": ms);
|
||||||
|
|
||||||
|
@mixin add-browser-prefix($browser, $prefix) {
|
||||||
|
$prefixes-by-browser: map.merge($prefixes-by-browser, ($browser: $prefix)) !global;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include add-browser-prefix("opera", o);
|
||||||
|
@debug $prefixes-by-browser;
|
||||||
|
// ("firefox": moz, "safari": webkit, "ie": ms, "opera": o)
|
||||||
|
===
|
||||||
|
@use "sass:map"
|
||||||
|
|
||||||
|
$prefixes-by-browser: ("firefox": moz, "safari": webkit, "ie": ms)
|
||||||
|
|
||||||
|
@mixin add-browser-prefix($browser, $prefix)
|
||||||
|
$prefixes-by-browser: map.merge($prefixes-by-browser, ($browser: $prefix)) !global
|
||||||
|
|
||||||
|
|
||||||
|
@include add-browser-prefix("opera", o)
|
||||||
|
@debug $prefixes-by-browser
|
||||||
|
// ("firefox": moz, "safari": webkit, "ie": ms, "opera": o)
|
||||||
|
{% endcodeExample %}
|
@ -22,12 +22,9 @@ introduction: >
|
|||||||
@debug & // null
|
@debug & // null
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
If a [list][] contains a `null`, that `null` is omitted from the generated CSS.
|
||||||
If a [list][] contains a `null`, that `null` is omitted from the generated
|
|
||||||
CSS.
|
|
||||||
|
|
||||||
[list]: /documentation/values/lists
|
[list]: /documentation/values/lists
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'null-lists' %}
|
{% codeExample 'null-lists' %}
|
||||||
$fonts: ("serif": "Helvetica Neue", "monospace": "Consolas");
|
$fonts: ("serif": "Helvetica Neue", "monospace": "Consolas");
|
||||||
@ -42,9 +39,7 @@ introduction: >
|
|||||||
font: 18px bold map-get($fonts, "sans")
|
font: 18px bold map-get($fonts, "sans")
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
If a property value is `null`, that property is omitted entirely.
|
||||||
If a property value is `null`, that property is omitted entirely.
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'null-value-omitted' %}
|
{% codeExample 'null-value-omitted' %}
|
||||||
$fonts: ("serif": "Helvetica Neue", "monospace": "Consolas");
|
$fonts: ("serif": "Helvetica Neue", "monospace": "Consolas");
|
||||||
@ -66,15 +61,13 @@ introduction: >
|
|||||||
family: map-get($fonts, "sans")
|
family: map-get($fonts, "sans")
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
`null` is also [*falsey*][], which means it counts as `false` for any rules or
|
||||||
`null` is also [*falsey*][], which means it counts as `false` for any rules or
|
[operators][] that take booleans. This makes it easy to use values that can be
|
||||||
[operators][] that take booleans. This makes it easy to use values that can be
|
`null` as conditions for [`@if`][] and [`if()`][].
|
||||||
`null` as conditions for [`@if`][] and [`if()`][].
|
|
||||||
|
|
||||||
[*falsey*]: /documentation/at-rules/control/if#truthiness-and-falsiness
|
[*falsey*]: /documentation/at-rules/control/if#truthiness-and-falsiness
|
||||||
[operators]: /documentation/operators/boolean
|
[operators]: /documentation/operators/boolean
|
||||||
[`@if`]: /documentation/at-rules/control/if
|
[`@if`]: /documentation/at-rules/control/if
|
||||||
[`if()`]: /documentation/modules#if
|
[`if()`]: /documentation/modules#if
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% render 'code_snippets/example-if-parent-selector' %}
|
{% render 'code_snippets/example-if-parent-selector' %}
|
@ -19,14 +19,12 @@ introduction: >
|
|||||||
@debug 5px * 2px // 10px*px (read "square pixels")
|
@debug 5px * 2px // 10px*px (read "square pixels")
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
Sass numbers support the same formats as CSS numbers, including [scientific
|
||||||
Sass numbers support the same formats as CSS numbers, including [scientific
|
notation][], which is written with an `e` between the number and its power of
|
||||||
notation][], which is written with an `e` between the number and its power
|
10. Because support for scientific notation in browsers has historically been
|
||||||
of 10. Because support for scientific notation in browsers has historically
|
spotty, Sass always compiles it to fully expanded numbers.
|
||||||
been spotty, Sass always compiles it to fully expanded numbers.
|
|
||||||
|
|
||||||
[scientific notation]: https://en.wikipedia.org/wiki/Scientific_notation
|
[scientific notation]: https://en.wikipedia.org/wiki/Scientific_notation
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'scientific-notation', false %}
|
{% codeExample 'scientific-notation', false %}
|
||||||
@debug 5.2e3; // 5200
|
@debug 5.2e3; // 5200
|
||||||
@ -44,34 +42,32 @@ introduction: >
|
|||||||
|
|
||||||
{% render 'doc_snippets/number-units' %}
|
{% render 'doc_snippets/number-units' %}
|
||||||
|
|
||||||
{% markdown %}
|
## Precision
|
||||||
## Precision
|
|
||||||
|
|
||||||
{% compatibility 'dart: true', 'libsass: false', 'ruby: "3.5.0"', 'feature: "10 Digit Default"' %}
|
{% compatibility 'dart: true', 'libsass: false', 'ruby: "3.5.0"', 'feature: "10 Digit Default"' %}
|
||||||
LibSass and older versions of Ruby Sass default to 5 digits of numeric
|
LibSass and older versions of Ruby Sass default to 5 digits of numeric
|
||||||
precision, but can be configured to use a different number. It's recommended
|
precision, but can be configured to use a different number. It's recommended
|
||||||
that users configure them for 10 digits for greater accuracy and
|
that users configure them for 10 digits for greater accuracy and
|
||||||
forwards-compatibility.
|
forwards-compatibility.
|
||||||
{% endcompatibility %}
|
{% endcompatibility %}
|
||||||
|
|
||||||
Sass numbers are represented internally as 64-bit floating point values. They
|
Sass numbers are represented internally as 64-bit floating point values. They
|
||||||
support up to 10 digits of precision after the decimal point when serialized
|
support up to 10 digits of precision after the decimal point when serialized to
|
||||||
to CSS and for the purposes of equality. This means a few different things:
|
CSS and for the purposes of equality. This means a few different things:
|
||||||
|
|
||||||
* Only the first ten digits of a number after the decimal point will be
|
* Only the first ten digits of a number after the decimal point will be included
|
||||||
included in the generated CSS.
|
in the generated CSS.
|
||||||
|
|
||||||
* Operations like [`==`][] and [`>=`][] will consider two numbers equivalent
|
* Operations like [`==`][] and [`>=`][] will consider two numbers equivalent if
|
||||||
if they're the same up to the tenth digit after the decimal point.
|
they're the same up to the tenth digit after the decimal point.
|
||||||
|
|
||||||
* If a number is less than `0.0000000001` away from an integer, it's
|
* If a number is less than `0.0000000001` away from an integer, it's considered
|
||||||
considered to be an integer for the purposes of functions like
|
to be an integer for the purposes of functions like [`list.nth()`][] that
|
||||||
[`list.nth()`][] that require integer arguments.
|
require integer arguments.
|
||||||
|
|
||||||
[`==`]: /documentation/operators/equality
|
[`==`]: /documentation/operators/equality
|
||||||
[`>=`]: /documentation/operators/relational
|
[`>=`]: /documentation/operators/relational
|
||||||
[`list.nth()`]: /documentation/modules/list#nth
|
[`list.nth()`]: /documentation/modules/list#nth
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'precision', false %}
|
{% codeExample 'precision', false %}
|
||||||
@debug 0.012345678912345; // 0.0123456789
|
@debug 0.012345678912345; // 0.0123456789
|
@ -10,15 +10,13 @@ introduction: >
|
|||||||
these cover the different kinds of text that appear in CSS.
|
these cover the different kinds of text that appear in CSS.
|
||||||
---
|
---
|
||||||
|
|
||||||
{% funFact false %}
|
{% funFact %}
|
||||||
{% markdown %}
|
You can convert a quoted string to an unquoted string using the
|
||||||
You can convert a quoted string to an unquoted string using the
|
[`string.unquote()` function][], and you can convert an unquoted string to a
|
||||||
[`string.unquote()` function][], and you can convert an unquoted string to a
|
quoted string using the [`string.quote()` function][].
|
||||||
quoted string using the [`string.quote()` function][].
|
|
||||||
|
|
||||||
[`string.unquote()` function]: /documentation/modules/string#unquote
|
[`string.unquote()` function]: /documentation/modules/string#unquote
|
||||||
[`string.quote()` function]: /documentation/modules/string#quote
|
[`string.quote()` function]: /documentation/modules/string#quote
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'fun-fact-strings', false %}
|
{% codeExample 'fun-fact-strings', false %}
|
||||||
@use "sass:string";
|
@use "sass:string";
|
||||||
@ -33,25 +31,22 @@ introduction: >
|
|||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
{% endfunFact %}
|
{% endfunFact %}
|
||||||
|
|
||||||
{% markdown %}
|
## Escapes
|
||||||
## Escapes
|
|
||||||
|
|
||||||
All Sass strings support the standard CSS [escape codes][]:
|
All Sass strings support the standard CSS [escape codes][]:
|
||||||
|
|
||||||
[escape codes]: https://developer.mozilla.org/en-US/docs/Web/CSS/string#Syntax
|
[escape codes]: https://developer.mozilla.org/en-US/docs/Web/CSS/string#Syntax
|
||||||
|
|
||||||
* Any character other than a letter from A to F or a number from 0 to 9 (even
|
* Any character other than a letter from A to F or a number from 0 to 9 (even a
|
||||||
a newline!) can be included as part of a string by writing `\` in front of
|
newline!) can be included as part of a string by writing `\` in front of it.
|
||||||
it.
|
|
||||||
|
|
||||||
* Any character can be included as part of a string by writing `\` followed by
|
* Any character can be included as part of a string by writing `\` followed by
|
||||||
its [Unicode code point number][] written in [hexadecimal][]. You can
|
its [Unicode code point number][] written in [hexadecimal][]. You can
|
||||||
optionally include a space after the code point number to indicate where the
|
optionally include a space after the code point number to indicate where the
|
||||||
Unicode number ends.
|
Unicode number ends.
|
||||||
|
|
||||||
[Unicode code point number]: https://en.wikipedia.org/wiki/List_of_Unicode_characters
|
[Unicode code point number]: https://en.wikipedia.org/wiki/List_of_Unicode_characters
|
||||||
[hexadecimal]: https://en.wikipedia.org/wiki/Hexadecimal
|
[hexadecimal]: https://en.wikipedia.org/wiki/Hexadecimal
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'escapes', false %}
|
{% codeExample 'escapes', false %}
|
||||||
@debug "\""; // '"'
|
@debug "\""; // '"'
|
||||||
@ -72,29 +67,27 @@ introduction: >
|
|||||||
escape produces exactly the same string as writing the character itself.
|
escape produces exactly the same string as writing the character itself.
|
||||||
{% endfunFact %}
|
{% endfunFact %}
|
||||||
|
|
||||||
{% markdown %}
|
## Quoted
|
||||||
## Quoted
|
|
||||||
|
|
||||||
Quoted strings are written between either single or double quotes, as in
|
Quoted strings are written between either single or double quotes, as in
|
||||||
`"Helvetica Neue"`. They can contain [interpolation][], as well as any
|
`"Helvetica Neue"`. They can contain [interpolation][], as well as any unescaped
|
||||||
unescaped character except for:
|
character except for:
|
||||||
|
|
||||||
[interpolation]: /documentation/interpolation
|
[interpolation]: /documentation/interpolation
|
||||||
|
|
||||||
* `\`, which can be escaped as `\\`;
|
* `\`, which can be escaped as `\\`;
|
||||||
* `'` or `"`, whichever was used to define that string, which can be escaped
|
* `'` or `"`, whichever was used to define that string, which can be escaped as
|
||||||
as `\'` or `\"`;
|
`\'` or `\"`;
|
||||||
* newlines, which can be escaped as `\a ` (including a trailing space).
|
* newlines, which can be escaped as `\a ` (including a trailing space).
|
||||||
|
|
||||||
Quoted strings are guaranteed to be compiled to CSS strings that have the same
|
Quoted strings are guaranteed to be compiled to CSS strings that have the same
|
||||||
contents as the original Sass strings. The exact format may vary based on the
|
contents as the original Sass strings. The exact format may vary based on the
|
||||||
implementation or configuration—a string containing a double quote may be
|
implementation or configuration—a string containing a double quote may be
|
||||||
compiled to `"\""` or `'"'`, and a non-[ASCII][] character may or may not be
|
compiled to `"\""` or `'"'`, and a non-[ASCII][] character may or may not be
|
||||||
escaped. But that should be parsed the same in any standards-compliant CSS
|
escaped. But that should be parsed the same in any standards-compliant CSS
|
||||||
implementation, including all browsers.
|
implementation, including all browsers.
|
||||||
|
|
||||||
[ASCII]: https://en.wikipedia.org/wiki/ASCII
|
[ASCII]: https://en.wikipedia.org/wiki/ASCII
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'quoted', false %}
|
{% codeExample 'quoted', false %}
|
||||||
@debug "Helvetica Neue"; // "Helvetica Neue"
|
@debug "Helvetica Neue"; // "Helvetica Neue"
|
||||||
@ -123,15 +116,13 @@ introduction: >
|
|||||||
[its quotes are removed]: /documentation/interpolation#quoted-strings
|
[its quotes are removed]: /documentation/interpolation#quoted-strings
|
||||||
{% endfunFact %}
|
{% endfunFact %}
|
||||||
|
|
||||||
{% markdown %}
|
## Unquoted
|
||||||
## Unquoted
|
|
||||||
|
|
||||||
Unquoted strings are written as CSS [identifiers][], following the syntax
|
Unquoted strings are written as CSS [identifiers][], following the syntax
|
||||||
diagram below. They may include [interpolation][] anywhere.
|
diagram below. They may include [interpolation][] anywhere.
|
||||||
|
|
||||||
[identifiers]: https://drafts.csswg.org/css-syntax-3/#ident-token-diagram
|
[identifiers]: https://drafts.csswg.org/css-syntax-3/#ident-token-diagram
|
||||||
[interpolation]: /documentation/interpolation
|
[interpolation]: /documentation/interpolation
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
<figure>
|
<figure>
|
||||||
<object type="image/svg+xml" data="/assets/img/illustrations/identifier-diagram.svg"></object>
|
<object type="image/svg+xml" data="/assets/img/illustrations/identifier-diagram.svg"></object>
|
||||||
@ -173,31 +164,28 @@ introduction: >
|
|||||||
strings.
|
strings.
|
||||||
{% endheadsUp %}
|
{% endheadsUp %}
|
||||||
|
|
||||||
{% markdown %}
|
### Escapes in Unquoted Strings
|
||||||
### Escapes in Unquoted Strings
|
|
||||||
|
|
||||||
{% compatibility 'dart: "1.11.0"', 'libsass: false', 'ruby: false', 'feature: "Normalization"' %}
|
{% compatibility 'dart: "1.11.0"', 'libsass: false', 'ruby: false', 'feature: "Normalization"' %}
|
||||||
LibSass, Ruby Sass, and older versions of Dart Sass don't normalize escapes
|
LibSass, Ruby Sass, and older versions of Dart Sass don't normalize escapes in
|
||||||
in identifiers. Instead, the text in the unquoted string is the exact text
|
identifiers. Instead, the text in the unquoted string is the exact text the
|
||||||
the user wrote. For example, `\1F46D` and `👭` are not considered
|
user wrote. For example, `\1F46D` and `👭` are not considered equivalent.
|
||||||
equivalent.
|
{% endcompatibility %}
|
||||||
{% endcompatibility %}
|
|
||||||
|
|
||||||
When an unquoted string is parsed, the literal text of escapes are parsed as
|
When an unquoted string is parsed, the literal text of escapes are parsed as
|
||||||
part of the string. For example, `\a ` is parsed as the characters `\`, `a`,
|
part of the string. For example, `\a ` is parsed as the characters `\`, `a`, and
|
||||||
and space. In order to ensure that unquoted strings that have the same
|
space. In order to ensure that unquoted strings that have the same meanings in
|
||||||
meanings in CSS are parsed the same way, though, these escapes are
|
CSS are parsed the same way, though, these escapes are *normalized*. For each
|
||||||
*normalized*. For each code point, whether it's escaped or unescaped:
|
code point, whether it's escaped or unescaped:
|
||||||
|
|
||||||
* If it's a valid identifier character, it's included unescaped in the
|
* If it's a valid identifier character, it's included unescaped in the unquoted
|
||||||
unquoted string. For example, `\1F46D` returns the unquoted string `👭`.
|
string. For example, `\1F46D` returns the unquoted string `👭`.
|
||||||
|
|
||||||
* If it's a printable character other than a newline or a tab, it's included
|
* If it's a printable character other than a newline or a tab, it's included
|
||||||
after a `\`. For example, `\21 ` returns the unquoted string `\!`.
|
after a `\`. For example, `\21 ` returns the unquoted string `\!`.
|
||||||
|
|
||||||
* Otherwise, the lowercase Unicode escape is included with a trailing space.
|
* Otherwise, the lowercase Unicode escape is included with a trailing space. For
|
||||||
For example, `\7Fx` returns the unquoted string `\7f x`.
|
example, `\7Fx` returns the unquoted string `\7f x`.
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'normalization', false %}
|
{% codeExample 'normalization', false %}
|
||||||
@use "sass:string";
|
@use "sass:string";
|
||||||
@ -215,18 +203,16 @@ introduction: >
|
|||||||
@debug string.length(\7Fx) // 5
|
@debug string.length(\7Fx) // 5
|
||||||
{% endcodeExample %}
|
{% endcodeExample %}
|
||||||
|
|
||||||
{% markdown %}
|
## String Indexes
|
||||||
## String Indexes
|
|
||||||
|
|
||||||
Sass has a number of [string functions][] that take or return numbers, called
|
Sass has a number of [string functions][] that take or return numbers, called
|
||||||
*indexes*, that refer to the characters in a string. The index 1 indicates the
|
*indexes*, that refer to the characters in a string. The index 1 indicates the
|
||||||
first character of the string. Note that this is different than many
|
first character of the string. Note that this is different than many programming
|
||||||
programming languages where indexes start at 0! Sass also makes it easy to
|
languages where indexes start at 0! Sass also makes it easy to refer to the end
|
||||||
refer to the end of a string. The index -1 refers to the last character in a
|
of a string. The index -1 refers to the last character in a string, -2 refers to
|
||||||
string, -2 refers to the second-to-last, and so on.
|
the second-to-last, and so on.
|
||||||
|
|
||||||
[string functions]: /documentation/modules/string
|
[string functions]: /documentation/modules/string
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
{% codeExample 'string-indexes', false %}
|
{% codeExample 'string-indexes', false %}
|
||||||
@use "sass:string";
|
@use "sass:string";
|
Loading…
Reference in New Issue
Block a user