CSSプリプロセッサのfunctionを拡張してみた (CSS Preprocessor Advent Calendar 8th day)
Posted: Updated:
CSSプリプロセッサのfunction
CSS Preprocessor Advent Calendar 2012の8日目でございます。飛び道具的な好奇心に基づき、functionの拡張について調べてみた次第。
今回は、下記の2つの関数をサンプルとして扱います。どちらも実用的なものではありませんが、あくまでサンプルということで、、、。
reverse- 与えられた文字列を逆順に並べ直して返すrandomColor- ランダムなカラーの16進数を返す
Sass編
Module: Sass::Script::FunctionsにあるAdding Custom Functionsを参考にします。じつは、LESSとStylusは使ってたんですが、Sassって使ったことないんですよね...。
sass_add_func.rb
Sass::Script::Functionsにメソッドをつくって、declareすればOK。単純に引数として受け取り、加工して返せば出力されます。
# @see http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#adding_custom_functions
require 'sass'
module Sass::Script::Functions
def reverse(string)
assert_type string, :String
Sass::Script::String.new("'#{string.value.reverse}'")
end
def randomColor()
Sass::Script::String.new('#'+'%06x' % (rand * 0xffffff))
end
declare :reverse, :args => [:string]
declare :randomColor, :args => []
end
ほとんど参考URLのまま写しています。
span::before {
content: reverse(ABCDEFGHIJKL);
background-color: randomColor();
}
.scssなファイルはこちら。続くstylusとの代わり映えのため、SCSSとしました。
Use
作成したRubyファイルをrオプションで読み込ませて利用します。compassとあわせるときはconfig.rbに仕込んだりすれば良いようです。
% sass sample.scss -r ./sass_add_func.rb
span::before {
content: 'LKJIHGFEDCBA';
background-color: #33f620; }
順当に出力されます。良いかんじです。
Stylus編
お次はStylusです。Stylus - JavaScript APIを参考にします。ここに書いてある内容は、わりと必要最小限なので、リポジトリのlib/nodes/*とlib/utils.jsも読んだ方がよさそうです。
stylus_add_func.js
.use(fn)に渡すfunctionをexportsするJavaScriptファイルを用意します。渡ってきたstylus本体に、defineで関数を定義していけばOK。
// @see https://github.com/LearnBoost/stylus/blob/master/docs/js.md
module.exports = function() {
return function(styl) {
var nodes = require('stylus/lib/nodes');
styl.define('reverse', function(arg){
return arg.string.split('').reverse().join('');
});
styl.define('randomColor', function() {
return new nodes.Literal('#'+Math.floor(Math.random()*16777215).toString(16));
});
}
};
randomColorについては、ただのStringで返すと'#12b3b2'のようにシングルクオートがついてくるので、nodes.Literalとして返します。nodesの中は色々あります。
span::before content reverse(ABCDEFGHIJKL) background-color randomColor()
.stylなファイルはこんな感じ。記号レスとして存分に削ってみました。
Use
uオプションで拡張functionを記述したJavaScriptファイルを読み込ませて、コンパイルを実行します。
% stylus -u ./stylus_add_func.js sample.styl
compiled sample.css
% cat sample.css
span::before {
content: 'LKJIHGFEDCBA';
background-color: #12b3b2;
}
StylusはそのままCSSを生成するので、別途catして確認します。OKOK。
LESS編
えー、node実装ならStylusでいいじゃん、とか乱暴な持論を振り回した上で
・・・時間切れ!時間切れでござるよ!!
lessc -hしてみて、それっぽいのが無かったので時間の都合上、手早くあきらめました。すみません(´・ω・`)
まとめ
そんなわけで、変に限られたコンテキストから頑張って凝ったmixinを定義するより、ちゃっちゃとfunctionとして自由なコンテキストで処理するほうがラクだったりするケースもあるんじゃないでしょーか。
ぜひお試しくださいまし。ではでは。