FLOCSSによるコーディング設計
お疲れ様です。
ライフマップ開発チームの石上です。
突然ですが、コーディングの規約について悩んだことはありませんか?特にクラスの命名規則とか。僕もコーディング始めたての頃は、何が最適解なのか悩みながら書き進めていました(今でも悩む瞬間はありますが…)
クラスの名前は自由に設定できる分、標準化されていないと惨事が巻き起こります。それを防ぐにはコーディング規約の制定が重要です。
今回の記事では、「FLOCSSという規約を採用するとコーディングが楽になるよ」というようなことを書いていきます。
慣れるまでは違和感が拭えなかったりするかもしれませんが、それを超えた先にはスムーズで楽ちんなコーディングが待っているハズです。
まずは「FLOCSSって何?」という点から解消していきましょう。
FLOCSSとは?
日本人が提唱したCSSの設計手法で、破綻しにくく保守性の高いCSS運用を目的としています(日本語のドキュメントが多くて大変助かります)。
このFLOCSSでは、CSSを大きく3つのジャンルに分けます。
F:Foundation
L:Layout
O:Object
それぞれ詳しく見ていきましょう。
Foundation
プロジェクトの土台となるスタイルやreset.cssなど、基本的なスタイルを定義します。全ページ・全要素に共通するものと認識しておけばOKでしょう。
変数などもここに含まれてきます。
Layout
ヘッダーやフッター、ナビゲーションなど、サイト全体の共通部分となるレイアウトに関わるものを定義します。
Object
このObjectですが、さらに3つに分かれています。
Component
サイト内で再利用できる最小限の要素を定義します。見出しやボタンなど、各所で使い回すものを定義することが多いですね。
Project
そのページやセクションのみで使用する要素を定義します。
Utility
ちょっとしたスタイル調整のためだけの要素を定義します。「このセクションだけ下余白を設けたい」「この要素だけ文字の色を変えたい」とか。
これらの区分に則り、CSS(SCSS)のファイルを分けていきます。公式のドキュメントでは一例として以下のような構成を推奨していますが、ここら辺はやりやすいように少しアレンジして良いでしょう。
foundation
_base.scss
_reset.scss
layout
_footer.scss
_header.scss
_main.scss
_sidebar.scss
object
・component
_button.scss
_dialog.scss
_grid.scss
_media.scss
・project
_articles.scss
_comments.scss
_gallery.scss
_profile.scss
・utility
_align.scss
_clearfix.scss
_margin.scss
_position.scss
_size.scss
_text.scss
FLOCSSにおける命名規則
さて、FLOCSSではクラス名の付け方に規則(=命名規則)がありまして、その基本形式が「プレフィックス+BEM」です。
この「プレフィックス」と「BEM」という2つの要素について、それぞれ詳しく見ていきましょう。
プレフィックス(=接頭辞)
1つ目のポイントが「プレフィックス」です。
用途に応じてクラス名に接頭辞をつける、ということになります。
と言ってもルールは非常にシンプルで、先述したCSSの役割に準じた頭文字をつければOKです。
例えば、ヘッダーだったら「サイト全体の共通レイアウト=Layout」なので「l-」をつけて「l-header」となります。
componentだったら「c-」、projectだったら「p-」、utilityだったら「u-」といった具合ですね。
Layout:l- (l-header,l-footer,l-navなど)
Component:c- (c-button, c-cardなど)
Project:p- (p-about,p-profileなど)
Utility:u- (u-pc,u-color,u-marginなど)
BEM(Blocks-Elements-Modifiers)
2つ目のポイントが「BEM」です。
「BEM(= Blocks-Elements-Modifiers )」はCSS命名規則の一種で、この記事のメインテーマであるFLOCSSでも採用されています。
基本的な記述方法は以下のようになります。サンプルのコードも併せてご覧ください。
block__element--modifier
block: 大枠となる独立したブロック要素(サンプルでは about)
element: blockの中の子要素(サンプルでは title,item)
modifier: blockやelementのスタイル(サンプルでは red,blue 等)
<section class="about">
<h1 class="about__title">見出し</h1>
<ul class="about__list">
<li class="about__item about__item--red">アイテム</li>
<li class="about__item about__item--blue">アイテム</li>
<li class="about__item">アイテム</li>
<li class="about__item">アイテム</li>
</ul>
</section>
見慣れない人には気持ち悪く映るかもしれませんが、「子要素は__(アンダーバー2つ)で繋ぐ」「バージョン違いは--(ハイフン2つ)で繋ぐ」と言うことを頭に入れておけばOKです。
「プレフィックス+BEM」
という訳で、この2つを組み合わせたものが命名の基本形になります。
実際にコードに反映してみると、こんな具合(↓)になります(あくまでサンプルなので、簡易的なものになります。)
<header class="l-header">
<h1 class="l-header__logo">ロゴ</h1>
</header>
<nav class="l-nav">
<ul class="l-nav__list">
<li class="l-nav__item"><a href="#" class="l-nav__link">リンク</a></li>
<li class="l-nav__item"><a href="#" class="l-nav__link">リンク</a></li>
<li class="l-nav__item"><a href="#" class="l-nav__link">リンク</a></li>
<li class="l-nav__item"><a href="#" class="l-nav__link">リンク</a></li>
</ul>
</nav>
<main class="l-main">
<section class="p-profile">
<h2 class="p-profile__title">見出し</h2>
<div class="p-profile__text">
<p class="p-profile__para">テキスト</p>
<p class="p-profile__para p-profile__para--red">テキスト</p>
<p class="p-profile__para">テキスト</p>
<p class="p-profile__para">テキスト</p>
</div>
</section>
<section class="p-contact">
<h2 class="p-contact__title">見出し</h2>
<div class="c-button">
<a href="#" class="c-button__link">リンク</a>
</div>
</section>
</main>
<footer class="l-footer">
<div class="l-footer__inner">
<div class="l-footer__bottom">
<small class="l-footer__copy">コピーライト</small>
</div>
</div>
</footer>
FLOCSSのメリット
ここまでFLOCSSの概要について説明してきました。クラス名は長ったるいし、接頭辞の分類もまどろっこしいし、慣れるまで少し時間はかかるかもしれません。
しかし、その懸念点を補って余りあるメリットがこのFLOCSSにはあります。具体的にご紹介していきますね。
クラスの役割がハッキリする
プレフィックスの存在により、そのクラスがどのような役割を担っているのか予測可能となり、修正作業がやりやすくなります。
例えば「p-は特有のスタイルだから触っても他に影響は無さそうだな」であったり、「c-は共通のスタイルだから他ページの調査も必要だな」であったり。
クラスのバッティングを避けられる
見出しの通りです。接頭辞に加えファイル分割を行うことで、クラス名がバッティングする可能性を著しく下げることができます。
SCSSとの相性が良い
これはFLOCSSの、というよりはBEMのメリットですね。
BEMの命名規則とSCSSの記法は抜群の相性です。
SCSSには「セレクタを入れ子で記述できる」「&で親セレクタを参照できる」という機能があるのですが、それをBEMと併用すると以下のようなコードになります。
.p-about {
&__title {
font-size: 20px;
font-weight: bold;
text-align: center;
&--right {
text-align: right;
}
&--left {
text-align: left;
}
}
&__paragraph {
width: 800px;
margin: 0 auto;
p {
margin-top: 16px;
}
}
&__list {
display: flex;
}
}
最初にプレフィックスとblock(ここでは「.p-about」になります)を書いておけば、あとは「&__」もしくは「&--」で繋いでいけばOKなのです。
コードがまとまってくれるため、視認性に優れていて全貌を把握しやすいですね。また、これを見ただけでHTMLの構造がざっと理解できるのも嬉しいです。
ちなみにですが、これを通常のCSSで書こうとすると、下(↓)のように何度も同じテキスト(.p-about__)を記述することになります。
.p-about__title {
font-size: 20px;
font-weight: bold;
text-align: center;
}
.p-about__title--right {
text-align: right;
}
.p-about__title--left {
text-align: left;
}
.p-about__paragraph {
width: 800px;
margin: 0 auto;
}
.p-about__paragraph p {
margin-top: 16px;
}
.p-about__list {
display: flex;
}
.p-about__item {
width: 30%;
}
(シングルページなど小規模サイトならまだ良いのですが、規模が大きくなったら…)
運用のポイントや注意点
最後に、運用していく上でのポイントや注意点、個人的にはこんな風にアレンジしてるよ、といったことをお話しできればと思います。
SCSSファイルの構成をアレンジする
ファイル構成は、公式が推奨しているそのまんまの形ではなく少しアレンジしてもOKだと思います。
僕の場合、小規模なサイトであればあまり細かく分けることはせず、共通のscssファイル(style.scss)とページごとのscssファイル(about.scssとかcontact.scssとか)に分ける程度で済ませています。
また、ComponentとProjectの違いがわかりづらく、分類に困ることもあります。
ざっくりにはなりますが、「他ページでも使用するものはComponent、そうでないものはProject」くらいの認識でOKかなというのが個人的な考えです。無理に共通化しようとするとそれはそれで大変なので、臨機応変に対応しましょう。
この辺りは、プロジェクトやチームで落とし所を決めていくのが吉です。
独自のプレフィックスを導入する
上で紹介した4つ以外に、独自のプレフィックスを導入することもOKです。
例えば、Javascriptの操作に関するものには「js-」、要素の状態を表す場合には「is-」など。この2つは僕もよく用います。
単語の連続にはキャメルケースで対応する
クラス名を考える際、稀に複数の単語が連続してしまうことがあります。
単語同士を「-(ハイフン)」や「_(アンダーバー)」で繋ぐ記述方法(スネークケースやケバブケースと呼ばれます。)もありますが、基本的にこれらは採用しません。
なぜなら、BEMで使用する「__」「--」と思いっきりバッティングして見辛いからです。
キャメルケースでの記述がオススメです。
ルールは「最初の単語以外は頭文字を大文字にして接続する」というもの。以下のような感じになります。
×:l-nav__sns-list
×:l-nav__sns_list
○:l-nav__snsList
補足:
これはあくまでクラスの命名における都合なので、他言語においてはもちろんこの限りではありません。「BEMとは相性が悪いのでは?」という点に尽きます。
終わりに
今回はFLOCSSについての紹介記事でした。
記事中にあるように、FLOCSSをベースとしてやりやすいようにアレンジして運用するのが良いかなと思います。
ではまた!
https://github.com/hiloki/flocss
https://tane-be.co.jp/knowledge/web-design/2270/
https://webdesign-trends.net/entry/15813
https://yumegori.com/flocss
https://haniwaman.com/flocss/#index_id13