これまで Basis は Sass/CSS フレームワークとして開発していましたが、先日書いた記事(SassからStylusに乗り換えてみたので違いや躓いたところなど)のとおり Stylus がなかなか良さ気だったので Stylus 版の Basis を作りました。
その中で、Stylus でやるなら単純に Sass を書き換えるだけじゃなく設計から変えたほうが良いのではないか?という気がして内部的には結構書き換えを行ったりしたので、その辺りも含め、Basis とは何か、どういう思想に基づいて開発しているのか、等改めてまとめてみたいと思います。
Basis の設計思想
Basis は「どんな Web サイトの制作にも適用でき、簡単に使え、邪魔にならない CSS フレームワークが欲しい」との思いから開発をはじめました。それらを実現するため、Basis には次のようなことを意識して開発しています。
疎結合なコンポーネント
CSS フレームワークにはボタンやアラートなど様々なコンポーネントが用意されていますが、Basis はこれらコンポーネントがなるべく疎結合で他の要素に影響を与えることがないように考えています。そのためよりコンポーネント化を意識できるように命名規則は MindBEMding を使用しています。
余計な装飾を持たない
一般的なフレームワークのボタンコンポーネント等ははじめから色がついていたりしますが、そのような装飾はモックや管理画面を作る場合等はあったほうが良いかもしれませんが、Web サイトの制作においてはほとんどの場合邪魔になるので Basis のコンポーネントはなるべく装飾を持たないようにしています。
名前空間を汚染しない
プリフィックスがない場合、名前空間が汚染されプロジェクトで .btn
というクラスを定義したら勝手に邪魔な装飾がついてしまうであるとか、変数を定義したら意図せず上書きされてコンパイルが通らない等の問題が起こってしまいます。そのため Basis のクラス名、変数、mixin 等、グローバルな要素には全てプリフィックスがついています。クラスのプリフィックス(デフォルトではアンダーバー)は変数で定義されているので好きな文字列に上書き可能です。
// 変数、mixin は bs- がついています bs-font-size ?= 16px; bs-font-size-line-height() { ... } // クラス名は _ がついています。 ._btn { ... } ._alert { ... }
プリプロセッサ使用前提
Basis は Stylus で書いていて、一応 GitHub のリリースページではコンパイルされた CSS も一緒に配布していますが、実際にはそのコンパイルされた CSS を使うことは推奨していません。
僕はもともとコンパイル済みの Bootstrap をよく使っていたのですが、結局作業を効率化するためには共通部分を mixin で定義したり変数を定義して使いまわしたりしていたので、それならいっそそれらをフル活用できるようなフレームワークにしよう、という考えるようになりました。
そのため、Basis では変数として用意されたベースのフォントサイズを設定すれば、それにあわせて自動的に余白や行間サイズが調整されるような仕組みにしたり、プリプロセッサをなるべくフル活用できるよう考えながら開発しています。
Basis の特徴
CSS 設計
最近 CSS 設計に関する記事や話を聞く機会が多くなってきています。CSS フレームワークは汎用的に使える必要があるので、ただ普通にページコーディングする場合よりも設計が重要になってきます。Basis では「Web制作者のためのCSS設計の教科書」の著者である谷さんが考案された FLOCSS を使用しています。シンプルであること、日本語のドキュメントがあること、命名規則が MindBEMding であることが理由です。
バーティカルリズム
バーティカルリズムとは縦のリズム(余白、行間、文字サイズ)を一定のルールに則って整えることでデザインの整合性・一貫性を保つ手法のことです(こちらの記事「なぜタイポグラフィにおいてVertical Rhythm(バーティカルリズム)は重要な手法なのか?」がわかりやすいです)。例えばベースラインが 24px の場合は段落間の余白も 24px にするとか、各要素の line-height
を必ず倍数にしたりすることでリズムを整えることができます。
Basis はバーティカルリズムを実現するためにグローバル空間に変数(基本となる文字サイズや行間、余白の大きさの基準となる係数等)と mixin を定義しています。
// // Default font size // If html { font-size: 62.5% }, set 10px // @type px // $bs-base-font-size-px = 16px; // // Between the character and line of line-height // In the case of multibytes characters might be a good is about 0.375rem. // @type rem // $bs-between-lines = (1rem / 4); // // Margin coefficient // If you want to take the margin larger between elements than the standard, please try to 2 or more. // @type int // $bs-margin-coefficient = 1;
下記のようにスタイルを定義することで自動的に最適な line-height
が適用されます。
.foo { /* 基本の行間設定に応じて、文字サイズに応じて最適な line-height を設定する */ bs-font-size-line-height(16px); } .bar { bs-font-size-line-height(32px); } ↓↓コンパイル結果 .foo { font-size: 16px; line-height: 1.5; /* 24px 相当 */ } .baa { font-size: 32px; line-height: 1.1875; /* 38px 相当 */ }
また、margin
や padding
についても係数を指定して自動的に最適な値を設定できる仕組みを用意しています(行間がすごく広いのに余白はすごく狭い、みたいなデザインは基本的にはありえませんよね)。グローバルの変数に加え mixin で指定される係数を掛けあわせて最適な余白を自動的に設定します。
.foo { bs-margin-top(2); bs-padding-top(1); bs-padding-bottom(1); } .bar { bs-margin(1); bs-padding(1, 2); }
完璧にリズムを整えるためには文字サイズも計算して決めなければいけませんし、画像などの要素が入るとどうしてもズレてしまうので完璧に整えることは現実的ではありませんが、特に考えずにその時の間隔で CSS を書くよりは、はるかに整ったリズムに(しかも簡単に)することができると思います。
Flexbox ベースのグリッドシステム
一般的によく使われている Bootstrap や Foundation などのフレームワークは float ベースのグリッドシステムですが最近では IE8 や 9 はほぼ無視できる状況になってきているので float より無理なく柔軟なグリッドの指定ができる Flexible Box Layout Module(Flexbox)を採用しています。また、Basis のグリッドシステムはサイズを指定する class の母数が可変になっており、より柔軟なグリッドサイズの指定を行うことができます。
// サイズ無指定の場合は均等サイズに分割 <div class="_c-row"> <div class="_c-row__col">1/3</div> <div class="_c-row__col">1/3</div> <div class="_c-row__col">1/3</div> </div> // 1/4 ずつに分割したグリッド <div class="_c-row"> <div class="_c-row__col _c-row__col--1-4">1/4</div> <div class="_c-row__col _c-row__col--1-4">1/4</div> <div class="_c-row__col _c-row__col--1-4">1/4</div> <div class="_c-row__col _c-row__col--1-4">1/4</div> </div> // 母数は2〜12の可変。変数で上書き可能。 <div class="_c-row"> <div class="_c-row__col _c-row__col--1-2">1/2</div> <div class="_c-row__col _c-row__col--6-12">6/12</div> </div> // float ベースでは難しかった下付けや中央揃えも簡単に実装できる <div class="_c-row _c-row--bottom"> <div class="_c-row__col"></div> <div class="_c-row__col"></div> </div> <div class="_c-row _c-row--middle"> <div class="_c-row__col"></div> <div class="_c-row__col"></div> </div>
アドオン
Basis は本体をなるべくスリムに保つために、汎用的によく使われるコンポーネントは本体に、そうでないコンポーネントはアドオンとして分けて配布する仕組みにしています。アドオンは例えばハンバーガーボタンやドロワーメニュー等があります。Basis 本体もアドオンも全て npm で配布しているのでコマンドで簡単に取り込むことができます。
$ npm install getbasis $ npm install getbasis-hamburger-btn $ npm install getbasis-drawer あとはプロジェクト内の .styl や .js からインポートするだけ
アニメーション・トランジション
他のフレームワークではあまり見ない(僕が知らないだけかも)、ちょっと動きを付けれるほうがデザイン的におもしろそうという短絡的な理由でアニメーション・トランジションの mixin、クラスを用意しています。結構気に入っているので汎用化できるパターンが思いつけば増やしていきたいなと思っています(その場合はまるっとアドオンとして切り出したほうが良いかもしれない)。
クラスを出力せずにコアだけの利用も可能
「CSS フレームワークは無駄なクラスが大量にあって重いから使わない」という方もいますよね。確かに使わないクラスが吐き出されたりプロジェクトに合わない命名規則だとイヤな感じがしたりするかもしれません。Basis はそのようなフレームワーククラス不要論者の方のために変数でクラスを吐き出すかどうかを選択できるようになっています。
// デフォルトは false。true にしてから Basis をインポートすればクラスは吐き出されない bs-use-mixin-only = true; @import "/Path/TO/get-basis/basis";
Sass 版との違い
mixin vs extend
Sass 版のコンポーネントは mixin の組み合わせ、Stylus 版の Basis は placeholder を extend する形でコンポーネントを定義しています。Stylus の extend は Sass の extend と違い子要素まで継承できます。Basis のコンポーネント定義に限定すればそれはあまり関係無いのですが、よりそれを意識して Basis をプロジェクトで利用できるようにという意図で Stylus 版では extend を多用する設計に変更しました(Sass 版の mixin の組み合わせで、というのも結構試行錯誤であまり納得がいっていなかった&機能していなかった、というのもあります)。
Vanilla JS vs jQuery
Basis 本体には JS は含まれていないのでこれはアドオンの話になります。Sass 版の場合は jQuery を使用せずに JS を書いていますが Stylus 版では jQuery を使用しています。僕はもともと jQuery 否定派でも何でもなくて便利なものは使えばええやん派なのですが、まともに JS を書いたことがなかったので ES2015 の勉強ついでにやってみようと素の JS で書きました。結果、単純にめんどくさい、僕はどうせ WordPress がほとんどでコアに jQuery が含まれているので軽量化としての意味はなさない、という理由から Stylus 版では普通に jQuery を使って書きました。難しいことはしていないのでコードも短くシンプルになって結果これで良かったなと思います。
今後
Sass 版と Stylus 版はコードや設計に結構違いがあり二重管理になってしまうのが非常に辛いだろうなという気がしているので今のところは新規開発は Stylus 版のみ(Sass 版はバグフィックスのみ)にしようかなと考えています。構文的に Stylus のほうが簡潔で、Sass の機能をフルに活用していてやめれないということでなければ Stylus 版のほうが覚えやすいと思うので、この機会に Stylus さわってみてはいかがでしょうか?