Awesome Syntax Changes in Sass 3

Posted March 31, 2010

Update: Sass 3 Beta 2 introduces a sass-convert --recursive flag for recursively converting stylesheets. This post has been updated to use that flag.

Update: Sass 3.1 no longer supports converting from Sass 2 syntax to Sass 3 syntax. If you still need to do this, install version 3 of the haml gem.

In addition to a brand new syntax, Sass 3 introduces two major changes and one minor change to the existing syntax. I think pretty much everyone will agree that they’re good changes, though. In addition, to ease the upgrade path, Sass 3 also introduces a new, turbocharged version of css2sass known as sass-convert. sass-convert can convert files between CSS, Sass, and SCSS, as well as convert files from the old Sass 2 syntax to the new Sass 3 syntax:

# Convert a single file to the Sass 3 syntax
$ sass-convert --from sass2 --in-place style.sass

# Convert all files to the Sass 3 syntax
$ sass-convert --from sass2 --to sass --in-place --recursive .

$var, Not !var

Sass 3 no longer uses the ! prefix for variables. It still works, for backwards-compatibility, but it prints a warning and will be removed in Sass 3.2. Instead, the more aesthetically appealing $ prefix is used.

The reason for this decision is simply that no one really liked !. It was originally chosen to parallel the !important syntax, but since !important isn’t really a variable, that didn’t make much sense.

$ was chosen primarily because it’s not used elsewhere in CSS, and so doesn’t conflict, syntactically or cognitively. It’s also used for variables in other languages, including occasionally Javascript, which many designers have at least passing familiarity with.

No More =

The = character is no longer required for using SassScript. Ever. Anywhere. : should now always be used instead for properties, variables, and even default arguments to mixins. Here’s an example:

$height: 34px

h1
  height: $height
  line-height: $height/2 + 2px

This was one of the most consistent complaints I’ve heard with Sass, including from myself. Many was the time I would ponder why my Sass didn’t work, only to find that I forgot to change a colon to an equals. May this never plague anyone again.

SassScript Changes

The SassScript syntax has also been slightly modified so that it will properly parse all valid CSS properties. SassScript used with the deprecated = character will work as it did in 2.2 for backwards-compatibility, but this prints a warning and will be removed in 3.2.

String Changes

In Sass 2, strings with quotes were rendered without quotes and strings without quotes were deprecated1. In Sass 3, strings with quotes are rendered with quotes, and strings without quotes are rendered without quotes. In addition, there are now quote() and unquote() functions to convert a string to one form or the other.

There is still one place where strings with quotes render without them: when using #{} to insert a string in a selector or property, that string is always rendered without quotes.

Division and /

Two numbers separated by a / character are allowed as property syntax in CSS, e.g. for the font property. SassScript also uses / for division, however, which means it must decide what to do when it encounters numbers separated by /.

For CSS compatibility, SassScript does not perform division by default. However, division will be done in almost all cases where division is intended. In particular, SassScript will perform division in the following three situations:

  1. If the value, or any part of it, is stored in a variable.
  2. If the value is surrounded by parentheses.
  3. If the value is used as part of another arithmetic expression.

Hyphens in Names

The minor change is that all identifier names in Sass, including variables, can now use the full range of CSS identifiers, including those with hyphens. Honestly, I’m not sure why I hadn’t added hyphen support before now.

Moreover, to aid the transition from underscored names to hyphenated ones, either one may be used to refer to the other. For example, the variables $main_width and $main-width are considered to be the same.

1 We did this in anticipation of getting rid of the variable prefix entirely. However, now that all property values are SassScript, we need that prefix to distinguish variables from CSS values like bold and solid.

Anonymous said March 31, 2010:

Less let’s me have mixins like this one:

.transform-rotate(@degrees: -5deg) {
  transform: rotate(@degrees);
  -webkit-transform: rotate(@degrees);
  -moz-transform: rotate(@degrees);
}

Does Sass 3 support something equivalent to this? I.e., variables/arguments inside regular CSS functions?

Nathan said March 31, 2010:

Anonymous: Absolutely. Here’s an example:

@mixin transform-rotate($degrees: -5deg) {
  transform: rotate($degrees);
  -webkit-transform: rotate($degrees);
  -moz-transform: rotate($degrees);
}
Andy said March 31, 2010:

Nathan, glad to see that! It’s back to Sass then! :)

(That first post was mine.)

Caleb said April 01, 2010:

“only to find that I forgot to change a semicolon to an equals” <- I think you mean changing a colon to an equal sign.

SCSS++ said April 01, 2010:

Is there a specific reason numbers are not allowed as the first character in a variable? I’ve been digging around the source and could attempt to fix it if its not intentional behavior.

For example: $2columns: 200px;

Returns: Syntax error: Invalid CSS after ”$”: expected identifier, was “2columns: 200px;” on line 1 of test.scss

Nathan said April 01, 2010:

Caleb: Yes, you’re right. I’ll fix that.

SCSS++: Variable names are CSS identifiers, as defined by the CSS 3 spec. These identifiers cannot start with numbers, and so neither can Sass variables. I think this consistency is important.

Robby Colvin said April 04, 2010:

The line to convert all files to the SASS 3 syntax should look like this:

$ find . -name '*.sass' -exec sass-convert --from sass2 --in-place {} \;
Nathan said April 07, 2010:

Robby: I’ve changed it. My find defaults to ., but I guess not all of them do.

David J. said May 19, 2010:

I’m a little concerned … all of your documentation now uses SCSS style instead of Sass. I realize you’ve already said Sass syntax is here to stay, but where is someone supposed to find out about it? Specifically the new mixin syntax — how do I do that in Sass?

Nathan said May 20, 2010:

There’s a separate page of documentation detailing the difference between the indented syntax and SCSS. This is linked from the Sass reference, in the section on syntax.

I’m not exactly sure what you mean by the new mixin syntax… do you mean using `@mixin` and `@include`? Those work the same in Sass as they do in SCSS.

KandadaBoggu said June 15, 2011:

Nathan: The `sass2` option no longer works in latest version of `sass-convert` . Can you update your blog to add the latest instructions for conversion as per Chris’s answer here.

Breaking your tool is dumb said November 11, 2011:

Fix the sass-convert tool. It was really dumb to just break it for no reason.

Make your comments snazzy with Textile!