Compass V1.0 Cross-Browser Support Configuration の書式を確認する


先日、出力されたコードを確認していて気づきました。

リリースから日がたっていることもあり、既知のトピックかもしれませんが、日本語の情報が見当たらなかったのでシェアします。

識者の方がおられましたら対応策などフォローをお願い致します。

```
% compass --version
Compass 1.0.1 (Polaris)
```

> * [Compass Cross-Browser Support Configuration | Compass Documentation](http://compass-style.org/reference/compass/support/)
> * [Tuning Vendor Prefix Support | Compass Documentation](http://compass-style.org/help/documentation/tuning-vendor-prefixes/)


ポイントは3つ。

* `@import "compass";` の前に config を読み込む。
* `$browser-minimum-versions` の設定よりも、The browser usage threshold の値が優先される。
* 旧記法は機能しない。 ex.) `$legacy-support-for-*`

今までに作成した css や mixin が、意図したとおりの出力や動作をしていない可能性もあります。




## サンプルコード

設定値を変更しながら、結果を確認します。

```main.scss
$supported-browsers: ("chrome", "safari", "firefox", "ie");
$graceful-usage-threshold: 0.1;
$critical-usage-threshold: 0.01;
$browser-minimum-versions: ("firefox": "33", "ie": "9");

@import "compass";

$debug-browser-support: true;
@debug "$graceful-usage-threshold is:" $graceful-usage-threshold;
@debug "$critical-usage-threshold is:" $critical-usage-threshold;
@debug "$supported-browsers is:" $supported-browsers;
@debug "$browser-minimum-versions is:" $browser-minimum-versions;


.gradient {
  @include background-image(linear-gradient(#ffffff, #f5f5f5 30%, #f5f5f5));
}


.test {
  @if support-legacy-browser(ie, "7") {
    content: 'ie7';
  }
  @else {
    content: 'ie8 and higher';
  }
}
.clearfix { @include clearfix; }
.opacity { @include opacity(.5); }
```




## 実験1: Vendor Prefix への影響 

.gradient について、それぞれの設定で生成される CSS を確認します。

> * [Can I use... Support tables for HTML5, CSS3, etc](http://caniuse.com/#feat=css-gradients)


### 閾値にディフォルト値を設定する

`$graceful-usage-threshold` と `$critical-usage-threshold` にディフォルト値を代入しておきます。

```main.scss
$supported-browsers: ("chrome", "safari", "firefox", "ie");
$graceful-usage-threshold: 0.1;
$critical-usage-threshold: 0.01;
$browser-minimum-versions: ("firefox": "33", "ie": "9");
```

`$supported-browsers` の設定が効いており、android 用のコードは生成されません（以降、省略）。

一方、`$browser-minimum-versions` は効かず、-moz が生成されています。

```main.css
    :
  /* Content for android 2.1 - 3 omitted.
     Not allowed in the current scope: android is not listed as a supported browser. */
  /* Capability css-gradients is prefixed with -moz because 0.75106% of users need it which is more than the threshold of 0.1%. */
  /* Creating new -moz context. */
  background-image: -moz-linear-gradient(#ffffff, #f5f5f5 30%, #f5f5f5);
    :
```


### 適切な閾値を設定する

`$graceful-usage-threshold` に 1% を設定します。

```main.scss
$graceful-usage-threshold: 1;
```

-moz は生成されません。

```main.css
  /* Capability css-gradients is not prefixed with -moz because 0.75106% of users are affected which is less than the threshold of 1. */
```


### 適切な閾値とブラウザバージョンを設定する

firefox だけ -moz が出力される version 15 を指定します。

```main.scss
$graceful-usage-threshold: 1;
$browser-minimum-versions: ("firefox": "15", "ie": "9");
```

-moz が生成されました。

```main.css
  /* Capability css-gradients is prefixed with -moz because firefox 15 is required. */
  /* Creating new -moz context. */
  background-image: -moz-linear-gradient(#ffffff, #f5f5f5 30%, #f5f5f5);
```

これだけであれば、Autoprefixer を後からかけることで問題ないかもしれません。




## 実験2: function, mixin への影響

.test, .clearfix, .opacity について、それぞれの設定で生成される CSS を確認します。

> * [Can I use... Support tables for HTML5, CSS3, etc](http://caniuse.com/#feat=css-opacity)


### 閾値にディフォルト値を設定する

おなじく `$graceful-usage-threshold` と `$critical-usage-threshold` にディフォルト値を代入しておきます。

```main.scss
$supported-browsers: ("chrome", "safari", "firefox", "ie");
$graceful-usage-threshold: 0.1;
$critical-usage-threshold: 0.01;
$browser-minimum-versions: ("firefox": "33", "ie": "9");
```

`$browser-minimum-versions` は効かず、IE9+ では不要なコードが生成されています。

また、`@if support-legacy-browser` の分岐も意図しないものになります。

`$debug-browser-support` を有効化していますが、clearfix にはコメントが付かないことが分かります。

```main.css
/* line 20, ../sass/main.scss */
.test {
  content: 'ie7';
}

/* line 28, ../sass/main.scss */
.clearfix {
  overflow: hidden;
  *zoom: 1;
}

/* line 29, ../sass/main.scss */
.opacity {
  /* Content for ie 8.
  Min version: 9.
  User threshold to keep: 0.1%. If ie 8 are omitted: 4.46163%. */
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
  opacity: 0.5;
}
```


### 適切な閾値を設定する

`$graceful-usage-threshold` に 5% を設定します。

```main.scss
$graceful-usage-threshold: 5;
```

.opacity は意図通りのコードとなっていますが、その他は変わりません。
つまり、`$browser-minimum-versions` の IE9+ が認識されているわけではありません。

```main.css
/* line 20, ../sass/main.scss */
.test {
  content: 'ie7';
}

/* line 28, ../sass/main.scss */
.clearfix {
  overflow: hidden;
  *zoom: 1;
}

/* line 29, ../sass/main.scss */
.opacity {
  /* Content for ie 8 omitted.
     Minimum support is 9. */
  opacity: 0.5;
}
```


### 閾値を 100% に設定する

話を分かりやすくするために、閾値を 100% に設定します。
さらに `$browser-minimum-versions` をコメントアウトします。

```main.scss
$graceful-usage-threshold: 100;
$critical-usage-threshold: 100;
// $browser-minimum-versions: ("firefox": "33", "ie": "9");
```

すると IE9+ なコードが生成されました。

```main.css
/* line 20, ../sass/main.scss */
.test {
  content: 'ie8 and higher';
}

/* line 28, ../sass/main.scss */
.clearfix {
  overflow: hidden;
}

/* line 29, ../sass/main.scss */
.opacity {
  /* Content for ie 8 omitted.
     Minimum support is . */
  opacity: 0.5;
}
```

`$browser-minimum-versions` のコメントを外し有効化しても、おなじ結果となります。


### 閾値を 100% に設定し、ブラウザミニマムバージョンを調整する

`$browser-minimum-versions` の値を、IE8, IE7 と変更してみます。

```main.scss
$graceful-usage-threshold: 100;
$critical-usage-threshold: 100;
$browser-minimum-versions: ("firefox": "33", "ie": "8");
```

IE8 の場合、.opacity が変わったことが分かります。

```main.css
/* line 20, ../sass/main.scss */
.test {
  content: 'ie8 and higher';
}

/* line 28, ../sass/main.scss */
.clearfix {
  overflow: hidden;
}

/* line 29, ../sass/main.scss */
.opacity {
  /* Content for ie 8.
  Min version: 8.
  User threshold to keep: 100%. If ie 8 are omitted: 4.46163%. */
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
  opacity: 0.5;
}
```

IE7 の場合、すべて変更されたことが分かります。

```
/* line 20, ../sass/main.scss */
.test {
  content: 'ie7';
}

/* line 28, ../sass/main.scss */
.clearfix {
  overflow: hidden;
  *zoom: 1;
}

/* line 29, ../sass/main.scss */
.opacity {
  /* Content for ie 8.
  Min version: 7.
  User threshold to keep: 100%. If ie 8 are omitted: 4.46163%. */
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
  opacity: 0.5;
}
```

つまり

* `$*-usage-threshold` が第一条件
* `$browser-minimum-versions` は、これに追加される or 条件

と扱いが違うようです。




## どのように対応すればよいのか

Compass の振る舞いから、caniuse のデータに基づいて生成するから、制作者側で対応ブラウザを適当に絞るのはやめようぜ、という設計方針なのかなと推測しています。

* 選択1: このままつかう


適切な閾値とブラウザ設定を行う方法もあり得そうで、閾値の調べ方も紹介されていました。

> * [This is how you can ask compass what the usage threshold cutoff for each browser version is.](https://gist.github.com/chriseppstein/db821931dc50b624c84c)
> * [affected_browsers.scss](https://gist.github.com/chriseppstein/66b89cac2c6e08fc8ce4)

* 選択2: 適切な閾値とブラウザ設定を行う


もう一つは、`$*-usage-threshold` を 100% とし、必要な `$browser-minimum-versions` を全て設定する方法。
これで全てコントロールできるのかも知れません。

* 選択3: `$*-usage-threshold` を 100% とし、必要な `$browser-minimum-versions` を全て設定する


個人的には、あまり込み入ったことをしていないので、「選択1: このままつかう」になるような気がしています。
いまのところ。。。

プロの方のご意見や間違いがありましたら、是非教えてください。
<(_ _)>




## 今後は？

今後のバージョンアップで、`$browser-minimum-versions` の設定が優先されるように変わるのかも（英語苦手です）。

> * [In support-legacy-browser(), default threshold should not override browser minimum versions by JohnAlbin · Pull Request #1524 · Compass/compass](https://github.com/Compass/compass/pull/1524#issuecomment-51499351)
> * [A way to exclude old browsers · Issue #1762 · Compass/compass](https://github.com/Compass/compass/issues/1762)




## 参考ソース

その他、参考にさせて頂いたソース。

> * [Compass Cross-Browser Support Configuration not working · Issue #1885 · Compass/compass](https://github.com/Compass/compass/issues/1885)
> * [sass - Configure compass browser support (Compass 1.x syntax) - Stack Overflow](http://stackoverflow.com/questions/25863370/configure-compass-browser-support-compass-1-x-syntax)
> * [sass - Examples of minimum browser support for Compass 1.x - Stack Overflow](https://stackoverflow.com/questions/24745994/examples-of-minimum-browser-support-for-compass-1-x/26145361#26145361)