What should the syntax for module mixins be?
See original GitHub issueDraft 2 of the proposal allows a module mixin to be defined using the syntax @use "susy" mixin
. This defines a mixin with the same name as the module’s prefix that, when included, injects the module’s CSS at that point in the document. This is intended to satisfy the use-case currently handled using nested imports, where a user wants to scope a chunk of upstream CSS within a specific selector or media query.
I’m not sure this is the best syntax to use, though. Creating an implicit mixin feels weird, especially because it means namespace
and namespace.member
will both be meaningful identifiers, but the latter won’t actually be referring to a member of the former. It would also be the only instance under the new module system where a @use
without no-prefix
would create an identifier that’s not part of a unique namespace.
Note: I’m considering this discussion largely orthogonal to https://github.com/sass/language/issues/8. In any of these proposals, the module mixin may or may not allow configuration parameters to be passed.
Possible Options
-
Keep the existing syntax
@use "susy" mixin; .susy { @include susy; }
-
Add a meta mixin and a
silent
modifierThis mixin would take the namespace or URL of the module and include its CSS. This way we don’t pollute the top-level namespace. It would also require adding a modifier to
@use
to tell it not to generate any CSS on its own, but that may be useful anyway.@use "susy" silent; @use "sass:meta"; .susy { @include meta.module-css("susy"); }
-
Add a meta mixin that can dynamically load files
If the meta mixin can take a module URL, it raises a new question: why not just allow it to take any URL, not just one that has a
@use
declaration in the same file? This dovetails with the plannedload()
function nicely; it would effectively be a shorthand for@include meta.include(map.get(meta.load($url), "css"))
.It also dodges most of the downsides of dynamic includes, because it explicitly does not introduce any new names to the file that includes it. Static analysis therefore remains tractable (although, as with
load()
, it does become impossible to statically determine the set of files a stylesheet depends on).@use "sass:meta"; .susy { @include meta.load-css("susy"); }
Issue Analytics
- State:
- Created 5 years ago
- Comments:5 (4 by maintainers)
Top GitHub Comments
I would actually propose an alternate approach here, with the goal of creating a generally more strict and explicit system to combining concrete CSS trees:
@use
always encapsulates the CSS tree of the target into a mixin (or similar construct). This admittedly further departs from the existing@import
mechanics, but pushes for a more explicit ecosystem. Since@use
is a totally new syntax, it’s the perfect time to change how people think about importing other Sass files.The motivations here are:
@use
mixins/variables/functions. I have seen this happen on multiple occasions, with people unknowingly ballooning their CSS payload size.@use
can interact with CSS trees. Having exactly one mental model for@use
makes it easier to internalize.Since
@import
is a standard CSS feature, it would then make sense to continue using@import
to do what it does today (always pulling in the full CSS tree of the target).Now that the module system proposal has been accepted, this has been definitively decided: module mixins are included using a special built in
meta.load-css()
mixin.