Unformed Building

CSSを拡張して記述できるPHPベースのプリプロセッサPCSSとCSS Crush

公開:
更新:

パーマリンク

CSSを拡張して記述できるものと言えば、SassとLESSが有名ですね。
これらはHTML/CSSフレームワークなどでも使われていたり、日本語での解説も多くあります。
ですが、今回はそのどちらでもない、PHPベースのプリプロセッサである「PCSS」と「CSS Crush」の簡単な説明をしてみたいと思います。

誤解のないように言っておきますが、これは「Rubyとか入れなくてもいいしこっち使おうぜ」という内容の記事ではありません。
こういうものもある、という程度に見ておくといいかもしれません。

また、この記事内の解説は公式ドキュメントを簡単にまとめたものです。
詳しく見たい方は公式サイトをご覧ください。

PCSS

PCSS – CSS Server-side Preprocessor

「ショートカット志向サーバーサイドCSS3プリプロセッサ」とタイトルに書かれています。
PCSSではどんなことができるのか。その特徴を見てみます。

PCSSが動作するにはPHP5が必要となります。

  • 事前定義されたCSSの定数とPCSSの関数によって、より直感的にCSSが書けるようになり、コードがスリム化され読みやすくなります。
  • classの入れ子ができます。
  • あらゆる種類のデータを格納できる変数があります。
  • デフォルトの単位とデフォルトの画像ディレクトリを事前定義された関数にセットすることができます。
  • サーバーサイドでブラウザを検出することで@font-faceのコードをスリム化して出力するショートカットがあります。
  • 面倒なコマンドを避けるためにベンダープレフィックスをサーバー側で検出して出力するためのショートカットがあります(-webkit-, -moz-, など)。
  • CSSは圧縮されて出力されます。

導入

簡単な導入方法は、pcss.php をウェブサイトのディレクトリに置いて、普通のCSSファイルと同じように<link>@importで読み込むことです。

<link rel="stylesheet" type="text/css" href="pcss.php?css=file.css" />

または

<style type="text/css">@import url(pcss.php?css=file.css);</style>

これは最も簡単な導入方法ですが、PCSSを利用した他の方法もあります。
次に説明するのは複数のCSSファイル(実際にはPCSSファイル)を1つのCSSファイルに出力するのに向いている方法です。

<?php
  include "pcss.php";
  print new PCSS("file1.pcss");
  print new PCSS("file2.pcss");
  print new PCSS("file3.pcss");
?>

Apache のmod_rewriteが有効な環境で.htaccessに下記を記述することにより、よりフレンドリーなURLにすることができます。

RewriteEngine on
RewriteRule ^([a-zA-Z0-9_-]+).p.css$ pcss.php?css=$1

この場合、file.p.csspcss.php?css=file.pcssと同様のファイルを呼び出すことができます。また、これはカスタマイズ可能です。

変数

&[variable_name] = [value];

文字列の先頭に&をつけることで変数として指定できます。
値は=(等号)で代入します。
末尾の;(セミコロン)は任意です。

以下はその例です。

&mycolour = #fff;
&floatedbox = display:block; float:left;

デフォルト値の定義

デフォルトの単位と画像ディレクトリを定義します。デフォルト画像ディレクトリはBGIMGPCSS関数で使用されます。
以下のように指定します。

unit [unit]
imgdir [dirname]

指定例は次の通りです。

/* example 1 */
unit em
imgdir images

/* example 2 */
unit %
imgdir ../

これらの指定が見つからない場合、imgdirは空、unitにはpxが指定されます。ディレクトリ名の最後にスラッシュは必要ありません。

@font-faceショートカット

@font-faceを簡単に指定することができます。

fontface [fontname] [fontfiles]

以下はその例です。

fontface MyFont dir/myfont-file

これは次のように出力されます(フォーマットはされません)。

@font-face {
  font-family: 'MyFont';
  src        : url('dir/myfont-file.eot')  format('eot'),
               url('dir/myfont-file.woff') format('woff'),
               url('dir/myfont-file.ttf')  format('truetype');
}

classの入れ子

classは入れ子で指定することができます。

.class{ BLOCK;
  .subclass{ HIDE; }
}

これは次のように出力されます。

.class {
  display: block;
}
.class .subclass {
  display: none;
}

多くのclassを入れ子にすればするほどCSSは大きくなるので気をつけてください。

サーバーサイドコメント

PCSSの中では、スラッシュを2回続けて書くことでPHPのようにコメントを書くことができます。

// ここはコメントです

このコメントはCSSに出力されません。

定数

事前定義された定数により、一部のセレクタや指定を短く書くことができます。

.class{
  HIDE;
}

これは以下のように出力されます。

.class{
  display: none;
}

セレクタの定数は次のようなものです。

.class FILE{
  HIDE;
}

これは以下のように出力されます。

.class input[type=file]{
  display: none;
}

他にも様々な定数があります。詳しくは「Constants reference」を参照してください。
また、これらの定数は自分で作ることもできます。

関数

関数はCSSのように記述でき、CSSより短く、ブラウザごとに最適化されたCSSを書き出すことができます。

.class{
  FSIZE:14;
}

これは以下のように出力されます。

.class{
  font-size: 14px;
}

FSIZEfont-sizeの短縮形で、デフォルトの単位がpx(または指定されていない)だとこうなります。

次の例を見てましょう。

.class{
  BOUNDS:5 10,0 0 10;
}

これは以下のようになります(デフォルト単位がpxの場合)。

.class{
  padding: 5px 10px; margin: 0 0 10px;
}

BOUNDS関数はmarginpaddingを一度に指定できます。

次は背景画像です。

.class{
  BGIMG:someimage.png;
}

結果は次の通り。

.class{
  background-image: url(images/someimage.png);
}

BGIMGbackground-imageの短縮形です。imgdirを定義してあれば、このように更に短く書くことができます。

では最後の例です。

.class{
  GRADIENT:#fff #000;
}

これはFirefoxでページを見た場合、次のように出力されます。

.class{
  background-image: -moz-linear-gradient(top, #fff, #000);
  background-image: linear-gradient(top, #fff, #000);
}

Ineternet Explorer 9以下で見た場合は次のようになります。

.class{
  filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#fff', EndColorStr='#000');
}

GRADIENTbackground-image: linear-gradiennt()の短縮形です。
また、この指定はサーバーサイドでブラウザを判別し、ブラウザごとに最適化されたコードを出力します。ROTATE関数も同じように働きます。

他の関数については「Functions reference」を参照してください。

PCSSのサイトで使われているPCSSのコードはhttp://pcss.wiq.com.br/pcss.pcssで見ることができます。
出力されるのはhttp://pcss.wiq.com.br/pcss.p.cssです。

ここまで PCSSの簡単な解説をしてきました。
次はCSS Crushをやっていきます。
感想などは最後に。

CSS Crush

CSS Crush ― An extensible PHP based CSS preprocessor

CSS Crush(作者のブログ記事)

「拡張性のあるPHPベースのCSSプリプロセッサ」とのことです。
それでは機能などを見ていきたいと思います。

導入

スクリプトをページに組み込み、CssCrush::fileメソッドに処理したいCSSファイルへのパスを指定します。

<?php
  require_once 'CssCrush.php';

  // この場合、生成または更新されるファイルパスは /css/screen.crush.css となります
  $compiled_file = CssCrush::file( '/css/screen.css' );
?>

<link rel="stylesheet" type="text/css" href="<?php echo $compiled_file; ?>" />

また、カスタムオプションを配列として渡すことができます。

<?php
  require_once 'CssCrush.php';

  $compiled_file = CssCrush::file( '/css/screen.css', array(
    'debug'       => true,  // ミニファイするかどうか(デフォルトはfalse)
    'boilerplate' => false, // ボイラープレートを出力するかどうか(デフォルトはtrue)
    'versioning'  => false, // 出力されるファイル名にタイムスタンプのクエリ文字列をつけるかどうか(デフォルトはtrue)
));
?>

ボイラープレートは、生成されるファイルの先頭にある次のような文です。

/*
 * CSS Crush(ed) on (時刻)
 * http://github.com/peteboere/css-crush
 */

この内容はCssCrush.boilerplateというファイルに書かれています。

ダイレクト@import

@importで呼び出されるファイルは、出力されるファイルに直接書き込まれます。これによりHTTPリクエストを減らすことができます。
また、@importにメディアの指定がある場合は、@mediaブロックで囲んで出力されます。

/* コンパイル前 */
@import "print.css" print;
@import url( "small-screen.css" ) screen and ( max-width: 500px );

/* コンパイル後 */
@media print {
    /* print.cssの中身がここに書き込まれます */
}
@media screen and (max-width: 500px) {
    /* 小さいスクリーン向けのCSSファイルの中身 */
}

エイリアス

エイリアスにより、プロパティのベンダープレフィックスを自動でつけることができます。エイリアスはメインのスクリプトと同じディレクトリのファイルに格納されています。CssCrush.aliasesというファイルですね。

エイリアスは編集可能です。たとえば、border-radiusのエイリアスは次のようになっています。

border-radius[] = -webkit-border-radius
border-radius[] = -moz-border-radius

CSS Crushがファイルをコンパイルするときにエイリアスはロードされ、一致する全ての指定に適用されます。

/* コンパイル前 */
p { border-radius: 10px; }

/* コンパイル後 */
p {
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    border-radius: 10px;
}

エイリアスはプロパティ以外に、関数にも使えます。

/* コンパイル前 */
div { background: #fff linear-gradient( left, red, white ) no-repeat; }

/* コンパイル後 */
div {
    background: #fff -webkit-linear-gradient( left, red, white ) no-repeat;
    background: #fff -moz-linear-gradient( left, red, white ) no-repeat;
    background: #fff -ms-linear-gradient( left, red, white ) no-repeat;
    background: #fff -o-linear-gradient( left, red, white ) no-repeat;
    background: #fff linear-gradient( left, red, white ) no-repeat;
}

@ルールにも可能です。

/* コンパイル前 */
@keyframes myanim {
    0%   { left: 0; }
    100% { left: 100px; }
}

/* コンパイル後 */
@-moz-keyframes myanim {
    0%   { left: 0; }
    100% { left: 100px; }
}
@-webkit-keyframes myanim {
    0%   { left: 0; }
    100% { left: 100px; }
}
@keyframes myanim {
    0%   { left: 0; }
    100% { left: 100px; }
}

マクロ

エイリアスが十分でない場合、PHPで書かれたマクロを定義することができます。
マクロの指定はCssCrush.macros.phpの中にあります。

/* コンパイル前 */
p {
    filter: blur( pixelradius=2 ),
            dropshadow( color=#000, offY=1px, offX=2px );
}

/* コンパイル後 */
p {
    filter: progid:DXImageTransform.Microsoft.Blur(
            pixelradius=2 ),
        progid:DXImageTransform.Microsoft.DropShadow(
            color=#000, offY=1px, offX=2px );
    -ms-filter: "progid:DXImageTransform.Microsoft.Blur(
            pixelradius=2 ),
        progid:DXImageTransform.Microsoft.DropShadow(
            color=#000, offY=1px, offX=2px )";
    zoom: 1;
}

ファイルの中を見てみたところ、2011年9月2日のバージョンには上記のfilter以外にも以下のようなマクロが指定されていました。

IE 7以下のdisplay:inline-block対策

/* コンパイル前 */
display: inline-block;

/* コンパイル後 */
display: inline-block;
*display: inline;
*zoom: 1;

IE6のmin-height

/* コンパイル前 */
min-height: 100px;

/* コンパイル後 */
min-height: 100px;
_height: 100px;

IE7以下のclip()対策

/* コンパイル前 */
clip: rect(1px,1px,1px,1px);

/* コンパイル後 */
clip: rect(1px,1px,1px,1px);
*clip: rect(1px 1px 1px 1px);

rgba()のフォールバック

/* コンパイル前 */
background: rgba(0,0,0,.5);

/* コンパイル後 */
background: rgb(0,0,0);
background: rgba(0,0,0,.5);

要らないものはコメントアウトしたりして使うように、だそうです。

関数

CSS Crushにはシンプルな数学関数があります。

math
四則演算ができます。使用できる演算子は+ – / * ()です。
数値以外の文字は無視されます。
percent
第1引数を第2引数で割ったものを返します。
round
mathの結果を四捨五入します。
floor
mathの結果を切り捨てします。
ceil
mathの結果を切り上げします。

()のように関数名を省略して書いた場合はmathとして扱われます。

/* コンパイル前 */
.column-1 {
    width: percent( 200, 960 );
    font-size: ( 12 / 16 )em;
}

/* コンパイル後 */
.column-1 {
    width: 0.208333333%;
    font-size: 0.75em;
}

また、data-uri関数を使うことで、相対パスで指定された画像やウェブフォントを自動的にData URIに変換することができます。

/* コンパイル前 */
ul li {
    background-image: data-uri(../my-bg.png);
}

/* コンパイル後 */
ul li {
    background-image: url(data:image/png;base64,R0lGODlhAQABAIA...);
}

変数

変数は、@ルールの文法と同じように指定します。また、CSSの指定内ではvar関数で変数を使います。

/* 変数の指定 */
@variables {
    helvetica: "Helvetica Neue", Helvetica, Arial, sans-serif;
    brand-blue: #C1D9F5;
}

/* 変数を使う */
ul, p {
    font-family: var( helvetica );
    background: var( brand-blue ) url( tile.png ) repeat-x;
}

セレクタのグルーピング

:any擬似クラスをサポートしています。これはベンダープレフィックス付きではありますが、最新のMozillaWebKitではサポートされています。
ちなみに、Selectors Level 4の中には:matchesがあります。

/* コンパイル前 */
:any( .sidebar, .block ) a:any( :hover, :focus ) {
    color: red;
}

/* コンパイル後 */
.block a:hover,
.block a:focus,
.sidebar a:hover,
.sidebar a:focus {
    color: red;
}

ミニファイとキャッシュ

デフォルトではCSS Crushが出力するCSSはミニファイ(圧縮)されています。これはオプションでデバッグモードにすることで無効にできます。

/* コンパイル前 */
body {
    padding: 0 0 0 0;
    margin: 20px auto 0px;
    background-color: #ffffff;
}

/* コンパイル後 */
body{padding:0;margin:20px auto 0;background-color:#fff}

ミニファイ時には以下のような変更が行われます。

  • margin: 0px;のような指定をmargin:0;
  • padding: 0 0 0 0;のような指定をpadding:0;
  • 不要な空白を削除
  • 最後の指定のセミコロンを削除
  • 空の指定の削除

@importされるファイルも含め、全てのファイルは変更された日時のタイムスタンプが保存され、チェックされます。いずれかのファイルに変更があった場合は、新たにコンパイルされます。何も変更がなかった場合は、キャッシュされたファイルが返されます。

CSS Crushのサイトで使われているCSS Crushファイルはhttp://the-echoplex.net/csscrush/css/global.cssで見ることができます。
出力されるのはhttp://the-echoplex.net/csscrush/css/global.crush.cssです。

CSS Crushの紹介は以上です。

個人的な感想

この2つのうちどちらを使いたいか、という質問があったらCSS Crushと答えると思います。
理由は簡単で、あまりトリッキーなことをしていないので、新しく覚えることが少ないからです。
セレクタのネストもあったら嬉しかったんですが……。

PCSSは書く量はかなり減ると思うんですが、それをやろうとすると大文字で書かないといけないのが多かったり、新しく覚えるものが多いのが大変そうです。
あと、ユーザーエージェントからブラウザを判別して出力するコードを変更するというのがちょっと……。

仮にどちらかを使うとしても、ローカルで使って実際のサイトにはコンパイルされたファイルを使うことになると思います。

おまけ:SassとLESSのリンク集

せっかくなのでメジャーどころの2つがどういうものなのか分かる記事へのリンクをまとめておきます。基本的に日本語で読める記事です。

Sass

LESS

他にも検索すればいっぱい出てきますので、色々見てみるといいと思います。
また、比較記事もあります。

どちらもとても分かりやすい比較なので興味のある方は目を通しておくといいかもしれません。