sass/spec/at-rules/mixin.md
2024-06-17 17:49:23 -07:00

4.2 KiB

@mixin, @include, and @content

Table of Contents

@mixin

Syntax

MixinRule ::= '@mixin' <ident-token> ArgumentDeclaration? '{' Statements '}'

No whitespace is allowed between the Identifier and the ArgumentDeclaration in MixinRule.

Semantics

To execute a @mixin rule rule:

  • Let name be the value of rule's Identifier.

  • If name begins with --, throw an error.

  • Let parent be the current scope.

  • Let mixin be a mixin named name which accepts a content block if rule contains a @content rule. To execute this mixin with args:

    • With the current scope set to an empty scope with parent as its parent:

      • Evaluate args with rule's ArgumentDeclaration.

      • Execute each statement in rule.

  • If rule is outside of any block of statements:

    • If name doesn't begin with - or _, set the current module's mixin name to mixin.

      This overrides the previous definition, if one exists.

    • Set the current import context's mixin name to mixin.

      This happens regardless of whether or not it begins with - or _.

  • Otherwise, set the current scope's mixin name to mixin.

    This overrides the previous definition, if one exists.

@include

Syntax

IncludeRule      ::= '@include' NamespacedIdentifier ArgumentInvocation?
                     ContentBlock?
ContentBlock     ::= UsingDeclaration? '{' Statements '}'
UsingDeclaration ::= 'using' ArgumentDeclaration

No whitespace is allowed between the NamespacedIdentifier and the ArgumentInvocation in IncludeRule.

Semantics

To execute an @include rule rule:

  • Let name be rule's NamespacedIdentifier.

  • Let mixin be the result of resolving a mixin named name. If this returns null, throw an error.

  • Execute mixin with rule's ArgumentInvocation.

@content

The @content rule runs a block of styles provided by the user who invoked the current mixin.

Syntax

ContentRule ::= '@content' ArgumentInvocation?

As with all statements, a ContentRule must be separated from other statements with a semicolon.

Semantics

To execute a @content rule content within a mixin that's invoked with an @include rule include:

@content rules are syntactically guaranteed to only appear in mixin bodies, and mixins must be invoked using @include, so include is guaranted to exist.

  • Let invocation be content's ArgumentInvocation, or an invocation with no arguments if content has no ArgumentInvocation.

    This means that @content and @content() are interpreted identically.

  • Let declaration be include's UsingDeclaration's ArgumentDeclaration, or a declaration with no arguments if include has no UsingDeclaration.

    This means that @include foo { ... } and @include foo using () { ... } are interpreted identically.

  • Let arguments be the result of applying invocation to declaration.

    This means arguments is a mapping from variable names to values. If invocation isn't a valid invocation of declaration, this will throw an error that should be surfaced to the user.

  • If include has no ContentBlock, do nothing.

    Exiting here rather than earlier means that @content(value) is an error if include has no content block.

  • Otherwise, let scope be a new scope that's a child of include's scope.

  • For each pair variable and value in arguments:

    • Set variable to value in scope.
  • Execute include's ContentBlock statements in scope.