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として自由なコンテキストで処理するほうがラクだったりするケースもあるんじゃないでしょーか。
ぜひお試しくださいまし。ではでは。