Merge pull request #55 from oddbird/port-docs-atrules-error-warn-debug-atroot

Porting documentation - At-Rules - @error, @warn, @debug, @at-root, Flow Control, From CSS
This commit is contained in:
Jonny Gerig Meyer 2023-05-30 16:28:45 -04:00 committed by GitHub
commit 7d43f9fae3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 917 additions and 1 deletions

View File

@ -34,6 +34,6 @@
{%- if details | strip -%}
<div class="sl-c-callout sl-c-callout--impl-status">
{{ details | markdown }}
{% if useMarkdown %}{{ details | markdown }}{% else %}{{ details }}{% endif %}
</div>
{%- endif -%}

View File

@ -0,0 +1,19 @@
{% codeExample 'each-list' %}
$sizes: 40px, 50px, 80px;
@each $size in $sizes {
.icon-#{$size} {
font-size: $size;
height: $size;
width: $size;
}
}
===
$sizes: 40px, 50px, 80px
@each $size in $sizes
.icon-#{$size}
font-size: $size
height: $size
width: $size
{% endcodeExample %}

View File

@ -0,0 +1,19 @@
{% codeExample 'each-map' %}
$icons: ("eye": "\f112", "start": "\f12e", "stop": "\f12f");
@each $name, $glyph in $icons {
.icon-#{$name}:before {
display: inline-block;
font-family: "Icon Font";
content: $glyph;
}
}
===
$icons: ("eye": "\f112", "start": "\f12e", "stop": "\f12f")
@each $name, $glyph in $icons
.icon-#{$name}:before
display: inline-block
font-family: "Icon Font"
content: $glyph
{% endcodeExample %}

View File

@ -0,0 +1,29 @@
{% codeExample 'example-if' %}
@mixin avatar($size, $circle: false) {
width: $size;
height: $size;
@if $circle {
border-radius: $size / 2;
}
}
.square-av {
@include avatar(100px, $circle: false);
}
.circle-av {
@include avatar(100px, $circle: true);
}
===
@mixin avatar($size, $circle: false)
width: $size
height: $size
@if $circle
border-radius: $size / 2
.square-av
@include avatar(100px, $circle: false)
.circle-av
@include avatar(100px, $circle: true)
{% endcodeExample %}

View File

@ -0,0 +1,79 @@
---
title: "@at-root"
introduction: >
The `@at-root` rule is usually written `@at-root <selector> { ... }` and
causes everything within it to be emitted at the root of the document instead
of using the normal nesting. It's most often used when doing [advanced
nesting](/documentation/style-rules/parent-selector#advanced-nesting) with the
[SassScript parent
selector](/documentation/style-rules/parent-selector#in-sassscript) and
[selector functions](/documentation/modules/selector).
---
{% render 'code-snippets/example-advanced-nesting' %}
{% markdown %}
The `@at-root` rule is necessary here because Sass doesn't know what
interpolation was used to generate a selector when it's performing selector
nesting. This means it will automatically add the outer selector to the inner
selector *even if* you used `&` as a SassScript expression. The `@at-root`
explicitly tells Sass not to include the outer selector.
{% funFact %}
The `@at-root` rule can also be written `@at-root { ... }` to put multiple style
rules at the root of the document. In fact, `@at-root <selector> { ... }` is
just a shorthand for `@at-root { <selector> { ... } }`!
{% endfunFact %}
## Beyond Style Rules
On its own, `@at-root` only gets rid of [style rules][]. Any at-rules like
[`@media`][] or [`@supports`][] will be left in. If this isn't what you want,
though, you can control exactly what it includes or excludes using syntax like
[media query features][], written `@at-root (with: <rules...>) { ... }` or
`@at-root (without: <rules...>) { ... }`. The `(without: ...)` query tells Sass
which rules should be excluded; the `(with: ...)` query excludes all rules
*except* those that are listed.
[style rules]: /documentation/style-rules
[`@media`]: /documentation/at-rules/css#media
[`@supports`]: /documentation/at-rules/css#supports
[media query features]: https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries#Targeting_media_features
{% endmarkdown %}
{% codeExample 'at-root' %}
@media print {
.page {
width: 8in;
@at-root (without: media) {
color: #111;
}
@at-root (with: rule) {
font-size: 1.2em;
}
}
}
===
@media print
.page
width: 8in
@at-root (without: media)
color: #111
@at-root (with: rule)
font-size: 1.2em
{% endcodeExample %}
{% markdown %}
In addition to the names of at-rules, there are two special values that can be
used in queries:
* `rule` refers to style rules. For example, `@at-root (with: rule)` excludes
all at-rules but preserves style rules.
* `all` refers to all at-rules *and* style rules should be excluded.
{% endmarkdown %}

View File

@ -0,0 +1,73 @@
---
title: "@each"
introduction: >
The `@each` rule makes it easy to emit styles or evaluate code for each
element of a [list](/documentation/values/lists) or each pair in a
[map](/documentation/values/maps). Its great for repetitive styles that only
have a few variations between them. Its usually written `@each <variable> in
<expression> { ... }`, where the
[expression](/documentation/syntax/structure#expressions) returns a list. The
block is evaluated for each element of the list in turn, which is assigned to
the given variable name.
---
{% render 'code-snippets/example-each-list' %}
{% markdown %}
## With Maps
You can also use `@each` to iterate over every key/value pair in a map by
writing it `@each <variable>, <variable> in <expression> { ... }`. The key is
assigned to the first variable name, and the element is assigned to the second.
{% endmarkdown %}
{% render 'code-snippets/example-each-map' %}
{% markdown %}
## Destructuring
If you have a list of lists, you can use `@each` to automatically assign
variables to each of the values from the inner lists by writing it
`@each <variable...> in <expression> { ... }`. This is known as *destructuring*,
since the variables match the structure of the inner lists. Each variable name
is assigned to the value at the corresponding position in the list, or
[`null`][] if the list doesn't have enough values.
[`null`]: /documentation/values/null
{% endmarkdown %}
{% codeExample 'each' %}
$icons:
"eye" "\f112" 12px,
"start" "\f12e" 16px,
"stop" "\f12f" 10px;
@each $name, $glyph, $size in $icons {
.icon-#{$name}:before {
display: inline-block;
font-family: "Icon Font";
content: $glyph;
font-size: $size;
}
}
===
$icons: "eye" "\f112" 12px, "start" "\f12e" 16px, "stop" "\f12f" 10px
@each $name, $glyph, $size in $icons
.icon-#{$name}:before
display: inline-block
font-family: "Icon Font"
content: $glyph
font-size: $size
{% endcodeExample %}
{% funFact %}
Because `@each` supports destructuring and [maps count as lists of lists][],
`@each`'s map support works without needing special support for maps in
particular.
[maps count as lists of lists]: /documentation/values/maps
{% endfunFact %}

View File

@ -0,0 +1,27 @@
---
title: "@for"
introduction: >
The `@for` rule, written `@for <variable> from <expression> to <expression> {
... }` or `@for <variable> from <expression> through <expression> { ... }`,
counts up or down from one number (the result of the first
[expression](/documentation/syntax/structure#expressions)) to another (the
result of the second) and evaluates a block for each number in between. Each
number along the way is assigned to the given variable name. If `to` is used,
the final number is excluded; if `through` is used, it's included.
---
{% codeExample 'for' %}
$base-color: #036;
@for $i from 1 through 3 {
ul:nth-child(3n + #{$i}) {
background-color: lighten($base-color, $i * 5%);
}
}
===
$base-color: #036
@for $i from 1 through 3
ul:nth-child(3n + #{$i})
background-color: lighten($base-color, $i * 5%)
{% endcodeExample %}

View File

@ -0,0 +1,149 @@
---
title: "@if and @else"
table_of_contents: true
introduction: >
The `@if` rule is written `@if <expression> { ... }`, and it controls whether
or not its block gets evaluated (including emitting any styles as CSS). The
[expression](/documentation/syntax/structure#expressions) usually returns
either [`true` or `false`](/documentation/values/booleans)—if the expression
returns `true`, the block is evaluated, and if the expression returns `false`
its not.
---
{% render 'code-snippets/example-if' %}
{% markdown %}
## `@else`
An `@if` rule can optionally be followed by an `@else` rule, written
`@else { ... }`. This rule's block is evaluated if the `@if` expression returns
`false`.
{% endmarkdown %}
{% codeExample 'if' %}
$light-background: #f2ece4;
$light-text: #036;
$dark-background: #6b717f;
$dark-text: #d2e1dd;
@mixin theme-colors($light-theme: true) {
@if $light-theme {
background-color: $light-background;
color: $light-text;
} @else {
background-color: $dark-background;
color: $dark-text;
}
}
.banner {
@include theme-colors($light-theme: true);
body.dark & {
@include theme-colors($light-theme: false);
}
}
===
$light-background: #f2ece4
$light-text: #036
$dark-background: #6b717f
$dark-text: #d2e1dd
@mixin theme-colors($light-theme: true)
@if $light-theme
background-color: $light-background
color: $light-text
@else
background-color: $dark-background
color: $dark-text
.banner
@include theme-colors($light-theme: true)
body.dark &
@include theme-colors($light-theme: false)
{% endcodeExample %}
{% markdown %}
Conditional expressions may contain [boolean operators][] (`and`, `or`, `not`).
[boolean operators]: /documentation/operators/boolean
### `@else if`
You can also choose whether to evaluate an `@else` rule's block by writing it
`@else if <expression> { ... }`. If you do, the block is evaluated only if the
preceding `@if`'s expression returns `false` *and* the `@else if`'s expression
returns `true`.
In fact, you can chain as many `@else if`s as you want after an `@if`. The
first block in the chain whose expression returns `true` will be evaluated, and
no others. If there's a plain `@else` at the end of the chain, its block will be
evaluated if every other block fails.
{% endmarkdown %}
{% codeExample 'else' %}
@use "sass:math";
@mixin triangle($size, $color, $direction) {
height: 0;
width: 0;
border-color: transparent;
border-style: solid;
border-width: math.div($size, 2);
@if $direction == up {
border-bottom-color: $color;
} @else if $direction == right {
border-left-color: $color;
} @else if $direction == down {
border-top-color: $color;
} @else if $direction == left {
border-right-color: $color;
} @else {
@error "Unknown direction #{$direction}.";
}
}
.next {
@include triangle(5px, black, right);
}
===
@use "sass:math"
@mixin triangle($size, $color, $direction)
height: 0
width: 0
border-color: transparent
border-style: solid
border-width: math.div($size, 2)
@if $direction == up
border-bottom-color: $color
@else if $direction == right
border-left-color: $color
@else if $direction == down
border-top-color: $color
@else if $direction == left
border-right-color: $color
@else
@error "Unknown direction #{$direction}."
.next
@include triangle(5px, black, right)
===
.next {
height: 0;
width: 0;
border-color: transparent;
border-style: solid;
border-width: 2.5px;
border-left-color: black;
}
{% endcodeExample %}
{% render 'documentation/snippets/truthiness-and-falsiness' %}

View File

@ -0,0 +1,24 @@
---
title: Flow Control Rules
introduction: >
Sass provides a number of at-rules that make it possible to control whether
styles get emitted, or to emit them multiple times with small variations. They
can also be used in [mixins](/documentation/at-rules/mixin) and
[functions](/documentation/at-rules/function) to write small algorithms to
make writing your Sass easier. Sass supports four flow control rules.
---
- [`@if`](/documentation/at-rules/control/if) controls whether or not a block is
evaluated.
- [`@each`](/documentation/at-rules/control/each) evaluates a block for each
element in a [list][] or each pair in a [map][].
- [`@for`](/documentation/at-rules/control/for) evaluates a block a certain
number of times.
- [`@while`](/documentation/at-rules/control/while) evaluates a block until a
certain condition is met.
[list]: /documentation/values/lists
[map]: /documentation/values/maps

View File

@ -0,0 +1,55 @@
---
title: "@while"
introduction: >
The `@while` rule, written `@while <expression> { ... }`, evaluates its block
if its [expression](/documentation/syntax/structure#expressions) returns
`true`. Then, if its expression still returns `true`, it evaluates its block
again. This continues until the expression finally returns `false`.
---
{% codeExample 'while' %}
@use "sass:math";
/// Divides `$value` by `$ratio` until it's below `$base`.
@function scale-below($value, $base, $ratio: 1.618) {
@while $value > $base {
$value: math.div($value, $ratio);
}
@return $value;
}
$normal-font-size: 16px;
sup {
font-size: scale-below(20px, 16px);
}
===
@use "sass:math"
/// Divides `$value` by `$ratio` until it's below `$base`.
@function scale-below($value, $base, $ratio: 1.618)
@while $value > $base
$value: math.div($value, $ratio)
@return $value
$normal-font-size: 16px
sup
font-size: scale-below(20px, 16px)
===
sup {
font-size: 12.36094px;
}
{% endcodeExample %}
{% headsUp %}
Although `@while` is necessary for a few particularly complex stylesheets,
you're usually better of using either [`@each`][] or [`@for`][] if either of
them will work. They're clearer for the reader, and often faster to compile as
well.
[`@each`]: /documentation/at-rules/control/each
[`@for`]: /documentation/at-rules/control/for
{% endheadsUp %}
{% render 'documentation/snippets/truthiness-and-falsiness' %}

View File

@ -0,0 +1,227 @@
---
title: CSS At-Rules
table_of_contents: true
---
{% # Arguments are (in order): `dart`, `libsass`, `node`, `ruby`, optional feature name, additional details within %}
{% compatibility '1.15.0', false, null, false, "Name Interpolation" %}
LibSass, Ruby Sass, and older versions of Dart Sass don't support
[interpolation][] in at-rule names. They do support interpolation in values.
[interpolation]: /documentation/interpolation
{% endcompatibility %}
{% markdown %}
Sass supports all the at-rules that are part of CSS proper. To stay flexible and
forwards-compatible with future versions of CSS, Sass has general support that
covers almost all at-rules by default. A CSS at-rule is written
`@<name> <value>`, `@<name> { ... }`, or `@<name> <value> { ... }`. The name
must be an identifier, and the value (if one exists) can be pretty much
anything. Both the name and the value can contain [interpolation][].
[interpolation]: /documentation/interpolation
{% endmarkdown %}
{% codeExample 'css' %}
@namespace svg url(http://www.w3.org/2000/svg);
@font-face {
font-family: "Open Sans";
src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
}
@counter-style thumbs {
system: cyclic;
symbols: "\1F44D";
}
===
@namespace svg url(http://www.w3.org/2000/svg)
@font-face
font-family: "Open Sans"
src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2")
@counter-style thumbs
system: cyclic
symbols: "\1F44D"
{% endcodeExample %}
{% markdown %}
If a CSS at-rule is nested within a style rule, the two automatically swap
positions so that the at-rule is at the top level of the CSS output and the
style rule is within it. This makes it easy to add conditional styling without
having to rewrite the style rule's selector.
{% endmarkdown %}
{% codeExample 'nested-css-at-rule' %}
.print-only {
display: none;
@media print { display: block; }
}
===
.print-only
display: none
@media print
display: block
{% endcodeExample %}
{{ '## `@media`' | markdown }}
{% # Arguments are (in order): `dart`, `libsass`, `node`, `ruby`, optional feature name, additional details within %}
{% compatibility '1.11.0', false, null, '3.7.0', 'Range Syntax', false %}
{% markdown %}
LibSass and older versions of Dart Sass and Ruby Sass don't support media
queries with features written in a [range context][]. They do support other
standard media queries.
[range context]: https://www.w3.org/TR/mediaqueries-4/#mq-range-context
{% endmarkdown %}
{% codeExample 'range-syntax', false %}
@media (width <= 700px) {
body {
background: green;
}
}
===
@media (width <= 700px)
body
background: green
===
@media (width <= 700px) {
body {
background: green;
}
}
{% endcodeExample %}
{% endcompatibility %}
{% markdown %}
The [`@media` rule][] does all of the above and more. In addition to allowing
interpolation, it allows [SassScript expressions][] to be used directly in the
[feature queries][].
[`@media` rule]: https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries
[SassScript expressions]: /documentation/syntax/structure#expressions
[feature queries]: https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries#Targeting_media_features
{% endmarkdown %}
{% codeExample 'media-rule' %}
$layout-breakpoint-small: 960px;
@media (min-width: $layout-breakpoint-small) {
.hide-extra-small {
display: none;
}
}
===
$layout-breakpoint-small: 960px
@media (min-width: $layout-breakpoint-small)
.hide-extra-small
display: none
{% endcodeExample %}
{% markdown %}
When possible, Sass will also merge media queries that are nested within one
another to make it easier to support browsers that don't yet natively support
nested `@media` rules.
{% endmarkdown %}
{% codeExample 'merge-media-queries' %}
@media (hover: hover) {
.button:hover {
border: 2px solid black;
@media (color) {
border-color: #036;
}
}
}
===
@media (hover: hover)
.button:hover
border: 2px solid black
@media (color)
border-color: #036
{% endcodeExample %}
{% markdown %}
## `@supports`
The [`@supports` rule][] also allows [SassScript expressions][] to be used in
the declaration queries.
[SassScript expressions]: /documentation/syntax/structure#expressions
[`@supports` rule]: https://developer.mozilla.org/en-US/docs/Web/CSS/@supports
{% endmarkdown %}
{% codeExample 'support-at-rule' %}
@mixin sticky-position {
position: fixed;
@supports (position: sticky) {
position: sticky;
}
}
.banner {
@include sticky-position;
}
===
@mixin sticky-position
position: fixed
@supports (position: sticky)
position: sticky
.banner
@include sticky-position
{% endcodeExample %}
{% markdown %}
## `@keyframes`
The [`@keyframes` rule][] works just like a general at-rule, except that its
child rules must be valid keyframe rules (`<number>%`, `from`, or `to`) rather
than normal selectors.
[`@keyframes` rule]: https://developer.mozilla.org/en-US/docs/Web/CSS/@keyframes
{% endmarkdown %}
{% codeExample 'keyframes' %}
@keyframes slide-in {
from {
margin-left: 100%;
width: 300%;
}
70% {
margin-left: 90%;
width: 150%;
}
to {
margin-left: 0%;
width: 100%;
}
}
===
@keyframes slide-in
from
margin-left: 100%
width: 300%
70%
margin-left: 90%
width: 150%
to
margin-left: 0%
width: 100%
{% endcodeExample %}

View File

@ -0,0 +1,43 @@
---
title: "@debug"
introduction: >
Sometimes its useful to see the value of a
[variable](/documentation/variables) or
[expression](/documentation/syntax/structure#expressions) while youre
developing your stylesheet. Thats what the `@debug` rule is for: its written
`@debug <expression>`, and it prints the value of that expression, along with
the filename and line number.
---
{% codeExample 'debug', false %}
@mixin inset-divider-offset($offset, $padding) {
$divider-offset: (2 * $padding) + $offset;
@debug "divider offset: #{$divider-offset}";
margin-left: $divider-offset;
width: calc(100% - #{$divider-offset});
}
===
@mixin inset-divider-offset($offset, $padding)
$divider-offset: (2 * $padding) + $offset
@debug "divider offset: #{$divider-offset}"
margin-left: $divider-offset
width: calc(100% - #{$divider-offset})
{% endcodeExample %}
{% markdown %}
The exact format of the debug message varies from implementation to
implementation. This is what it looks like in Dart Sass:
```
test.scss:3 Debug: divider offset: 132px
```
{% endmarkdown %}
{% funFact %}
You can pass any value to `@debug`, not just a string! It prints the same
representation of that value as the [`meta.inspect()` function][].
[`meta.inspect()` function]: /documentation/modules/meta#inspect
{% endfunFact %}

View File

@ -0,0 +1,80 @@
---
title: "@error"
introduction: >
When writing [mixins](/documentation/at-rules/mixin) and
[functions](/documentation/at-rules/function) that take arguments, you usually
want to ensure that those arguments have the types and formats your API
expects. If they aren't, the user needs to be notified and your mixin/function
needs to stop running.
---
{% markdown %}
Sass makes this easy with the `@error` rule, which is written
`@error <expression>`. It prints the value of the [expression][] (usually a
string) along with a stack trace indicating how the current mixin or function
was called. Once the error is printed, Sass stops compiling the stylesheet and
tells whatever system is running it that an error occurred.
[expression]: /documentation/syntax/structure#expressions
{% endmarkdown %}
{% codeExample 'error', false %}
@mixin reflexive-position($property, $value) {
@if $property != left and $property != right {
@error "Property #{$property} must be either left or right.";
}
$left-value: if($property == right, initial, $value);
$right-value: if($property == right, $value, initial);
left: $left-value;
right: $right-value;
[dir=rtl] & {
left: $right-value;
right: $left-value;
}
}
.sidebar {
@include reflexive-position(top, 12px);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Error: Property top must be either left or right.
}
===
@mixin reflexive-position($property, $value)
@if $property != left and $property != right
@error "Property #{$property} must be either left or right."
$left-value: if($property == right, initial, $value)
$right-value: if($property == right, $value, initial)
left: $left-value
right: $right-value
[dir=rtl] &
left: $right-value
right: $left-value
.sidebar
@include reflexive-position(top, 12px)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Error: Property top must be either left or right.
{% endcodeExample %}
{% markdown %}
The exact format of the error and stack trace varies from implementation to
implementation, and can also depend on your build system. This is what it looks
like in Dart Sass when run from the command line:
```
Error: "Property top must be either left or right."
3 │ @error "Property #{$property} must be either left or right.";
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
example.scss 3:5 reflexive-position()
example.scss 19:3 root stylesheet
```
{% endmarkdown %}

View File

@ -0,0 +1,67 @@
---
title: "@warn"
introduction: >
When writing [mixins](/documentation/at-rules/mixin) and
[functions](/documentation/at-rules/function), you may want to discourage
users from passing certain arguments or certain values. They may be passing
legacy arguments that are now deprecated, or they may be calling your API in a
way thats not quite optimal.
---
{% markdown %}
The `@warn` rule is designed just for that. It's written `@warn <expression>`
and it prints the value of the [expression][] (usually a string) for the user,
along with a stack trace indicating how the current mixin or function was
called. Unlike the [`@error` rule][], though, it doesn't stop Sass entirely.
[expression]: /documentation/syntax/structure#expressions
[`@error` rule]: /documentation/at-rules/error
{% endmarkdown %}
{% codeExample 'warn' %}
$known-prefixes: webkit, moz, ms, o;
@mixin prefix($property, $value, $prefixes) {
@each $prefix in $prefixes {
@if not index($known-prefixes, $prefix) {
@warn "Unknown prefix #{$prefix}.";
}
-#{$prefix}-#{$property}: $value;
}
#{$property}: $value;
}
.tilt {
// Oops, we typo'd "webkit" as "wekbit"!
@include prefix(transform, rotate(15deg), wekbit ms);
}
===
$known-prefixes: webkit, moz, ms, o
@mixin prefix($property, $value, $prefixes)
@each $prefix in $prefixes
@if not index($known-prefixes, $prefix)
@warn "Unknown prefix #{$prefix}."
-#{$prefix}-#{$property}: $value
#{$property}: $value
.tilt
// Oops, we typo'd "webkit" as "wekbit"!
@include prefix(transform, rotate(15deg), wekbit ms)
{% endcodeExample %}
{% markdown %}
The exact format of the warning and stack trace varies from implementation to
implementation. This is what it looks like in Dart Sass:
```
Warning: Unknown prefix wekbit.
example.scss 6:7 prefix()
example.scss 16:3 root stylesheet
```
{% endmarkdown %}

View File

@ -0,0 +1,23 @@
{% markdown %}
## Truthiness and Falsiness
Anywhere `true` or `false` are allowed, you can use other values as well. The
values `false` and [`null`][] are *falsey*, which means Sass considers them to
indicate falsehood and cause conditions to fail. Every other value is considered
*truthy*, so Sass considers them to work like `true` and cause conditions to
succeed.
[`null`]: /documentation/values/null
For example, if you want to check if a string contains a space, you can just
write `string.index($string, " ")`. The [`string.index()` function][] returns
`null` if the string isn't found and a number otherwise.
[`string.index()` function]: /documentation/modules/string#index
{% endmarkdown %}
{% headsUp %}
Some languages consider more values falsey than just `false` and `null`. Sass
isn't one of those languages! Empty strings, empty lists, and the number `0` are
all truthy in Sass.
{% endheadsUp %}

View File

@ -28,6 +28,7 @@ export const compatibility = async (
node: string | boolean | null = null,
ruby: string | boolean | null = null,
feature: string | null = null,
useMarkdown = true,
) =>
liquidEngine.renderFile('compatibility', {
details,
@ -36,6 +37,7 @@ export const compatibility = async (
node,
ruby,
feature,
useMarkdown,
});
/**