SASS to CSS Converter

Indented .sass in, browser-ready .css out. Variables get inlined, nested blocks flatten into full selectors, and mixins written with = and + expand where you called them. The compiler runs inside this tab, so nothing about your stylesheet touches a server.

Indented SASS
Compiled CSS

Paste indented SASS on the left to see compiled CSS here.

Ctrl + Enter recompiles

Two file extensions carry the Sass name and they are not interchangeable. A .scss file looks like CSS with extra features bolted on. A .sass file drops every brace and semicolon and uses indentation to mark structure, the way Python does. Paste the second kind into a normal SCSS compiler and you get a parse error on line one. This page reads the indented dialect directly.

Indentation is the syntax, so it has to be consistent

In a .sass file, a line indented deeper than the line above it becomes a child of that line. There is no other signal. Mix a tab into a file indented with spaces and the parser sees an indentation jump it cannot resolve, then reports something vague about an unexpected token several lines later.

When the first parse fails on whitespace, this page retries with tabs converted to spaces and says so in the status bar. Treat that message as a warning rather than a pass. A local Sass build has no such retry and will reject the same file. Set your editor to insert spaces, two per level, and fix the source rather than relying on the recovery.

Pasting SCSS here also works. The indented parse fails first, the page reads the input as SCSS on the second attempt, and the compiled CSS comes out the same.

Which pieces survive into the CSS file

Most Sass features exist only at compile time. Variables, mixin definitions, and silent comments never appear in the output. Knowing which is which saves a lot of confusion when the compiled file looks shorter than the source.

FeatureIndented .sassSCSS equivalentIn the CSS output?
Variable$brand: #cd6799$brand: #cd6799;No. The value gets substituted wherever you used it.
Nested ruleindent under the parent{ } bracesYes, flattened to .card .title.
Parent reference&:hover&:hoverYes, written out as .btn:hover.
Mixin definition=button($bg)@mixin button($bg)No. A definition alone emits nothing.
Mixin call+button(#cd6799)@include button(#cd6799);Yes. Declarations get copied into each caller.
Placeholder%chip with @extend%chip with @extendYes, as one grouped selector list instead of repeated blocks.
Loop@each, @forsameYes, one rule per iteration.
Silent comment// note// noteNo, stripped during compile.
Loud commentYes, except in minified output.

Load the Mixins example above and watch the difference in practice. The source defines =button once and calls it twice. The output contains two full rule blocks with no trace of the mixin, which is why heavy mixin reuse grows a CSS file faster than people expect. Placeholders with @extend group selectors instead of duplicating declarations, so they stay smaller at the cost of selector order you control less directly.

Mixin syntax trips up almost everyone

The indented dialect gives mixins their own shorthand. =name defines one and +name calls it. Both @mixin and @include also work in .sass files, so you will meet both styles in older codebases:

=card-shell
border-radius: 8px
padding: 16px
.pricing-card
+card-shell
border: 1px solid #e5e7eb

Define before you call. The compiler reads top to bottom, so a +card-shell above its =card-shell definition fails with a missing mixin error even though the name is spelled correctly.

The three compiler errors worth recognizing

  1. Invalid CSS after "...": expected expressionNearly always an indentation problem, not a value problem. Check the line above the reported one for a stray tab or an extra space level.
  2. File to import not found or unreadableAn @import pointing at a partial such as _variables. This converter has no file system, so partials cannot resolve. Paste the partial contents above the code that needs them.
  3. No mixin named xEither the call sits above the definition, or the file used +x while the definition lives in a separate partial that never got pasted in.

Empty output is not always a failure. A file holding only variables and mixin definitions compiles cleanly and produces zero bytes of CSS, because nothing in it applies to a selector. The status bar says so rather than showing a blank pane with no explanation.

What runs here and what still needs a build step

Compiles in this tab

  • Variables, arithmetic, and interpolation with #{}
  • Nesting of any depth, plus & parent references
  • Mixins with defaults and arguments, written as =/+ or @mixin/@include
  • Control directives: @if, @else, @each, @for, @while
  • Legacy color functions such as lighten(), darken(), mix(), rgba()
  • Nested @media and @supports blocks
  • Maps, lists, @extend, and placeholder selectors

Needs Dart Sass on your machine

  • @use and @forward. The module system arrived after this compiler engine froze.
  • Namespaced built-ins like math.div() or color.adjust()
  • @import of separate partial files
  • Source maps for browser debugging
  • Vendor prefixing, which belongs to Autoprefixer rather than Sass
  • Watching a folder and rebuilding on save

The engine behind this page is LibSass, compiled to run in the browser. LibSass stopped at the Sass 3.5 feature set and was retired in favor of Dart Sass. For converting a legacy .sass file, checking what a snippet expands to, or grabbing output during a code review, that gap rarely matters. For a project you actively ship, install Dart Sass and keep the build local. Division with / still works here while newer Dart Sass versions want math.div(), so code copied from this page into a modern build may raise deprecation warnings.

Moving off indented Sass

Teams migrating away from .sass usually go to SCSS first rather than straight to plain CSS, because SCSS keeps the variables and mixins intact. Compiling to CSS the way this page does throws that structure away, which is what you want when handing a stylesheet to a system with no build pipeline: a CMS theme field, an email template, or a plugin that accepts CSS only.

If you want to keep the features and only change the punctuation, use the SASS to SCSS converter instead. If you want the compiled result smaller, switch the output selector above to Minified, or run the expanded output through the CSS minifier for finer control over what gets stripped.

Privacy and file size

Compilation happens in JavaScript inside your browser tab. No stylesheet text is sent anywhere, which makes the tool usable on client work under NDA. The practical ceiling is around a few thousand lines. Past that, the browser main thread blocks noticeably during compile, and a local Dart Sass run finishes faster anyway.

Questions people hit when compiling .sass files

The issues that come up most often with indented Sass, answered without hand-waving.

What is the difference between .sass and .scss?

Both are Sass. The .scss syntax uses braces and semicolons and is a superset of CSS, so valid CSS is valid SCSS. The .sass syntax uses indentation for nesting and no punctuation at line ends. This page reads the indented .sass form. Pasting SCSS here still works because the converter retries through an SCSS path when the indented parse fails.

Why did my variables disappear from the CSS?

Variables live only during compilation. Sass substitutes the value everywhere you referenced the variable and then drops the declaration. If you want the value adjustable at runtime in the browser, write a CSS custom property such as --brand instead, which survives compilation untouched.

Can I import partials like _variables.sass?

No. The compiler runs in your browser with no access to your file system, so any @import pointing at another file fails with a file not found error. Paste the partial contents at the top of the editor above the code that references them.

How do I write a mixin in indented Sass?

Use =name to define and +name to call, with arguments in parentheses on both. The longer @mixin and @include forms also work in .sass files. Define the mixin before any line that calls it, since the compiler reads the file in order.

Does @use work here?

No. This page runs LibSass, which was retired before the Sass module system shipped. @use and @forward, plus namespaced functions like math.div and color.adjust, need Dart Sass installed locally. Legacy functions such as darken, lighten, and mix work fine here.

The output pane is empty but there is no error. Why?

Your source probably contains only variables, mixin definitions, or functions. None of those emit CSS on their own. Add a selector that uses them and output appears. The status bar reports this case separately from a compile failure.

Is the minified output safe to ship?

It is the compiler own compressed mode, so the CSS stays valid. It strips comments including loud blocks, which matters if your file carries a license header. Keep the header separately or use expanded output and minify in your build instead.

How large a file can I paste?

A few thousand lines compiles without trouble. Larger sheets freeze the tab briefly because the compile runs on the main thread. At that size a local Dart Sass build is quicker and gives you source maps as well.