Visitar URL original
Early opt out behavior for `@mixin` · Issue #4262 · sass/sass · GitHub
Skip to content

Early opt out behavior for @mixin #4262

Open

Description

@cduivis

Problem

@mixin currently does not support an early opt-out mechanism.
This can result in code that is harder to follow, or harder to write, as either more nesting or more variables are needed.
Simply put, it adds cognitive complexity that an early opt-out could avoid.

In simple use cases (like the one I posted below) this seems to matter little, but I would argue that even there it already has benefits.
For larger blocks with more conditions this can ramp up the cognitive complexity rapidly.

Nesting Example

@mixin render-non-accessible-icon($icon) {
	@if $icon != null and $icon != "" {
		@if meta.type-of($icon) != "string" {
			@error "`$icon` should be a string.";
		}

		content : $icon;
		content : $icon / "";
	}
}

Variable Example

@mixin render-non-accessible-icon($icon) {
	$has-value : ($icon != null and $icon != "");

	@if $has-value and meta.type-of($icon) != "string" {
		@error "`$icon` should be a string.";
	}

	@if $has-value {
		content : $icon;
		content : $icon / "";
	}
}

Proposal

@mixin render-non-accessible-icon($icon) {
	@if $icon == null or $icon == "" {
		@return;
	}

	@if meta.type-of($icon) != "string" {
		@error "`$icon` should be a string.";
	}

	content : $icon;
	content : $icon / "";
}

When @return is reached, all properties / code before it is still rendered and executed, and everything after it is skipped.

Why @return

  1. @return is currently already used by @function, so people are already familiar with the keyword and its functionality.
  2. It mimics a known pattern from other languages like JS, Java, C#, etc.
  3. No backwards compatibility issues, as @return inside a @mixin currently throws a compile error.

That being said, I'm not married to the @return keyword.

Related issues

These are some issues I've found, which seem tangentially related:

Activity

  1. nex3 commented on Oct 28, 2026

    @nex3
    Contributor

    I think this is a reasonable feature. The main question I have is whether @return or @break is the appropriate at-rule here. @return, as you say, mirrors other languages in the sense that mixin is analogous to a void function, but it does carry the implication of a return value which isn't accurate here. @break would be more literally accurate to the intention of "end execution immediately", but it has the disadvantage that it would break the innermost loop rather than the mixin as a whole if used in a nested context. I'm open to hearing arguments either way.

  2. cduivis commented on Oct 30, 2026

    @cduivis
    Author

    Between those 2 I would argue for @return still, mainly because of the point you already made for being able to also "escape" the mixin in deeper nested contexts.

    In that way you keep open that possibility for when implementing #387 with @continue and @break, or if you would want to add an @switch @case with @break.

    As for the wording I think both work fine @break as in "stop what your are doing now", but also @return as in "return to the code you came from".
    The benefit @return has over @break from a conceptual point of view is that it's then consistently used in both @function and in @mixin to completely step out of the context of the "executable context", where @break is then consistently used to step out of smaller control flows.

    I also think keeping these naming conventions in sync with older languages, is a benefit for adopting / learning sass quicker as it's the same terminology as lets say JS, which is probably a language a person who would write more complex sass mixins and functions is already familiar with. Although I wouldn't want to rely on this reasoning in all use cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestunder considerationThe Sass team is debating whether to do this

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions