Sass(サース、英: Syntactically Awesome Style Sheets)は、ハンプトン・キャトリンが設計しネイサン・バイゼンバウムが開発したスタイルシート言語である。
後にSassファイルに用いられる単純なスクリプト言語である SassScript 用の拡張が加えられた。

Sass は Cascading Style Sheets (CSS)で解釈される2種類の構文で構成されたスクリプト言語であり、SassScript はスクリプト言語自体を示す。
はじめにできた「インデント構文」では、Hamlと同様にコードブロックや改行コードを分離する際に字下げを活用している。単にSassと言ったらインデント構文のことを指す場合も多い。新しい構文である「SCSS」(Sassy CSS)は、CSSのようなブロックの書式を使用し、ブロック内の別々の行にブロックとセミコロンを示すため波括弧を用いている。

CSS3はグループルールを適用するセレクタ及び擬似セレクターの一群で構成されている。
SASSは伝統的なプログラミング言語、特にオブジェクト指向言語で利用可能ないくつかの仕組みで、CSS3にはないものを提供することでCSSを拡張している。
SassScript の解釈時には、Sass ファイルで定義された様々なセレクタとして、CSSルールのブロックが作成される。
Sass インタプリタが SassScript をCSSに変換する。`sass` か `scss` の保存時に Sass がこれらを監視し、CSS出力変換を行っている。
CSS用の単純な糖衣構文でもある。

公式に Ruby で実装されているオープンソースソフトウェアであるが、
PHPを含めた多言語の実装も存在しており、中には libSass と呼ばれるC++による高性能の実装や、JSass と呼ばれる Java による実装がある。また、RubyによるSassが低速で、C++によるSassが新しい機能が追加しにくくなってきたことから、Dartによるdart-sassという実装が生まれた。

インデント構文はメタ言語であり、SCSS はネストされたメタ言語であるように、プログラム意味論上では妥当なCSSは、妥当なSCSSである。Mozilla Firefox ウェブブラウザの拡張機能である Firebug との統合に対応している。

## 変数

定義する変数は「`$`」(半角ドル記号)で始まり、代入に半角のコロン「`:`」が用いられる。

数(単位を含む)、(引用符の有無にかかわらず)文字列、色(色名か指定記号)、ブーリアン型のデータ型に対応している。

SCSSとSassの比較と生成されるCSS

| Sass 構文 | SCSS 構文 | コンパイル結果 |
| --- | --- | --- |
| ``` $blue: #3bbfce $margin: 16px  .content-navigation   border-color: $blue   color: darken($blue, 10%)  .border   padding: $margin/2   margin:  $margin/2   border-color: $blue ``` | ``` $blue: #3bbfce; $margin: 16px;  .content-navigation {   border-color: $blue;   color: darken($blue, 10%); }  .border {   padding: $margin / 2;   margin: $margin / 2;   border-color: $blue; } ``` | ``` .content-navigation {   border-color: #3bbfce;   color: #2b9eab; }  .border {   padding: 8px;   margin: 8px;   border-color: #3bbfce; } ``` |

## ネスティング

CSSは論理的なネストに対応しているが、コードブロック自体はネストされていない。
Sass により、ネストされたコードは互いに挿入できる。

ネストしたSCSSと生成されるCSS

| SCSS 構文 | コンパイル結果 |
| --- | --- |
| ``` table.hl {   margin: 2em 0;   td.ln {     text-align: right;   } }  li {   font: {     family: serif;     weight: bold;     size: 1.3em;   } } ``` | ``` table.hl {   margin: 2em 0; } table.hl td.ln {   text-align: right; }  li {   font-family: serif;   font-weight: bold;   font-size: 1.3em; } ``` |

名前空間のネストや親の参照を含むより複雑な種類は、公式文書で説明されている。

## ミックスイン

CSSはミックスインに対応していないため、同じコードを別の位置に繰り返し記載する必要がある。
ミックスインは、任意の妥当な Sass コードを含むコード節を示し、実行されるたびに翻訳結果が呼び出し元の位置に挿入される。
これにより効率的なコーディングや記述の簡略化だけでなく、内容変更を容易にする。

ミックスインの例

| SCSS 構文 | コンパイル結果 |
| --- | --- |
| ``` @mixin table-base {   th {     text-align: center;     font-weight: bold;   }   td, th {padding: 2px} }  #data {   @include table-base; } ``` | ``` #data th {   text-align: center;   font-weight: bold; } #data td, #data th {   padding: 2px; } ``` |

### 反復処理

`@for`、`@each`、`@while`を用いてIDやClassに変数を適用できる。

反復処理の例

| Sass 構文 | コンパイル結果 |
| --- | --- |
| ``` $squareCount: 3 @for $i from 1 through $squareCount    #square-#{$i}     background-color: red    width: 50px * $i    height: 120px / $i ``` | ``` #square-1 {   background-color: red;   width: 50px;   height: 120px; }  #square-2 {   background-color: red;   width: 100px;   height: 60px; }  #square-3 {   background-color: red;   width: 150px;   height: 40px; } ``` |

### 引数

引数の例

| Sass 構文 | コンパイル結果 |
| --- | --- |
| ``` @mixin left($dist) {   float: left;   margin-left: $dist; }  #data {   @include left(10px); } ``` | ``` #data {   float: left;   margin-left: 10px; } ``` |

### 組み合わせ例

組み合わせ例

| SCSS 構文 | コンパイル結果 |
| --- | --- |
| ``` @mixin table-base {   th {     text-align: center;     font-weight: bold;   }   td, th {padding: 2px} }  @mixin left($dist) {   float: left;   margin-left: $dist; }  #data {   @include left(10px);   @include table-base; } ``` | ``` #data {   float: left;   margin-left: 10px; } #data th {   text-align: center;   font-weight: bold; } #data td, #data th {   padding: 2px; } ``` |

## セレクタの継承

セレクタの継承の例

| SCSS 構文 | コンパイル結果 |
| --- | --- |
| ``` .error {   border: 1px #f00;   background: #fdd; } .error.intrusion {   font-size: 1.3em;   font-weight: bold; }  .badError {   @extend .error;   border-width: 3px; } ``` | ``` .error, .badError {   border: 1px #f00;   background: #fdd; }  .error.intrusion, .badError.intrusion {   font-size: 1.3em;   font-weight: bold; }  .badError {   border-width: 3px; } ``` |