box-sizingを例で見てみる。
http://compass-style.org/reference/compass/css3/box_sizing/
リンク先のview sorceをクリックすると、内容を見ることができる。
@mixin box-sizing($bs) {
$bs: unquote($bs);
@include experimental(box-sizing, $bs, -moz, -webkit, not -o, not -ms, not -khtml, official); }
unquote()
で引数の値からクォートを外したあと、プロパティ名、プロパティの値(=引数の値)、ベンダープリフィックスの有無といった内容を、box-sizing
からexperimental
というミックスインに渡している。
http://compass-style.org/reference/compass/css3/shared/
@mixin experimental($property, $value, $moz: $experimental-support-for-mozilla, $webkit: $experimental-support-for-webkit, $o: $experimental-support-for-opera, $ms: $experimental-support-for-microsoft, $khtml: $experimental-support-for-khtml, $official: true) {
@if $webkit and $experimental-support-for-webkit {
-webkit-#{$property}: $value; }
@if $khtml and $experimental-support-for-khtml {
-khtml-#{$property}: $value; }
@if $moz and $experimental-support-for-mozilla {
-moz-#{$property}: $value; }
@if $ms and $experimental-support-for-microsoft {
-ms-#{$property}: $value; }
@if $o and $experimental-support-for-opera {
-o-#{$property}: $value; }
@if $official {
#{$property}: $value; } }
ズラズラと読みづらい。
まずは引数部分を見てみる。
↓改行して見やすくしてみた。
experimental(
$property,
$value,
$moz: $experimental-support-for-mozilla,
省略
) {
experimental
の3番目の引数である$moz
には、初期値として$experimental-support-for-mozilla
が設定されている。
3番目の引数か、$moz:**
が存在しない場合はこの変数の値が有効になるが、
box-sizing
のミックスインからは、3番目の引数として-moz
が渡されている。
@include experimental(
box-sizing,
$bs,
-moz, //← $moz
-webkit,
not -o,
not -ms,
not -khtml,
official);
experimental
に渡された$moz:-moz;
は、プロパティの表示/非表示を指定している条件文で使われる。
@if $moz and $experimental-support-for-mozilla {
-moz-#{$property}: $value; }
$moz
と、$experimental-support-for-mozilla
の両方が真の場合のみ、ベンダープリフィックス付きの値をCSSで出力されるようになっている。
前述のとおり、$moz
にはbox-sizing
から渡された-moz
が入っている。
@ifの条件式に文字列が指定されていると真となるので、$moz
は真。
次に$experimental-support-for-mozilla
に定義された値を確認する。
compassで使われているサポート系の変数のデフォルト値は以下から確認できる。
http://compass-style.org/help/tutorials/exclude_vendor_prefixes/
実際のソースでは以下のようになっている。
$experimental-support-for-mozilla
を見てみると
$experimental-support-for-mozilla : true !default;
true
が宣言されている。
以上により、@ifの条件式である$moz
と$experimental-support-for-mozilla
はどちらも真、
条件式全体も真であると判断され、
-moz-#{$property}: $value;
がCSSに出力される。
以上が、includeからベンダープレフィクス出力までの挙動である。
以下は、box-sizing
の引数。
@include experimental(
box-sizing,
$bs,
-moz,
-webkit,
not -o, // ← $o
not -ms,
not -khtml,
official);
このうちの5番目の引数($oに渡す引数)のように、experimental
にnot **
が渡されるケースがある。
引数はそのまま次条件文に入るため、experimental
では次のようになる。
@if $o and $experimental-support-for-opera {
-o-#{$property}: $value; }
↓
@if not -o and $experimental-support-for-opera {
-o-#{$property}: $value; }
@if $o
が@if not -o
となり、not
によって文字列-o
の真偽値が反転して偽となる。
結果条件式全体も偽となって、プロパティは出力されなくなる。
このケースはcompassのcss3関連のミックスインの定義によるため、ユーザ側が意識することはない。
どうしても変えたい場合は、compass内のmixinファイルを書き換えるか、
同じ内容のmixinを、compassより"あと"に再定義してcompassのmixinを上書きする必要がある。
プロパティが出力されないもう一つのケースは、
$experimental-support
変数が偽の場合。
$experimental-support
変数は次のように@import宣言前に宣言しておくことで、デフォルト値を上書きできる。
$experimental-support-for-opera:false;
@import "compass";
変数がflaseとなることで、
@if $o and $experimental-support-for-opera {
-o-#{$property}: $value; }
このif文の条件式は偽となって、プロパティは出力されなくなる。
こちらは、ユーザが簡単に制御することができる方法だが、
全プロパティで出力されなくなる。
デフォルトの出力はcommpassのcss3系のミックスインの初期値によって決められている。
例えばbackground_sizeは、msは出力しない設定になっている。
http://compass-style.org/reference/compass/css3/background_size/
デフォルトの出力が知りたい場合はjsdoitなどで入力してみるとよい
プロジェクト全体で特定のベンダープリフィックスを非表示にしたい場合は
$experimental-support-for-opera:false;
@import "compass";
このように@import前に$experimental-support
変数を上書きする。
この場合、プロジェクト全体に一律で特定のベンダープリフィックスが非表示になる。
$experimental-support
の初期値はこちら
https://github.com/chriseppstein/compass/blob/stable/frameworks/compass/stylesheets/compass/_support.scss
border-radius
やbox-shadow
といった、ブラウザサポートの範囲によってベンダープリフィックスが不要になるプロパティについて、
個別に制御したい場合は
- プロパティごとのミックスインは使わず、
experimental
ミックスインを使って、引数で出力するベンダープリフィックスを制御する - 同名のミックスインを作り、compassよりもあとで読み込んで優先的に実行させる
- compassのソース自体を書き換える
のいずれかの対応となる。
experimental
を使う場合は次のようにな指定となる。
@include experimental(
box-sizing, //プロパティ名
border-box, //値
-moz, //-mozの出力
-webkit, //-webkitの出力
not -o, //-oの出力
not -ms, //-msの出力
not -khtml, //-khtmlの出力(デフォルトでは`$experimental-support-for-khtml`がflaseなので出力されない)
official //ベンダープリフィックス無しの出力
);
↓
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
出力させたくないベンダープリフィックスにnotをつければ出力しなくなる。
プロパティではなく、値にベンダープリフィックスを当てたい場合はexperimental-value
を使う。
@include experimental-value(
display,
flex,
-moz,
-webkit,
not -o,
not -ms,
not -khtml,
official
);
↓
display: -webkit-flex;
display: -moz-flex;
display: flex;
ただし、compassのcss3系のミックスインは、単純にベンダープリフィックスをつけるだけではなく、 ブラウザのバクfixも行なっている場合がある。
例えばborder_radius
の説明を見てみると、
http://compass-style.org/reference/compass/css3/border_radius/
Note: webkit does not support shorthand syntax for several corners at once. So in the case where you pass several values only the first will be passed to webkit.
という注意書きがある。
要は古いsafariが/で区切ったショートハンドに対応していないため、
@include border-radius(2px 5px,3px 6px);
↓
-webkit-border-radius: 2px 3px;
-moz-border-radius: 2px 5px / 3px 6px;
border-radius: 2px 5px / 3px 6px;
というように、-webkitの値のみcompass側で古いsafariでも表示できる形に変換している。 こういった処理は、experimentalを使うと実行されなくなる。 (experimentalは、ベンダープリフィックスをつけるだけのmixinのため)
※これは新しいsafariではすでに修正されているバグのfixのため、fix自体が現状ではほとんど不要だと思われる。
しかしこのfixのみを省く方法は用意されていない。
このような、css3系のmixinに組み込まれたfix処理を実行したくない場合は、
ベンダープリフィックスの制御と同様に、experimentalを使うか、同名のmixinで上書きくかする必要がある。
同名のmixinが複数存在した場合、あと勝ちになることを利用して、
@import compass
の後で同名のミックスインを作成して読み込ませることで制御する。
具体的には以下のようになる。
@import "compass";
@mixin border-radius($radius: $default-border-radius) {
$radius: unquote($radius);
@include experimental(border-radius, $radius,not -moz, not -webkit, not -o, not -ms, not -khtml);
}
こうすることで、ベンダープリフィックスの制御や、不要なfixを省くことができる。
macだと、
/Library/Ruby/Gems/1.8/gems/compass-0.12.2/frameworks/compass/stylesheets/compass/css3
あたりに入っているsassを書き換えれば多分できると思われる。自己責任でお願いします。windowsの場所は知りません。