Whitespace is the brace. Miss a space and the rule moves.
Classic Sass, the indented form, drops braces and semicolons. Nesting depth comes from leading spaces. A property sits under a selector. A child selector sits one indent deeper. The compiler turns the outline into ordinary CSS rules.
Most teams write SCSS now, braces and all. Indented files still show up in older codebases, in short snippets from docs, and in shops still on the original syntax. This page exists for those files. Paste, compile, read the CSS. No install, no upload.
What the indent parser expects
Before LibSass sees your file, the page rewrites indented Sass into SCSS-shaped text. The rewrite walks each line and decides: property, or block. A few rules decide the outcome.
- Two spaces per level. Tabs become spaces. Mixed tabs and spaces still compile, yet the nesting tree often lands one level off.
- A colon marks a property when the left side has no spaces and does not start with
.,#,%,[, or:. - Everything else opens a block. Selectors,
@mixin,@media, and placeholders get a brace added for the SCSS pass. - Blank lines pass through. They do not close a block. Only a shallower indent closes the open ones above.
The Sample button loads a small header with nested navigation so you see the rewrite path end to end.
Indented source, flattened CSS
$ink: #1a2b3c
$accent: #0d9488
.card
background: $ink
padding: 16px
&__title
color: $accent
font-size: 1.125rem
a
color: lighten($accent, 8%)text-decoration: none.card {background: #1a2b3c;padding: 16px;}
.card__title {color: #0d9488;font-size: 1.125rem;}
.card a {color: #12a897;text-decoration: none;}&__title glues with no space, so the class becomes .card__title. The nested a keeps a space and becomes a descendant. Color math resolves at compile time. The browser never sees lighten.
Mistakes indented Sass invites
- One space off on a property
- The property joins the parent block or opens a new selector. The CSS looks fine until a color lands on the wrong element. Count spaces from the left edge, not from the previous line.
- Braces pasted from an SCSS snippet
- The indent rewriter treats
{as part of a selector name. Compilation fails with a cryptic message. Strip braces and semicolons first, or switch tools. @import "partial"with no file behind the page- A browser tab has no project folder. Paste the partial contents inline, in import order, or compile on your machine with a real filesystem.
- Deep nesting for layout trees
- Five indent levels compile to a five-part descendant selector. Specificity climbs, markup moves break the match. Two levels is a safer habit. Prefer
&__class names over stacking tags.
LibSass under the hood, not Dart Sass
Compilation runs through sass.js, a LibSass build. LibSass stopped receiving language updates in 2020. Files written for current Dart Sass will fail here in predictable ways.
@useand@forwardfail. Rewrite to@importfor a quick check, or use the CLI for module-based projects.math.div($a, $b)fails. Write$a / $bin the copy you paste.- Namespaced built-ins such as
color.adjust()fail. Older global names likeadjust-color()still work.
For a design system on the module system, keep the CLI as the source of truth. Treat this page as a scratchpad for a single component or a snippet you need to inspect.
Where this compiler stops
- No source maps. Mapping a CSS line back to the indented origin needs a local build.
- No Autoprefixer. Sass never added vendor prefixes. Run the output through PostCSS if older browsers matter.
- No multi-file graph. Partials do not resolve. One paste, one compile.
- One error at a time. LibSass stops at the first failure. Fix the line, then compile again.
- Main-thread work. Multi-thousand-line sheets pause the tab while they compile. Fine for components. Awkward for a whole theme dump.
Need braces instead of indents as the source format? The SCSS Compiler takes SCSS. Going from CSS back toward Sass nesting is a different job, handled by the CSS to SCSS Converter.
Before you commit the CSS
- Scan selectors for depth. Three parts is a smell. Five means the indent tree grew past the markup.
- Check baked colors.
lighten($accent, 8%)is a fixed hex in the output. Runtime themes need CSS custom properties, which pass through untouched. - Match house style with the CSS Beautifier or shrink with the CSS Minifier before shipping.
