mirror of
https://github.com/danog/sass-site.git
synced 2024-11-30 04:29:17 +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
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
## Interpolation
|
||||
## Interpolation
|
||||
|
||||
A property's name can include [interpolation][], which makes it possible to
|
||||
dynamically generate properties as needed. You can even interpolate the entire
|
||||
property name!
|
||||
A property's name can include [interpolation][], which makes it possible to
|
||||
dynamically generate properties as needed. You can even interpolate the entire
|
||||
property name!
|
||||
|
||||
[interpolation]: /documentation/interpolation
|
||||
{% endmarkdown %}
|
||||
[interpolation]: /documentation/interpolation
|
||||
|
||||
{% codeExample 'interpolation' %}
|
||||
@mixin prefix($property, $value, $prefixes) {
|
||||
@ -57,15 +55,13 @@ introduction: >
|
||||
@include prefix(filter, grayscale(50%), moz webkit)
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
## Nesting
|
||||
## Nesting
|
||||
|
||||
Many CSS properties start with the same prefix that acts as a kind of
|
||||
namespace. For example, `font-family`, `font-size`, and `font-weight` all
|
||||
start with `font-`. Sass makes this easier and less redundant by allowing
|
||||
property declarations to be nested. The outer property names are added to the
|
||||
inner, separated by a hyphen.
|
||||
{% endmarkdown %}
|
||||
Many CSS properties start with the same prefix that acts as a kind of namespace.
|
||||
For example, `font-family`, `font-size`, and `font-weight` all start with
|
||||
`font-`. Sass makes this easier and less redundant by allowing property
|
||||
declarations to be nested. The outer property names are added to the inner,
|
||||
separated by a hyphen.
|
||||
|
||||
{% codeExample 'nesting' %}
|
||||
.enlarge {
|
||||
@ -90,11 +86,9 @@ introduction: >
|
||||
font-size: 36px
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
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
|
||||
more explicit nested versions.
|
||||
{% endmarkdown %}
|
||||
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
|
||||
more explicit nested versions.
|
||||
|
||||
{% codeExample 'nesting-shorthand' %}
|
||||
.info-page {
|
||||
@ -110,16 +104,14 @@ introduction: >
|
||||
top: 2px
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
## Hidden Declarations
|
||||
## Hidden Declarations
|
||||
|
||||
Sometimes you only want a property declaration to show up some of the time. If
|
||||
a declaration's value is [`null`][] or an empty [unquoted string][], Sass
|
||||
won't compile that declaration to CSS at all.
|
||||
Sometimes you only want a property declaration to show up some of the time. If a
|
||||
declaration's value is [`null`][] or an empty [unquoted string][], Sass won't
|
||||
compile that declaration to CSS at all.
|
||||
|
||||
[`null`]: /documentation/values/null
|
||||
[unquoted string]: /documentation/values/strings#unquoted
|
||||
{% endmarkdown %}
|
||||
[`null`]: /documentation/values/null
|
||||
[unquoted string]: /documentation/values/strings#unquoted
|
||||
|
||||
{% codeExample 'hidden-declarations' %}
|
||||
$rounded-corners: false;
|
||||
@ -136,37 +128,34 @@ introduction: >
|
||||
border-radius: if($rounded-corners, 5px, null)
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
## Custom Properties
|
||||
## Custom Properties
|
||||
|
||||
{% 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
|
||||
just like any other property declaration, allowing the full range of
|
||||
SassScript expressions as values. Even when using these versions, it's
|
||||
recommended that you use interpolation to inject SassScript values for
|
||||
forwards-compatibility.
|
||||
{% 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
|
||||
just like any other property declaration, allowing the full range of
|
||||
SassScript expressions as values. Even when using these versions, it's
|
||||
recommended that you use interpolation to inject SassScript values for
|
||||
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
|
||||
{% endcompatibility %}
|
||||
[the breaking change page]: /documentation/breaking-changes/css-vars
|
||||
{% endcompatibility %}
|
||||
|
||||
[CSS custom properties][], also known as CSS variables, have an unusual
|
||||
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
|
||||
might potentially be relevant to the user. This includes values that would
|
||||
normally be parsed as SassScript.
|
||||
[CSS custom properties][], also known as CSS variables, have an unusual
|
||||
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
|
||||
might potentially be relevant to the user. This includes values that would
|
||||
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
|
||||
other property declarations. All tokens, including those that look like
|
||||
SassScript, are passed through to CSS as-is. The only exception is
|
||||
[interpolation][], which is the only way to inject dynamic values into a
|
||||
custom property.
|
||||
Because of this, Sass parses custom property declarations differently than other
|
||||
property declarations. All tokens, including those that look like SassScript,
|
||||
are passed through to CSS as-is. The only exception is [interpolation][], which
|
||||
is the only way to inject dynamic values into a custom property.
|
||||
|
||||
[interpolation]: /documentation/interpolation
|
||||
{% endmarkdown %}
|
||||
[interpolation]: /documentation/interpolation
|
||||
|
||||
{% codeExample 'custom-properties' %}
|
||||
$primary: #81899b;
|
||||
@ -197,16 +186,14 @@ introduction: >
|
||||
--consumed-by-js: $primary
|
||||
{% endcodeExample %}
|
||||
|
||||
{% headsUp false %}
|
||||
{% markdown %}
|
||||
Unfortunately, [interpolation][] removes quotes from strings, which makes it
|
||||
difficult to use quoted strings as values for custom properties when they
|
||||
come from Sass variables. As a workaround, you can use the [`meta.inspect()`
|
||||
function][] to preserve the quotes.
|
||||
{% headsUp %}
|
||||
Unfortunately, [interpolation][] removes quotes from strings, which makes it
|
||||
difficult to use quoted strings as values for custom properties when they come
|
||||
from Sass variables. As a workaround, you can use the [`meta.inspect()`
|
||||
function][] to preserve the quotes.
|
||||
|
||||
[interpolation]: /documentation/interpolation
|
||||
[`meta.inspect()` function]: /documentation/modules/meta#inspect
|
||||
{% endmarkdown %}
|
||||
[interpolation]: /documentation/interpolation
|
||||
[`meta.inspect()` function]: /documentation/modules/meta#inspect
|
||||
|
||||
{% codeExample 'custom-properties-strings-meta' %}
|
||||
@use "sass:meta";
|
@ -23,14 +23,11 @@ introduction: >
|
||||
border: 1px solid #e1e4e8
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
## Nesting
|
||||
## Nesting
|
||||
|
||||
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.
|
||||
Sass will automatically combine the outer rule's selector with the inner
|
||||
rule's.
|
||||
{% endmarkdown %}
|
||||
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.
|
||||
Sass will automatically combine the outer rule's selector with the inner rule's.
|
||||
|
||||
{% render 'code_snippets/example-nesting' %}
|
||||
|
||||
@ -41,14 +38,11 @@ introduction: >
|
||||
render it. Keep those selectors shallow!
|
||||
{% endheadsUp %}
|
||||
|
||||
{% markdown %}
|
||||
### Selector Lists
|
||||
### Selector Lists
|
||||
|
||||
Nested rules are clever about handling selector lists (that is,
|
||||
comma-separated selectors). Each complex selector (the ones between the
|
||||
commas) is nested separately, and then they're combined back into a selector
|
||||
list.
|
||||
{% endmarkdown %}
|
||||
Nested rules are clever about handling selector lists (that is, comma-separated
|
||||
selectors). Each complex selector (the ones between the commas) is nested
|
||||
separately, and then they're combined back into a selector list.
|
||||
|
||||
{% codeExample 'selector-lists' %}
|
||||
.alert, .warning {
|
||||
@ -66,15 +60,13 @@ introduction: >
|
||||
padding-bottom: 0
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
### Selector Combinators
|
||||
### Selector Combinators
|
||||
|
||||
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
|
||||
selector, or even all on its own in between the two.
|
||||
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
|
||||
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
|
||||
{% endmarkdown %}
|
||||
[combinators]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors#Combinators#Combinators
|
||||
|
||||
{% codeExample 'selector-combinators' %}
|
||||
ul > {
|
||||
@ -115,27 +107,24 @@ introduction: >
|
||||
opacity: 0.8
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
### Advanced Nesting
|
||||
### Advanced Nesting
|
||||
|
||||
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,
|
||||
Sass has your back. See the [parent selector documentation][] for more
|
||||
details.
|
||||
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,
|
||||
Sass has your back. See the [parent selector documentation][] for more 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
|
||||
variables and function calls into your selectors. This is particularly useful
|
||||
when you're writing [mixins][], since it allows you to create selectors from
|
||||
parameters your users pass in.
|
||||
You can use [interpolation][] to inject values from [expressions][] like
|
||||
variables and function calls into your selectors. This is particularly useful
|
||||
when you're writing [mixins][], since it allows you to create selectors from
|
||||
parameters your users pass in.
|
||||
|
||||
[interpolation]: /documentation/interpolation
|
||||
[expressions]: /documentation/syntax/structure#expressions
|
||||
[mixins]: /documentation/at-rules/mixin
|
||||
{% endmarkdown %}
|
||||
[interpolation]: /documentation/interpolation
|
||||
[expressions]: /documentation/syntax/structure#expressions
|
||||
[mixins]: /documentation/at-rules/mixin
|
||||
|
||||
{% codeExample 'interpolation' %}
|
||||
@mixin define-emoji($name, $glyph) {
|
||||
@ -167,13 +156,11 @@ introduction: >
|
||||
worrying that it won't parse.
|
||||
{% endfunFact %}
|
||||
|
||||
{% markdown %}
|
||||
You can combine interpolation with the parent selector `&`, the [`@at-root`
|
||||
rule][], and [selector functions][] to wield some serious power when
|
||||
dynamically generating selectors. For more information, see the [parent
|
||||
selector documentation][].
|
||||
You can combine interpolation with the parent selector `&`, the [`@at-root`
|
||||
rule][], and [selector functions][] to wield some serious power when dynamically
|
||||
generating selectors. For more information, see the [parent selector
|
||||
documentation][].
|
||||
|
||||
[`@at-root` rule]: /documentation/at-rules/at-root
|
||||
[selector functions]: /documentation/modules/selector
|
||||
[parent selector documentation]: /documentation/style-rules/parent-selector
|
||||
{% endmarkdown %}
|
||||
[`@at-root` rule]: /documentation/at-rules/at-root
|
||||
[selector functions]: /documentation/modules/selector
|
||||
[parent selector documentation]: /documentation/style-rules/parent-selector
|
@ -9,11 +9,9 @@ introduction: >
|
||||
or adding a selector *before* the parent.
|
||||
---
|
||||
|
||||
{% markdown %}
|
||||
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
|
||||
behavior.
|
||||
{% endmarkdown %}
|
||||
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
|
||||
behavior.
|
||||
|
||||
{% codeExample 'parent-selector' %}
|
||||
.alert {
|
||||
@ -66,17 +64,15 @@ introduction: >
|
||||
[this GitHub issue]: https://github.com/sass/sass/issues/1425
|
||||
{% endheadsUp %}
|
||||
|
||||
{% markdown %}
|
||||
## Adding Suffixes
|
||||
## Adding Suffixes
|
||||
|
||||
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][]
|
||||
that uses highly structured class names. As long as the outer selector ends
|
||||
with an alphanumeric name (like class, ID, and element selectors), you can use
|
||||
the parent selector to append additional text.
|
||||
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][] that
|
||||
uses highly structured class names. As long as the outer selector ends with an
|
||||
alphanumeric name (like class, ID, and element selectors), you can use the
|
||||
parent selector to append additional text.
|
||||
|
||||
[BEM]: http://getbem.com/
|
||||
{% endmarkdown %}
|
||||
[BEM]: http://getbem.com/
|
||||
|
||||
{% codeExample 'parent-selector-suffixes' %}
|
||||
.accordion {
|
||||
@ -119,17 +115,15 @@ introduction: >
|
||||
display: block
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
## In SassScript
|
||||
## In SassScript
|
||||
|
||||
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
|
||||
[selector functions][]: a comma-separated list (the selector list) that
|
||||
contains space-separated lists (the complex selectors) that contain unquoted
|
||||
strings (the compound selectors).
|
||||
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
|
||||
[selector functions][]: a comma-separated list (the selector list) that contains
|
||||
space-separated lists (the complex selectors) that contain unquoted strings (the
|
||||
compound selectors).
|
||||
|
||||
[selector functions]: /documentation/modules/selector#selector-values
|
||||
{% endmarkdown %}
|
||||
[selector functions]: /documentation/modules/selector#selector-values
|
||||
|
||||
{% codeExample 'parent-selector-sassscript' %}
|
||||
.main aside:hover,
|
||||
@ -146,27 +140,23 @@ introduction: >
|
||||
// (unquote(".sidebar") unquote("p")))
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
If the `&` expression is used outside any style rules, it returns `null`.
|
||||
Since `null` is [falsey][], this means you can easily use it to determine
|
||||
whether a mixin is being called in a style rule or not.
|
||||
If the `&` expression is used outside any style rules, it returns `null`. Since
|
||||
`null` is [falsey][], this means you can easily use it to determine whether a
|
||||
mixin is being called in a style rule or not.
|
||||
|
||||
[falsey]: /documentation/at-rules/control/if#truthiness-and-falsiness
|
||||
{% endmarkdown %}
|
||||
[falsey]: /documentation/at-rules/control/if#truthiness-and-falsiness
|
||||
|
||||
{% 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
|
||||
to functions or include it in interpolation—even in other selectors! Using it
|
||||
in combination with [selector functions][] and the [`@at-root` rule][] allows
|
||||
you to nest selectors in very powerful ways.
|
||||
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 in
|
||||
combination with [selector functions][] and the [`@at-root` rule][] allows you
|
||||
to nest selectors in very powerful ways.
|
||||
|
||||
[selector functions]: /documentation/modules/selector#selector-values
|
||||
[`@at-root` rule]: /documentation/at-rules/at-root
|
||||
{% endmarkdown %}
|
||||
[selector functions]: /documentation/modules/selector#selector-values
|
||||
[`@at-root` rule]: /documentation/at-rules/at-root
|
||||
|
||||
{% render 'code_snippets/example-advanced-nesting' %}
|
||||
|
@ -10,14 +10,12 @@ introduction: >
|
||||
|
||||
{% render 'code_snippets/example-placeholder' %}
|
||||
|
||||
{% markdown %}
|
||||
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
|
||||
extended and they don't mandate that users of a library use specific class
|
||||
names for their HTML.
|
||||
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
|
||||
extended and they don't mandate that users of a library use specific class names
|
||||
for their HTML.
|
||||
|
||||
[extended]: /documentation/at-rules/extend
|
||||
{% endmarkdown %}
|
||||
[extended]: /documentation/at-rules/extend
|
||||
|
||||
{% codeExample 'extended-selector' %}
|
||||
%toolbelt {
|
||||
@ -58,9 +56,7 @@ introduction: >
|
||||
color: #cddc39
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
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 just for your own app, it's often better to just extend a class
|
||||
selector if one is available.
|
||||
{% endmarkdown %}
|
||||
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
|
||||
just for your own app, it's often better to just extend a class selector if one
|
||||
is available.
|
@ -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
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
You can work with booleans using [boolean operators][]. The `and` operator
|
||||
returns `true` if *both* sides are `true`, and the `or` operator returns
|
||||
`true` if *either* side is `true`. The `not` operator returns the opposite of
|
||||
a single boolean value.
|
||||
You can work with booleans using [boolean operators][]. The `and` operator
|
||||
returns `true` if *both* sides are `true`, and the `or` operator returns `true`
|
||||
if *either* side is `true`. The `not` operator returns the opposite of a single
|
||||
boolean value.
|
||||
|
||||
[boolean operators]: /documentation/operators/boolean
|
||||
{% endmarkdown %}
|
||||
[boolean operators]: /documentation/operators/boolean
|
||||
|
||||
{% codeExample 'boolean-operators', false %}
|
||||
@debug true and true; // true
|
||||
@ -54,23 +52,19 @@ introduction: >
|
||||
@debug not false // true
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
## Using Booleans
|
||||
## Using Booleans
|
||||
|
||||
You can use booleans to choose whether or not to do various things in Sass.
|
||||
The [`@if` rule][] evaluates a block of styles if its argument is `true`:
|
||||
You can use booleans to choose whether or not to do various things in Sass. The
|
||||
[`@if` rule][] evaluates a block of styles if its argument is `true`:
|
||||
|
||||
[`@if` rule]: /documentation/at-rules/control/if
|
||||
{% endmarkdown %}
|
||||
[`@if` rule]: /documentation/at-rules/control/if
|
||||
|
||||
{% render 'code_snippets/example-if' %}
|
||||
|
||||
{% markdown %}
|
||||
The [`if()` function][] returns one value if its argument is `true` and
|
||||
another if its argument is `false`:
|
||||
The [`if()` function][] returns one value if its argument is `true` and another
|
||||
if its argument is `false`:
|
||||
|
||||
[`if()` function]: /documentation/modules#if
|
||||
{% endmarkdown %}
|
||||
[`if()` function]: /documentation/modules#if
|
||||
|
||||
{% codeExample 'if-function', false %}
|
||||
@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
|
||||
{% 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
|
||||
{% endmarkdown %}
|
||||
[list]: /documentation/values/lists
|
||||
|
||||
{% codeExample 'null-lists' %}
|
||||
$fonts: ("serif": "Helvetica Neue", "monospace": "Consolas");
|
||||
@ -42,9 +39,7 @@ introduction: >
|
||||
font: 18px bold map-get($fonts, "sans")
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
If a property value is `null`, that property is omitted entirely.
|
||||
{% endmarkdown %}
|
||||
If a property value is `null`, that property is omitted entirely.
|
||||
|
||||
{% codeExample 'null-value-omitted' %}
|
||||
$fonts: ("serif": "Helvetica Neue", "monospace": "Consolas");
|
||||
@ -66,15 +61,13 @@ introduction: >
|
||||
family: map-get($fonts, "sans")
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
`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
|
||||
`null` as conditions for [`@if`][] and [`if()`][].
|
||||
`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
|
||||
`null` as conditions for [`@if`][] and [`if()`][].
|
||||
|
||||
[*falsey*]: /documentation/at-rules/control/if#truthiness-and-falsiness
|
||||
[operators]: /documentation/operators/boolean
|
||||
[`@if`]: /documentation/at-rules/control/if
|
||||
[`if()`]: /documentation/modules#if
|
||||
{% endmarkdown %}
|
||||
[*falsey*]: /documentation/at-rules/control/if#truthiness-and-falsiness
|
||||
[operators]: /documentation/operators/boolean
|
||||
[`@if`]: /documentation/at-rules/control/if
|
||||
[`if()`]: /documentation/modules#if
|
||||
|
||||
{% render 'code_snippets/example-if-parent-selector' %}
|
@ -19,14 +19,12 @@ introduction: >
|
||||
@debug 5px * 2px // 10px*px (read "square pixels")
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
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 10. Because support for scientific notation in browsers has historically
|
||||
been spotty, Sass always compiles it to fully expanded numbers.
|
||||
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
|
||||
10. Because support for scientific notation in browsers has historically been
|
||||
spotty, Sass always compiles it to fully expanded numbers.
|
||||
|
||||
[scientific notation]: https://en.wikipedia.org/wiki/Scientific_notation
|
||||
{% endmarkdown %}
|
||||
[scientific notation]: https://en.wikipedia.org/wiki/Scientific_notation
|
||||
|
||||
{% codeExample 'scientific-notation', false %}
|
||||
@debug 5.2e3; // 5200
|
||||
@ -44,34 +42,32 @@ introduction: >
|
||||
|
||||
{% render 'doc_snippets/number-units' %}
|
||||
|
||||
{% markdown %}
|
||||
## Precision
|
||||
## Precision
|
||||
|
||||
{% 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
|
||||
precision, but can be configured to use a different number. It's recommended
|
||||
that users configure them for 10 digits for greater accuracy and
|
||||
forwards-compatibility.
|
||||
{% endcompatibility %}
|
||||
{% 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
|
||||
precision, but can be configured to use a different number. It's recommended
|
||||
that users configure them for 10 digits for greater accuracy and
|
||||
forwards-compatibility.
|
||||
{% endcompatibility %}
|
||||
|
||||
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
|
||||
to CSS and for the purposes of equality. This means a few different things:
|
||||
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 to
|
||||
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
|
||||
included in the generated CSS.
|
||||
* Only the first ten digits of a number after the decimal point will be included
|
||||
in the generated CSS.
|
||||
|
||||
* Operations like [`==`][] and [`>=`][] will consider two numbers equivalent
|
||||
if they're the same up to the tenth digit after the decimal point.
|
||||
* Operations like [`==`][] and [`>=`][] will consider two numbers equivalent if
|
||||
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
|
||||
considered to be an integer for the purposes of functions like
|
||||
[`list.nth()`][] that require integer arguments.
|
||||
* If a number is less than `0.0000000001` away from an integer, it's considered
|
||||
to be an integer for the purposes of functions like [`list.nth()`][] that
|
||||
require integer arguments.
|
||||
|
||||
[`==`]: /documentation/operators/equality
|
||||
[`>=`]: /documentation/operators/relational
|
||||
[`list.nth()`]: /documentation/modules/list#nth
|
||||
{% endmarkdown %}
|
||||
[`==`]: /documentation/operators/equality
|
||||
[`>=`]: /documentation/operators/relational
|
||||
[`list.nth()`]: /documentation/modules/list#nth
|
||||
|
||||
{% codeExample 'precision', false %}
|
||||
@debug 0.012345678912345; // 0.0123456789
|
@ -10,15 +10,13 @@ introduction: >
|
||||
these cover the different kinds of text that appear in CSS.
|
||||
---
|
||||
|
||||
{% funFact false %}
|
||||
{% markdown %}
|
||||
You can convert a quoted string to an unquoted string using the
|
||||
[`string.unquote()` function][], and you can convert an unquoted string to a
|
||||
quoted string using the [`string.quote()` function][].
|
||||
{% funFact %}
|
||||
You can convert a quoted string to an unquoted string using the
|
||||
[`string.unquote()` function][], and you can convert an unquoted string to a
|
||||
quoted string using the [`string.quote()` function][].
|
||||
|
||||
[`string.unquote()` function]: /documentation/modules/string#unquote
|
||||
[`string.quote()` function]: /documentation/modules/string#quote
|
||||
{% endmarkdown %}
|
||||
[`string.unquote()` function]: /documentation/modules/string#unquote
|
||||
[`string.quote()` function]: /documentation/modules/string#quote
|
||||
|
||||
{% codeExample 'fun-fact-strings', false %}
|
||||
@use "sass:string";
|
||||
@ -33,25 +31,22 @@ introduction: >
|
||||
{% endcodeExample %}
|
||||
{% 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
|
||||
a newline!) can be included as part of a string by writing `\` in front of
|
||||
it.
|
||||
* Any character other than a letter from A to F or a number from 0 to 9 (even a
|
||||
newline!) can be included as part of a string by writing `\` in front of it.
|
||||
|
||||
* Any character can be included as part of a string by writing `\` followed by
|
||||
its [Unicode code point number][] written in [hexadecimal][]. You can
|
||||
optionally include a space after the code point number to indicate where the
|
||||
Unicode number ends.
|
||||
* Any character can be included as part of a string by writing `\` followed by
|
||||
its [Unicode code point number][] written in [hexadecimal][]. You can
|
||||
optionally include a space after the code point number to indicate where the
|
||||
Unicode number ends.
|
||||
|
||||
[Unicode code point number]: https://en.wikipedia.org/wiki/List_of_Unicode_characters
|
||||
[hexadecimal]: https://en.wikipedia.org/wiki/Hexadecimal
|
||||
{% endmarkdown %}
|
||||
[Unicode code point number]: https://en.wikipedia.org/wiki/List_of_Unicode_characters
|
||||
[hexadecimal]: https://en.wikipedia.org/wiki/Hexadecimal
|
||||
|
||||
{% codeExample 'escapes', false %}
|
||||
@debug "\""; // '"'
|
||||
@ -72,29 +67,27 @@ introduction: >
|
||||
escape produces exactly the same string as writing the character itself.
|
||||
{% endfunFact %}
|
||||
|
||||
{% markdown %}
|
||||
## Quoted
|
||||
## Quoted
|
||||
|
||||
Quoted strings are written between either single or double quotes, as in
|
||||
`"Helvetica Neue"`. They can contain [interpolation][], as well as any
|
||||
unescaped character except for:
|
||||
Quoted strings are written between either single or double quotes, as in
|
||||
`"Helvetica Neue"`. They can contain [interpolation][], as well as any unescaped
|
||||
character except for:
|
||||
|
||||
[interpolation]: /documentation/interpolation
|
||||
[interpolation]: /documentation/interpolation
|
||||
|
||||
* `\`, which can be escaped as `\\`;
|
||||
* `'` or `"`, whichever was used to define that string, which can be escaped
|
||||
as `\'` or `\"`;
|
||||
* newlines, which can be escaped as `\a ` (including a trailing space).
|
||||
* `\`, which can be escaped as `\\`;
|
||||
* `'` or `"`, whichever was used to define that string, which can be escaped as
|
||||
`\'` or `\"`;
|
||||
* 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
|
||||
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
|
||||
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
|
||||
implementation, including all browsers.
|
||||
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
|
||||
implementation or configuration—a string containing a double quote may 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
|
||||
implementation, including all browsers.
|
||||
|
||||
[ASCII]: https://en.wikipedia.org/wiki/ASCII
|
||||
{% endmarkdown %}
|
||||
[ASCII]: https://en.wikipedia.org/wiki/ASCII
|
||||
|
||||
{% codeExample 'quoted', false %}
|
||||
@debug "Helvetica Neue"; // "Helvetica Neue"
|
||||
@ -123,15 +116,13 @@ introduction: >
|
||||
[its quotes are removed]: /documentation/interpolation#quoted-strings
|
||||
{% endfunFact %}
|
||||
|
||||
{% markdown %}
|
||||
## Unquoted
|
||||
## Unquoted
|
||||
|
||||
Unquoted strings are written as CSS [identifiers][], following the syntax
|
||||
diagram below. They may include [interpolation][] anywhere.
|
||||
Unquoted strings are written as CSS [identifiers][], following the syntax
|
||||
diagram below. They may include [interpolation][] anywhere.
|
||||
|
||||
[identifiers]: https://drafts.csswg.org/css-syntax-3/#ident-token-diagram
|
||||
[interpolation]: /documentation/interpolation
|
||||
{% endmarkdown %}
|
||||
[identifiers]: https://drafts.csswg.org/css-syntax-3/#ident-token-diagram
|
||||
[interpolation]: /documentation/interpolation
|
||||
|
||||
<figure>
|
||||
<object type="image/svg+xml" data="/assets/img/illustrations/identifier-diagram.svg"></object>
|
||||
@ -173,31 +164,28 @@ introduction: >
|
||||
strings.
|
||||
{% endheadsUp %}
|
||||
|
||||
{% markdown %}
|
||||
### Escapes in Unquoted Strings
|
||||
### Escapes in Unquoted Strings
|
||||
|
||||
{% compatibility 'dart: "1.11.0"', 'libsass: false', 'ruby: false', 'feature: "Normalization"' %}
|
||||
LibSass, Ruby Sass, and older versions of Dart Sass don't normalize escapes
|
||||
in identifiers. Instead, the text in the unquoted string is the exact text
|
||||
the user wrote. For example, `\1F46D` and `👭` are not considered
|
||||
equivalent.
|
||||
{% endcompatibility %}
|
||||
{% compatibility 'dart: "1.11.0"', 'libsass: false', 'ruby: false', 'feature: "Normalization"' %}
|
||||
LibSass, Ruby Sass, and older versions of Dart Sass don't normalize escapes in
|
||||
identifiers. Instead, the text in the unquoted string is the exact text the
|
||||
user wrote. For example, `\1F46D` and `👭` are not considered equivalent.
|
||||
{% endcompatibility %}
|
||||
|
||||
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`,
|
||||
and space. In order to ensure that unquoted strings that have the same
|
||||
meanings in CSS are parsed the same way, though, these escapes are
|
||||
*normalized*. For each code point, whether it's escaped or unescaped:
|
||||
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`, and
|
||||
space. In order to ensure that unquoted strings that have the same meanings in
|
||||
CSS are parsed the same way, though, these escapes are *normalized*. For each
|
||||
code point, whether it's escaped or unescaped:
|
||||
|
||||
* If it's a valid identifier character, it's included unescaped in the
|
||||
unquoted string. For example, `\1F46D` returns the unquoted string `👭`.
|
||||
* If it's a valid identifier character, it's included unescaped in the unquoted
|
||||
string. For example, `\1F46D` returns the unquoted string `👭`.
|
||||
|
||||
* 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 `\!`.
|
||||
* 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 `\!`.
|
||||
|
||||
* Otherwise, the lowercase Unicode escape is included with a trailing space.
|
||||
For example, `\7Fx` returns the unquoted string `\7f x`.
|
||||
{% endmarkdown %}
|
||||
* Otherwise, the lowercase Unicode escape is included with a trailing space. For
|
||||
example, `\7Fx` returns the unquoted string `\7f x`.
|
||||
|
||||
{% codeExample 'normalization', false %}
|
||||
@use "sass:string";
|
||||
@ -215,18 +203,16 @@ introduction: >
|
||||
@debug string.length(\7Fx) // 5
|
||||
{% endcodeExample %}
|
||||
|
||||
{% markdown %}
|
||||
## String Indexes
|
||||
## String Indexes
|
||||
|
||||
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
|
||||
first character of the string. 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 string. The index -1 refers to the last character in a
|
||||
string, -2 refers to the second-to-last, and so on.
|
||||
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
|
||||
first character of the string. 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 string. The index -1 refers to the last character in a string, -2 refers to
|
||||
the second-to-last, and so on.
|
||||
|
||||
[string functions]: /documentation/modules/string
|
||||
{% endmarkdown %}
|
||||
[string functions]: /documentation/modules/string
|
||||
|
||||
{% codeExample 'string-indexes', false %}
|
||||
@use "sass:string";
|
Loading…
Reference in New Issue
Block a user