indentation for style-rules docs

This commit is contained in:
Jonny Gerig Meyer 2023-05-31 12:16:59 -04:00
parent fdcb4e47d6
commit c146c76ffc
No known key found for this signature in database
4 changed files with 435 additions and 430 deletions

View File

@ -10,14 +10,14 @@ introduction: >
---
{% codeExample 'declaration' %}
.circle {
.circle {
$size: 100px;
width: $size;
height: $size;
border-radius: $size * 0.5;
}
===
.circle
}
===
.circle
$size: 100px
width: $size
height: $size
@ -25,50 +25,50 @@ introduction: >
{% 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
[interpolation]: /documentation/interpolation
{% endmarkdown %}
{% codeExample 'interpolation' %}
@mixin prefix($property, $value, $prefixes) {
@mixin prefix($property, $value, $prefixes) {
@each $prefix in $prefixes {
-#{$prefix}-#{$property}: $value;
}
#{$property}: $value;
}
}
.gray {
.gray {
@include prefix(filter, grayscale(50%), moz webkit);
}
===
@mixin prefix($property, $value, $prefixes)
}
===
@mixin prefix($property, $value, $prefixes)
@each $prefix in $prefixes
-#{$prefix}-#{$property}: $value
#{$property}: $value
.gray
.gray
@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.
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 %}
{% codeExample 'nesting' %}
.enlarge {
.enlarge {
font-size: 14px;
transition: {
property: font-size;
@ -77,9 +77,9 @@ separated by a hyphen.
}
&:hover { font-size: 36px; }
}
===
.enlarge
}
===
.enlarge
font-size: 14px
transition:
property: font-size
@ -91,89 +91,91 @@ separated by a hyphen.
{% 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.
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 %}
{% codeExample 'nesting-shorthand' %}
.info-page {
.info-page {
margin: auto {
bottom: 10px;
top: 2px;
}
}
===
.info-page
}
===
.info-page
margin: auto
bottom: 10px
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
[`null`]: /documentation/values/null
[unquoted string]: /documentation/values/strings#unquoted
{% endmarkdown %}
{% codeExample 'hidden-declarations' %}
$rounded-corners: false;
$rounded-corners: false;
.button {
.button {
border: 1px solid black;
border-radius: if($rounded-corners, 5px, null);
}
===
$rounded-corners: false
}
===
$rounded-corners: false
.button
.button
border: 1px solid black
border-radius: if($rounded-corners, 5px, null)
{% endcodeExample %}
{{ '## Custom Properties' | markdown }}
{% # Arguments are (in order): `dart`, `libsass`, `node`, `ruby`, optional feature name, additional details within %}
{% compatibility true, '3.5.0', null, '3.5.0', '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.
[the breaking change page]: /documentation/breaking-changes/css-vars
{% endcompatibility %}
{% markdown %}
[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.
## Custom Properties
[CSS Custom Properties]: https://developer.mozilla.org/en-US/docs/Web/CSS/--*
{% # Arguments are (in order): `dart`, `libsass`, `node`, `ruby`, optional feature name, additional details within %}
{% compatibility true, '3.5.0', null, '3.5.0', '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.
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.
See [the breaking change page][] for more details.
[interpolation]: /documentation/interpolation
[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]: 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.
[interpolation]: /documentation/interpolation
{% endmarkdown %}
<!-- TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass -->
{% codeExample 'custom-properties' %}
$primary: #81899b;
$accent: #302e24;
$warn: #dfa612;
$primary: #81899b;
$accent: #302e24;
$warn: #dfa612;
:root {
:root {
--primary: #{$primary};
--accent: #{$accent};
--warn: #{$warn};
@ -181,13 +183,13 @@ $warn: #dfa612;
// Even though this looks like a Sass variable, it's valid CSS so it's not
// evaluated.
--consumed-by-js: $primary;
}
===
$primary: #81899b
$accent: #302e24
$warn: #dfa612
}
===
$primary: #81899b
$accent: #302e24
$warn: #dfa612
:root
:root
--primary: #{$primary}
--accent: #{$accent}
--warn: #{$warn}
@ -195,49 +197,49 @@ $warn: #dfa612
// Even though this looks like a Sass variable, it's valid CSS so it's not
// evaluated.
--consumed-by-js: $primary
===
:root {
===
:root {
--primary: #81899b;
--accent: #302e24;
--warn: #dfa612;
--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.
{% 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.
[interpolation]: /documentation/interpolation
[`meta.inspect()` function]: /documentation/modules/meta#inspect
{% endmarkdown %}
[interpolation]: /documentation/interpolation
[`meta.inspect()` function]: /documentation/modules/meta#inspect
{% endmarkdown %}
{% codeExample 'custom-properties-strings-meta' %}
@use "sass:meta";
{% codeExample 'custom-properties-strings-meta' %}
@use "sass:meta";
$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto;
$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas;
$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto;
$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas;
:root {
:root {
--font-family-sans-serif: #{meta.inspect($font-family-sans-serif)};
--font-family-monospace: #{meta.inspect($font-family-monospace)};
}
===
@use "sass:meta"
}
===
@use "sass:meta"
$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto
$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas
$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto
$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas
:root
:root
--font-family-sans-serif: #{meta.inspect($font-family-sans-serif)}
--font-family-monospace: #{meta.inspect($font-family-monospace)}
===
:root {
===
:root {
--font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto;
--font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas;
}
{% endcodeExample %}
}
{% endcodeExample %}
{% endheadsUp %}

View File

@ -9,14 +9,14 @@ introduction: >
---
{% codeExample 'style-rules' %}
.button {
.button {
padding: 3px 10px;
font-size: 12px;
border-radius: 3px;
border: 1px solid #e1e4e8;
}
===
.button
}
===
.button
padding: 3px 10px
font-size: 12px
border-radius: 3px
@ -24,40 +24,42 @@ introduction: >
{% 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.
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 %}
{% render 'code-snippets/example-nesting' %}
{% headsUp %}
Nested rules are super helpful, but they can also make it hard to visualize how
much CSS you're actually generating. The deeper you nest, the more bandwidth it
takes to serve your CSS and the more work it takes the browser to render it.
Keep those selectors shallow!
Nested rules are super helpful, but they can also make it hard to visualize
how much CSS you're actually generating. The deeper you nest, the more
bandwidth it takes to serve your CSS and the more work it takes the browser to
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.
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 %}
{% codeExample 'selector-lists' %}
.alert, .warning {
.alert, .warning {
ul, p {
margin-right: 0;
margin-left: 0;
padding-bottom: 0;
}
}
===
.alert, .warning
}
===
.alert, .warning
ul, p
margin-right: 0
margin-left: 0
@ -65,88 +67,89 @@ separately, and then they're combined back into a selector list.
{% 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
[combinators]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors#Combinators#Combinators
{% endmarkdown %}
{% codeExample 'selector-combinators' %}
ul > {
ul > {
li {
list-style-type: none;
}
}
}
h2 {
h2 {
+ p {
border-top: 1px solid gray;
}
}
}
p {
p {
~ {
span {
opacity: 0.8;
}
}
}
===
ul >
}
===
ul >
li
list-style-type: none
h2
h2
+ p
border-top: 1px solid gray
p
p
~
span
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
[interpolation]: /documentation/interpolation
[expressions]: /documentation/syntax/structure#expressions
[mixins]: /documentation/at-rules/mixin
{% endmarkdown %}
{% codeExample 'interpolation' %}
@mixin define-emoji($name, $glyph) {
@mixin define-emoji($name, $glyph) {
span.emoji-#{$name} {
font-family: IconFont;
font-variant: normal;
font-weight: normal;
content: $glyph;
}
}
}
@include define-emoji("women-holding-hands", "👭");
===
@mixin define-emoji($name, $glyph)
@include define-emoji("women-holding-hands", "👭");
===
@mixin define-emoji($name, $glyph)
span.emoji-#{$name}
font-family: IconFont
font-variant: normal
@ -155,22 +158,22 @@ parameters your users pass in.
@include define-emoji("women-holding-hands", "👭")
@include define-emoji("women-holding-hands", "👭")
{% endcodeExample %}
{% funFact %}
Sass only parses selectors *after* interpolation is resolved. This means you can
safely use interpolation to generate any part of the selector without worrying
that it won't parse.
Sass only parses selectors *after* interpolation is resolved. This means you
can safely use interpolation to generate any part of the selector without
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
[`@at-root` rule]: /documentation/at-rules/at-root
[selector functions]: /documentation/modules/selector
[parent selector documentation]: /documentation/style-rules/parent-selector
{% endmarkdown %}

View File

@ -10,13 +10,13 @@ introduction: >
---
{% 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.
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 %}
{% codeExample 'parent-selector' %}
.alert {
.alert {
// The parent selector can be used to add pseudo-classes to the outer
// selector.
&:hover {
@ -34,9 +34,9 @@ behavior.
:not(&) {
opacity: 0.8;
}
}
===
.alert
}
===
.alert
// The parent selector can be used to add pseudo-classes to the outer
// selector.
&:hover
@ -56,30 +56,30 @@ behavior.
{% endcodeExample %}
{% headsUp %}
Because the parent selector could be replaced by a type selector like `h1`, it's
only allowed at the beginning of compound selectors where a type selector would
also be allowed. For example, `span&` is not allowed.
Because the parent selector could be replaced by a type selector like `h1`,
it's only allowed at the beginning of compound selectors where a type selector
would also be allowed. For example, `span&` is not allowed.
We're looking into loosening this restriction, though. If you'd like to help
make that happen, check out [this GitHub issue][].
We're looking into loosening this restriction, though. If you'd like to help
make that happen, check out [this GitHub issue][].
[this GitHub issue]: https://github.com/sass/sass/issues/1425
[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/
[BEM]: http://getbem.com/
{% endmarkdown %}
{% codeExample 'parent-selector-suffixes' %}
.accordion {
.accordion {
max-width: 600px;
margin: 4rem auto;
width: 90%;
@ -98,9 +98,9 @@ parent selector to append additional text.
display: block;
}
}
}
===
.accordion
}
===
.accordion
max-width: 600px
margin: 4rem auto
width: 90%
@ -120,62 +120,62 @@ parent selector to append additional text.
{% 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
[selector functions]: /documentation/modules/selector#selector-values
{% endmarkdown %}
{% codeExample 'parent-selector-sassscript' %}
.main aside:hover,
.sidebar p {
.main aside:hover,
.sidebar p {
parent-selector: &;
// => ((unquote(".main") unquote("aside:hover")),
// (unquote(".sidebar") unquote("p")))
}
===
.main aside:hover,
.sidebar p
}
===
.main aside:hover,
.sidebar p
parent-selector: &
// => ((unquote(".main") unquote("aside:hover")),
// (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
[falsey]: /documentation/at-rules/control/if#truthiness-and-falsiness
{% endmarkdown %}
{% 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
[selector functions]: /documentation/modules/selector#selector-values
[`@at-root` rule]: /documentation/at-rules/at-root
{% endmarkdown %}
{% render 'code-snippets/example-advanced-nesting' %}
{% headsUp %}
When Sass is nesting selectors, it doesn't know what interpolation was used to
generate them. This means it will automatically add the outer selector to the
inner selector *even if* you used `&` as a SassScript expression. That's why you
need to explicitly use the [`@at-root` rule][] to tell Sass not to include the
outer selector.
When Sass is nesting selectors, it doesn't know what interpolation was used to
generate them. This means it will automatically add the outer selector to the
inner selector *even if* you used `&` as a SassScript expression. That's why
you need to explicitly use the [`@at-root` rule][] to tell Sass not to include
the outer selector.
[`@at-root` rule]: /documentation/at-rules/at-root
[`@at-root` rule]: /documentation/at-rules/at-root
{% endheadsUp %}

View File

@ -11,35 +11,35 @@ 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
[extended]: /documentation/at-rules/extend
{% endmarkdown %}
{% codeExample 'extended-selector' %}
%toolbelt {
%toolbelt {
box-sizing: border-box;
border-top: 1px rgba(#000, .12) solid;
padding: 16px 0;
width: 100%;
&:hover { border: 2px rgba(#000, .5) solid; }
}
}
.action-buttons {
.action-buttons {
@extend %toolbelt;
color: #4285f4;
}
}
.reset-buttons {
.reset-buttons {
@extend %toolbelt;
color: #cddc39;
}
===
%toolbelt
}
===
%toolbelt
box-sizing: border-box
border-top: 1px rgba(#000, .12) solid
padding: 16px 0
@ -48,19 +48,19 @@ for their HTML.
&:hover
border: 2px rgba(#000, .5) solid
.action-buttons
.action-buttons
@extend %toolbelt
color: #4285f4
.reset-buttons
.reset-buttons
@extend %toolbelt
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.
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 %}