Unsupported Sass+ Features
This document lists Sass and SCSS features that are parsed correctly by Jess but are intentionally not supported during evaluation/compilation. These features represent design decisions that Jess avoids in favor of better alternatives.
This page covers features that parse but do not evaluate. For input that Sass+ rejects outright as a parse error (invalid CSS that Sass tolerates — bogus combinators, escaped directive keywords, etc.), see Stricter than Sass.
What is Sass+?
Sass+ is Sass without the bad parts. Jess supports the core Sass/SCSS syntax and features that provide real value, while intentionally omitting features that exist only because Sass painted itself into architectural corners.
Jess provides better alternatives through:
- Real AST ownership - Control evaluation order and structure without tree violations
- Explicit visibility controls - Use
rulesVisibilityoptions to control what's exported - Module boundaries - Use
@-composewith protection flags for clear module APIs - Intentional structure - Write code where it belongs instead of teleporting it around
Intentionally Unsupported Features
@at-root
The @at-root directive allows you to "teleport" rules to the root level even when nested inside other rules or at-rules.
Sass syntax:
@media print {
.page {
width: 8in;
@at-root (without: media) {
color: #111;
}
}
}
Why Sass needed it (and Jess doesn't):
Sass's constraints:
- Single-pass-ish evaluation
- Everything is text expansion
- No real AST ownership
- No phase separation
- No registration APIs
Why Jess doesn't need it:
Jess's advantages:
- You have an AST - you control the structure from the start
- You control evaluation order - no need to move things around after the fact
- You can organize code intentionally - write things where they belong
How to avoid needing @at-root in Jess:
-
Write utilities at the top level: Instead of nesting utilities inside other rules and trying to "teleport" them out, simply write them at the root level where they belong:
// Instead of this (Sass):
@media print {
.page {
@at-root .utility { color: red; }
}
}
// Do this (Jess):
.utility { color: red; }
@media print {
.page { /* ... */ }
} -
Use separate files/modules: If you need utilities that should be at the root level, put them in a separate file and compose it:
// utilities.jess
.utility { color: red; }
.another-utility { background: blue; }
// main.jess
@-compose "utilities";
@media print {
.page { /* ... */ }
} -
Structure your code intentionally: Jess gives you full control over your AST structure. If something needs to be at the root, write it at the root. If it needs to be nested, nest it. There's no need for "teleportation" because you control the structure from the start.
-
Use visibility controls when needed: If you need to conditionally include/exclude rules, use Jess's
rulesVisibilityoptions or control flow (@if) rather than trying to move rules around the tree.
Status: Parsed as an AtRule node, but will never be supported. A warning is emitted when this directive is encountered.
Verdict: There is no use case where @at-root is fundamentally necessary in a language designed sanely from the start. It only exists because Sass lacked proper AST control and forced developers to work around its limitations. Jess gives you full control over structure from the beginning, eliminating the need for tree manipulation hacks.
@forward with show/hide lists
Sass's @forward directive supports show and hide keywords to selectively re-export members from a module.
Sass syntax:
@forward "theme" show $colors, mixin-button;
@forward "utils" hide $internal-var, private-mixin;
Why this isn't supported:
Visibility control is the module's responsibility, not the forwarding module's. Each module should define its own public vs private API using rulesVisibility options. External modules shouldn't be able to override or filter another module's visibility decisions.
Jess alternative:
Modules control their own visibility. Use rulesVisibility options on declarations within the module itself:
// theme.jess - module defines its own public API
$colors: /* ... */; // public by default
@mixin button { /* ... */ } // public by default
// Private implementation details
$internal-var: /* ... */; // marked as private via rulesVisibility
@mixin _internal-mixin { /* ... */ } // marked as private
// main.jess
@-compose "theme";
// Only public members from theme.jess are accessible
Status: Parsed and metadata is captured (forwardShow/forwardHide on StyleImport.importOptions), but the filtering semantics are not implemented and will not be.
Verdict: Visibility is a module's own concern. External filtering violates encapsulation and makes it harder to reason about what a module actually exports.
@forward with as <prefix>-* prefixing
Sass's @forward supports automatic prefixing of all exported members.
Sass syntax:
@forward "theme" as theme-*;
// Exports $theme-colors, mixin-theme-button, etc.
Why this is problematic:
- String manipulation at module boundaries - Relies on prefix matching and string concatenation
- Unclear ownership - The forwarding module controls naming of forwarded members
- Hard to refactor - Changing prefixes requires updating all consumers
Jess alternative:
Use explicit namespacing:
@-compose "theme" as theme;
// Then access values as $theme.colors and keep mixin names explicit.
Status: Parsed and metadata is captured (forwardAsPrefix on StyleImport.importOptions), but the prefixing semantics are not implemented and will not be.
Verdict: Explicit namespacing is clearer and more maintainable than automatic string prefixing.
Philosophy
Jess supports Sass/SCSS syntax for conversion and compatibility, but makes unsupported features explicit and ugly (via warnings). We do not encourage these patterns and will not build new features around them.
Every "legit" Sass use case for these features is only legit because Sass painted itself into architectural corners. Jess solves the underlying problems by giving you proper AST control and explicit visibility mechanisms from the start.
Reporting Issues
If you encounter a Sass feature that you believe should be supported, please open an issue with:
- The Sass/SCSS code that uses the feature
- Your use case and why you need it
- Whether any of the Jess alternatives above would work for you