前回の記事「CSSフレームワークを開発していて悩む、CSSフレームワークが持つクラスのHTMLへの依存について」の続編です。記事を公開後、Twitter等で記事に対する意見をちょいちょい書いてくださってる方々がいてくださったので、参考にさせて頂いて Basis をリファクタリングしました。
レイヤー構成をアップデート
これまではまず各コンポーネントの基本部分を構成する placeholder と、その placeholder で構成されたクラスを提供していました。ただ、これだと MindBEMding から逃れられないということで、さらに placeholder を構成するための mixin レイヤーを追加しました。例えば media コンポーネントの場合は次のような感じです。
mixin レイヤー
mixin レイヤーでは最低限の骨格だけを定義。
_media() {
display: flex;
}
_media__figure() {
flex: none;
_background-image-cover();
}
_media__body() {
flex: 1;
}
placeholder レイヤー
placeholder レイヤーでは最低限の装飾も定義。
$_media {
_media();
&__figure {
_media__figure();
_margin(0, 1, 0, 0);
> * {
vertical-align: top;
margin-top: _between-lines;
}
}
&__body {
_media__body();
}
}
クラス(具体化)レイヤー
クラスレイヤーでは modifier も定義。
.{_prefix}c-media {
@extend $_media;
&__body {
> .{_prefix}c-media {
_margin-top(1);
}
}
&--middle {
align-items: center;
}
&--reverse {
.{_prefix}c-media__figure {
_margin(0, 0, 0, 1);
order: 1;
}
}
}
カスタムデータ属性の利用
JavaScript のイベント割り当てなど、クラスに依存しないほうが良い部分についてはカスタムデータ属性を使うように変更しました。JavaScript で最低限の動作や変更を行う場合、これだけはないとコンポーネントとして成立しないというスタイルがでてきます。そのため、そのようなスタイルについてはクラスではなくカスタムデータ属性に対してスタイルをあてました。例えばドロワーの場合は次のような感じです。
こうすることで何が解決するのか
Basis の CSS 設計から解放される
Basis は CSS 設計は FLOCSS、クラス名の命名規則は MindBEMding となっています。そのままクラスや placeholder を使うとどうしてもその設計や命名規則に依存してしまうのですが、mixin レイヤーを追加したことでこれらの設計や命名規則から解放されます。OOCSS でボタンコンポーネントを定義したい、ということであれば次のように実現できます。
.btn {
_btn();
&-info {
background-color: #5bc0de
color: #fff;
}
&-block {
display: block;
}
}
ついでに、クラス名に依存しないようになることで「CSS フレームワーク、セマンティックじゃない問題」も解決できますね。
JavaScript からの依存の解決
前の記事で詳しく書きましたが、これまではクラス名でイベントの対象を指定していました。
$('._c-drawer__btn').on('click', (event) => {
おされたときの処理
});
js ライブラリのインポート段階でこのセレクタは変更できるようにしていましたがそれはダサいなと…。カスタムデータ属性を使うようにしたことで、このダサい機能は不要になりました。カスタムデータ属性を付与することでそのコンポーネントとして成立する最低限の動作と装飾を、それ以上の見た目を整える装飾はクラスで行うという感じです。
$('[data-c="drawer-btn"]').on('click', (event) => {
おされたときの処理
});
「CSS フレームワーク重い問題」から解放される
個人的にはせいぜい数十KBとかいっても100KB程度の CSS フレームワークが体感として動作にすごく影響が出るほど重いとは思わないのですが、Bootstrap に対する批判としてよく聞かれますね。Bootstrap の場合は公式サイトから必要なコンポーネントを絞ってダウンロードできるので、不要ならその部分ダウンロードしなかったらええやん…と思うんですが。話がそれました。Basis の場合は変数でクラスを生成する、生成しないを選択できるようになっています。これは以前からそうしていてはいたのですが、mixin レイヤーを追加したことで、コンポーネントの生成がもっと簡単になるかなと。
ちなみにクラスを生成したくない場合は次のような感じで簡単にできます。
_use-mixin-only = true; @import 'node_modules/getbasis/src/stylus/basis';
まとめ
これまでちゃんと設計についてまとめたドキュメントがなかったので、下記の issue にまとめるようにしてみました。