CSS設計手法の1つであるFLOCSSについて、実際のソースコードを交えつつ具体的に解説していきます。CSS/Sassは書けるけれど設計に自信がない方や、FLOCSSを書いてみたが慣れずに挫折しそうという方は是非一度読んでみてください!
メリット・デメリット
メリット
FLOCSSとは?みたいな概念的なことは本記事では割愛します。気になる方は公式ドキュメントを参照してください!日本語で記載されているので読みやすいと思います。
FLOCSS導入のメリットは保守性を高めることに尽きますが、具体的には以下のようなメリットがあります!
- フォルダ構成やクラスのプレフィックスなどが決めれており、推察しやすくソースを見て直感的にわかりやすい。
- 共通部品の再利用性の高い。
- 特定の箇所を修正したことによる、予想外の箇所に影響があることが少なくなる。
デメリット
私が感じたデメリットは、BEMの命名規則を前提にしているのでクラス名が冗長になりがち ということです。ただ、この点についてはModifierではなくStateパターンを採用すること(後述)で少しでも冗長さを排除することは可能であります!
書き方
命名規則
BEM
FLOCSSではBEMの命名規則がベースとなっています。BEMの解説はこちらの記事を参考になるかと思います!BEMの悩みどころというと、HTMLのネストが深くなった際の命名に悩むことがあります。その際には、以下2つの方法で命名を考えます。冗長はなりますが、個人的には前者の書き方が好みです。
以下のようにリストの中にアイテムが来るようなよくあるシーンを想定してみます。
<div class="p-top">
<ul><!-- リスト -->
<li><!-- アイテム -->
<p>ダミーテキスト1</p>
<p>ダミーテキスト2</p>
<li>
</ul>
</div>
Elementの中でBlockを再定義
ネストが深くなったり、Element配下の要素が多く命名に悩んだりする場合は、Blockを再定義して上げるときれいな設計になります。
<div class="p-top">
<ul class="p-top__list">
<li class="p-top__item">
<div class="p-top-item"><!-- Blockを再定義 -->
<p class="p-top-item__txt1">ダミーテキスト1</p>
<p class="p-top-item__txt2">ダミーテキスト2</p>
</div>
<li>
</ul>
</div>
.p-top{
&__list{
display: flex;
}
&__item{
width: 33.333%;
}
&-item{
color: red;
&__txt1{
font-weight: bold;
}
&__txt2{
font-size: 18px;
}
}
}
Elementの中にElementをネスト
Element配下の要素が少ない今回の例のような場合だと、Elementをネストさせて命名することでも対応可能です。
<div class="p-top">
<ul class="p-top__list">
<li class="p-top__item">
<p class="p-top__item-txt1">ダミーテキスト1</p>
<p class="p-top__item-txt2">ダミーテキスト2</p>
<li>
</ul>
</div>
.p-top{
&__list{
display: flex;
}
&__item{
width: 33.333%;
color: red;
}
&__item-txt1{
font-weight: bold;
}
&__item-txt2{
font-size: 18px;
}
}
クラスにプレフィックスをつける
フォルダ構成の中で説明がありますが、各フォルダに合わせてプレフィックスをクラスに対して付与します。
フォルダ構成
FLOCSSのフォルダ構成について解説します。※ ファイル名は一例
style.scssには、Foundation → Layout → Object(component → layout → utility)の順に各種scssファイルをインポート
style.scss
|- Foundation - ブラウザスタイルの初期化やCSS全体の基本設定
|- _base.scss フォントサイズや色などの基本設定
|- _function.scss ファンション
|- _mixin.scss ミックスイン
|- _placeholder.scss プレースホルダー
|- _initialize.scss 初期化処理
|- Layout - ヘッダー、フッターなどのページ構成スタイルを設定
|- _header.scss ヘッダー
|- _footer.scss フッター
|- _sidemenu.scss サイドメニュー
|- Object - 以下サブフォルダを包含
|- Component - 共通的部品のスタイル
|- _button.scss
|- _calender.scss
|- _inner.scss
|- _title.scss
...
|- Project - 各ページ、コンポーネントの固有スタイル
|- _top.scss トップ
|- _company.scss 企業紹介
|- _contact.scss お問い合わせ
...
|- Utility - 軽微な調整用スタイル
|- _font.scss フォント調整用
|- _margin.scss マージン調整用
...
Foundation
クラスのプレフィックス:特になし
設定値やメディアクエリのミックスインなどスタイル全体で使用するものを定義する。
Layout
クラスのプレフィックス:l-
各ページを構成する枠組みのような部品に対するスタイル
ヘッダー、フッター、サイドメニュー、メインコンテンツエリアなどなど。
.l-header {
&__nav {
width: 100px;
}
&__logo {
width: 100px;
}
}
Component
クラスのプレフィックス: c-
ページ横断で使用される共通部品に対するスタイル
ボタンなど繰り返し使う部品はこちらに。
.c-button {
width: 100px;
height: 50px;
background-color: blue;
&--green{// 色違い:緑(Modifierによる装飾)※個人的には非推奨
background-color: green;
}
&.is-active{// アクティブカラー:赤(stateパターンによる装飾)
background-color: red;
}
}
Project
クラスのプレフィックス: p-
各ページの固有スタイル
画面ごとのスタイルなど、基本的にはProjectのクラスをガリガリ作成していく。
.p-top {
&__title{
font-size: 20px;
}
&__list{
display: flex;
}
...
}
Utility
クラスのプレフィックス: u-
軽微な調整用スタイル
ここの文字サイズ変えたいなーでも個別にクラス作成したりmodifier作成するのはイマイチだなというときに使うようなクラスで、以下のように使いそうなものは予め用意する&必要になったら追加していくでいいと思います。
.u-font {
$list: 10,15,20,30;
&-bold {// 太字
font-weight: 600;
}
&-s {// サイズ
@each $size in $list {
&-#{$size} {
font-size: (#{$size}/10)rem;
}
}
}
}
全体のBlock、Elementのイメージはこのような感じです!
カスケーディングルール
同一レイヤーによるカスケーディングは禁止、他レイヤー間のカスケーディングは許容
FLOCSSでは、Component << Project << Utility と後ろで定義したレイヤーのほうが優先されるように設計されているため。意味合い的には、Componentで共通的に用意したクラスをProjectの個別画面で一部上書きはOK。
だめな例
.c-page {
.c-button{
...
}
}
.p-page {
.p-item{
...
}
}
OKな例1
.c-button{
width: 100px;
height: 50px;
color: red;
}
...
.p-page {
.c-button{
height: 100px;// p-page内では高さを大きくする
}
}
共通的なc-buttonのスタイルを定義した上で、p-page内の一部スタイル変更などの場合が該当します。
あるいは、CSSでカスケーディングして解決するのではなくhtmlにマルチクラス化する。
.c-button{
width: 100px;
height: 50px;
color: red;
}
.p-page {
&__button{
height: 100px;// p-page内では高さを大きくする
}
}
<div class="c-button p-page__button">
...
</div>
個人的にはこっちが好みです。
迷いどころ
独自拡張
Modifier を使用しない
BEMのデメリットとしてクラス名が冗長でhtmlが見づらくなります。なので少しでもクラス名を短くしたい。かつ汚染(意図しない変更)がないように設計にするためには、公式でも紹介されているようにStateパターン(is-をプレフィックス)にして、差分のみ定義するがいいと思います。
<button class="c-button c-button--green"></button>
.c-button {// ボタンの基本的なスタイルを定義
width: 100px;
height: 50px;
background-color: blue;
&--green{// 色違い:緑(Modifierによる装飾)
background-color: green;
}
}
よりも
<button class="c-button is-green"></button>
.c-button {// ボタンの基本的なスタイルを定義
width: 100px;
height: 50px;
background-color: blue;
&.is-green{// 色違い:緑(Stateパターンによる装飾)
background-color: green;
}
}
まとめ
FLOCSSはBEMベースのため冗長ではありますが、その分保守性の高いコーディングが可能になります。独自拡張も含め、修正しやすく・破綻しにくい設計をしていくことが重要だと思います。
FLOCSS以外にもDart Sass化の手順についても公開していますし、制作の実績もあるのでよければ是非読んでみてください!
Dart Sass化について
-
【Dart Sass】Sassコンパイル環境の移行と高速化!
gulpのSassコンパイル環境のDart Sass化を解説します!これから移行しようとされている方や移行にチャレンジしたがエラーで詰まっている方は是非読んでみてください!
web制作実績一覧記事
-
【実績公開】これまでのWeb制作の実績や成果物を公開します!
2024/1/5 Web制作
今まで受注して作成させて頂いたサイトや個人で作成したサイトを公開します!
Sassの自作テンプレートはgithubにて公開しています!