モダンCSS設計というけれど
OOCSSとか、SMACSSとか、BEMとか。最近、モダンCSS設計ってのを見かけるんだけど、何か苦労してるなぁ、って感じる。
これらって命名規則にすぎないから、結局、運用次第ってことになる。プロジェクトメンバーが少人数ならいいだろうけど、人数が増えると結構簡単に破綻するんじゃないだろうか?
まぁ、CSSが貧弱すぎるのがいけないよね。
Bootstrapを使ってると、ふと疑問に思うことがある。
例えば「pull-right」。右に寄せるって、デザインじゃないの?
HTMLで構造を表してCSSでデザインする、とか言ってたと思うんだけど、どこに行ったんだろう?
まぁ、CSSが貧弱すぎるのがいけないよね。
でも、CSSだけで頑張りすぎているような気もするんだよね。
どうせテンプレートを使うんだから、もっと組み合わせて使うことを考えたらいいんじゃないだろうか?
Bootstrapは、テンプレートにクラスを指定すれば、ある程度のデザインができるのは楽なんだけど、デザインを修正するたびにHTMLとCSSの両方をいじっていることに気がついた。
これなら下手にCSSなんて独自に定義しないで、テンプレートにstyleで書き込んじゃうほうがいいんじゃないだろうか?
Backbone.Viewの中だけで使えるスタイルを定義する
Backbone.jsを使ってるんだけど、Viewの中でだけ使えるスタイルが定義できたらいいんじゃないだろうか?
というわけで、まずjQueryのプラグインを作ってみた。
これを使うと、
<div id="demo">
<img src="picture.jpg" class="picture">
<div class="body">
<div class="header">
header
</div>
<div class="memo">
memo
</div>
</div>
</div>
こんなHTMLに対して、
$('#demo').applyStyles({
classes: ['media', 'clearfix']
,sections: [{
'name': '.picture'
,'classes': ['pull-right']
,'styles': {
'width': '200px'
}
},{
'name': '.body'
,'classes': ['media-body']
,'styles': {
'width': '500px'
}
,'sections': [{
'name': '.header'
,'classes': ['media-heading', 'h4']
,'styles': {
'color': 'white'
,'background-color': 'rgb(103, 88, 195)'
,'width': '100%'
}
}]
}]
});
こんな適用をすると
<div id="demo" class="media clearfix">
<img src="picture.jpg" class="picture pull-right" style="width: 200px;">
<div class="body media-body" style="width: 500px;">
<div class="header media-heading h4" style="color: white; width: 100%; background-color: rgb(103, 88, 195);">
header
</div>
<div class="memo">
memo
</div>
</div>
</div>
こんなふうになる。
これを、Backbone.Viewの中で使う。
var view = Marionette.ItemView.extend({
styles: {
...
}
,onRender: function(){
this.$el.applyStyles(this.styles);
}
});
(Backboneといいつつ、Marionette.js使ってますが・・・)
これで、Viewの中だけでスタイルを定義できるようになった。
クラスも追加できるようにしてあるので、Bootstrapのようなライブラリと併用して使うことができる。
このあたりがちゃんと作りこんであれば、アプリケーション個別で定義するCSSは減るんじゃないだろうか?
CSSの記述量が減れば、命名規則で頑張らなくても、あんまり破綻しないと思う。
結果的に、テンプレートでは構造だけを表現することになった。シンプルになっていいよね?
課題
メインの処理をjQueryのプラグインにしたのは、Backbone以外のフレームワークでも使えるだろうと思ったからなんだけど、サーバーサイドでHTMLを生成している場合は、表示してからスタイルを適用するまでにタイムラグができちゃって、あまりよろしくないかも。
Backbone.Viewを使う場合でも、renderする前にViewが表示されていると同じことになるなぁ。