CSS設計思想の「FLOCSS」がイマイチ理解できてなかったため、練習としてFLOCSSを用いてLP的なものを作成。
※備忘録がてら、公式からの引用もしながらになります。
FLOCSSとは
FLOCSSとは「クラス設計」の1つで、HTML・CSSで使うクラス名の決め方のルールの一種ですね。
引用:https://github.com/hiloki/flocssFLOCSS(フロックス) は、OOCSSやSMACSS、BEM、SuitCSSのコンセプトを取り入れた、モジュラーなアプローチのためのCSS構成案です。
MCSSのレイヤー構成にも大きな影響を受けています。
CSSを個人で書くだけなら別にルールも何もいらない。と言う意見もあるかもしれませぬ。
ただ、チームでの開発ではもちろん、個人で開発したWEBサイトなどでも修正が必要になったときに、後から見返すと
「おいおい・・・誰やねんこんなクソコード書いたやつ。・・・オレか。」となり、ちょっとした修正すらムダに時間を使ってしまいますよね。
そんな状況を未然に防ぐためにクラス設計はやはり必要ではないかと思います。
FLOCSSのルールについて
このあたりが、私も開発をしていると徐々にごちゃごちゃしてきて、ルール崩壊しそうになるので公式のを引用させてもらいつつ備忘録としてまとめます。
①ディレクトリ構成について
FLOCSSは次の3つのレイヤーと、Objectレイヤーの子レイヤーで構成されます。
- Foundation - reset/normalize/base...
- Layout - header/main/sidebar/footer...
- Object
- Component - grid/button/form/media...
- Project - articles/ranking/promo...
- Utility - clearfix/display/margin...
他のOOCSSに基づくフレームワークおよびスタイルガイドと同様に、 再利用性や拡張性を持たせるために、これらのルールで分類をします。
引用:https://github.com/hiloki/flocss
特に、Objectの「Component」と「Project」がごっちゃになりやすい。
公式では以下のように説明されている。
1. Component
再利用できるパターンとして、小さな単位のモジュールを定義します。
一般的によく使われるパターンであり、例えばBootstrapのComponentカテゴリなどに見られる
button
などが該当します。出来る限り、最低限の機能を持ったものとして定義されるべきであり、それ自体が固有の幅や色などの特色を持つことは避けるのが望ましいです。
2. Project
プロジェクト固有のパターンであり、いくつかのComponentと、それに該当しない要素によって構成されるものを定義します。
例えば、記事一覧や、ユーザープロフィール、画像ギャラリーなどコンテンツを構成する要素などが該当します。
3. Utility
ComponentとProjectレイヤーのObjectのモディファイアで解決することが難しい・適切では無い、わずかなスタイルの調整のための便利クラスなどを定義します。
Utilityは、Component、ProjectレイヤーのObjectを無尽蔵に増やしてしまうことを防いだり、またこれらのObject自体が持つべきではない
margin
の代わりに.mbs { margin-bottom: 10px; }
のようなUtility Objectを用いて、隣接するモジュールとの間隔をつくるといった役割を担います。またclearfixテクニックのためのルールセットが定義されているヘルパークラスも、このレイヤーに含めます。
引用:https://github.com/hiloki/flocss
こう、説明を見ている段階では「ふんふん。なるほどね。」とか思うんだけど
実際に作っていると、「あれ?これComponent?Project?」みたいになるんだよね。
色んな記事参考にしながら練習するしかないニャ
個人的なイメージとしては
・Component
共通化するパーツ。「ボタン」にしても全部のページで「基本同じになるスタイル」部分はこっち。
例えばボタンのpaddingやborder-radiusなんかの、パターンとして同じものを設定
・Project
Componentで共通化したスタイルなど+その他に「独自性」を持たせたい部分に使用。
例えば「送信ボタンだけ別の色にして、大きさも変えよ。んじゃProjectとして設定するか。」みたいな感じ。
このあたりは以下の記事も参考にさせていただきました。
https://www.ozlink.co.jp/lab/1050/
https://qiita.com/uggds/items/d904b2f9a103c37a25fa
② 命名のルールについて
BEMシステムのシンタックスである、Block、Element、Modifierに分類して構成される規則を採用します。
FLOCSSでは、オリジナルのBEMのシンタックスではなく、MindBEMding のアイデアを基本的にそのまま取り入れています。
Modifierの命名の派生パターンとして、JavaScriptで操作されるような「状態」を表すようなModifierについては、SMACSSのStateパターンの命名を拝借し、
is-*
プレフィックスを付与し、.is-active
というようにすることもできます。このアイデアを採用する場合の原則として、
.is-active
そのものにルールを持たせるのは禁止します。これは.is-active
そのものが持つルールが、 他のモジュールのModifierのスタイルを汚染してしまうのを防ぐためです。Objectのプレフィックス
Objectレイヤーの中で分類されるモジュールに対し、役割を明確にするためにプレフィックスをつけることを推奨します。
- Component -
.c-*
- Project -
.p-*
- Utility -
.u-*
Note:
引用:https://github.com/hiloki/flocss
これらの命名規則は、あなたのプロジェクトが持つオリジナルの命名規則に従い、キャメルケースなどを組み合わせたものでも構いませんが、必ず命名に一貫性を保つようにしてください。
Block__(アンダースコア2つ)Element--(ハイフン2つ)Modifier
のように「〇〇__△△--□□」という形でクラス名を基本的に命名していく。
例)c-button__text--big
・「c-」でComponentだよー。色んなとこで使い回すよー。
・ボタンのスタイルなんで、buttonっていう「Block」(パーツ名)にしますよ。
・ボタンってパーツの中の、textっていう「Element」についてね。
・その中でも文字が大きいパターンのボタンが必要だから「Modifier」に、bigをつけるよー。
ってイメージで命名しちゃう。
とりあえずアウトプットしてみる。
やらないと分からないし、やっても結局訳わからなくなるんだが、やらないと身につかないので。
ってことでテキトーに作ったのが以下。
https://6frkg9fesdsmknooqituza.on.drv.tw/ramen-majin/home.html
ソースは以下のようになっています。
【HTML】
※head部分は省略
<body>
<header class="l-header">
<div class="p-header">
<h1 class="c-title p-header__title">RAMEN MAJIN</h1>
<!-- SP ハンバーガー -->
<button class="c-button p-toggle-button js-toggle-button">
<img src="public/images/menu.png" class="c-image p-toggle-button__image p-toggle-button__image--open js-toggle-image on">
<img src="public/images/close.png" class="c-image p-toggle-button__image p-toggle-button__image--close js-toggle-image ">
</button>
<!-- NAVメニュー -->
<nav class="p-nav js-toggle-nav">
<ul class="p-nav__wrap">
<li class="p-nav__list">
<a href="" class="c-link p-nav__link">HOME</a>
</li>
<li class="p-nav__list">
<a href="#news" class="c-link p-nav__link">NEWS</a>
</li>
(中略)
</ul>
</nav>
</div>
</header>
<main class="l-main">
<!-- HERO -->
<section class="c-section p-hero">
<img src="public/images/img1.jpg" class="c-image p-hero__image">
</section>
<!-- NEWS -->
<section id="news" class="c-section c-section--bg1 p-news">
<div class="c-container">
<h2 class="c-title p-news__title">NEWS</h2>
<div class="p-news__container">
<p class="c-text p-news__text">2023.8.15 OPEN!</p>
<p class="c-text p-news__text">2023.8.14 ついにはじまります。</p>
<p class="c-text p-news__text">2023.8.12 ラーメンが続々追加!</p>
</div>
</div>
</section>
<!-- MENU -->
<section id="menu" class="c-section c-section--bg2 p-menu">
<div class="c-container">
<h2 class="c-title p-menu__title">MENU</h2>
<div class="p-menu__container">
<div class="c-card p-menu__wrap">
<img src="public/images/img2.jpg" class="c-image p-menu__image">
<p class="c-text c-text--big p-menu__name">お子様ラーメン</p>
<p class="c-text p-menu__summary">お子様でも食べやすいシンプル・味薄めのラーメン。化学調味料・添加剤等は未使用です。</p>
<p class="c-text c-text--big p-menu__price">¥ 500</p>
</div>
<div class="c-card p-menu__wrap">
<img src="public/images/img3.jpg" class="c-image p-menu__image">
<p class="c-text c-text--big p-menu__name">オリジナル</p>
<p class="c-text p-menu__summary">当店の売れ筋No.1!原点にして頂点のあっさり醤油ラーメン</p>
<p class="c-text c-text--big p-menu__price">¥ 1,000</p>
</div>
(中略)
</div>
</div>
</section>
<!-- CONTACT -->
<section id="contact" class="c-section c-section--bg1 p-contact">
<div class="c-container">
<h2 class="c-title p-contact__title">CONTACT</h2>
<form action="" method="post" class="c-form p-contact__form">
<div class="p-contact__container">
<p class="p-contact__summary">お問い合わせフォーム</p>
<div class="c-form__wrap">
<label for="" class="c-form__label">メールアドレス:</label>
<input type="email" class="c-form__input">
</div>
<div class="c-form__wrap">
<label for="" class="c-form__label">電話番号:</label>
<input type="tel" class="c-form__input">
</div>
<div class="c-form__wrap">
<label for="" class="c-form__label">お問い合わせ内容:</label>
<textarea name="" id="" cols="30" rows="10" class="c-form__textarea" placeholder="ここにお問い合わせ内容を書けし"></textarea>
</div>
<!-- SUBMIT-->
<button class="c-button p-submit">
送信する
</button>
</div>
</form>
</div>
</section>
</main>
<footer class="l-footer">
<div class="p-footer">
<p class="p-footer__text">©️RA-MEN・MAJIN All Rights Reserved.</p>
</div>
</footer>
【ディレクトリ構成】
sass
├── Foundation
│ ├── _reset.scss
│ └── _variables.scss
├── Layouts
│ ├── _footer.scss
│ ├── _header.scss
│ └── _main.scss
├── Object
│ ├── component
│ │ ├── _button.scss
│ │ ├── _card.scss
│ │ ├── _container.scss
│ │ ├── _form.scss
│ │ ├── _image.scss
│ │ ├── _link.scss
│ │ ├── _section.scss
│ │ ├── _text.scss
│ │ └── _title.scss
│ ├── project
│ │ ├── _contact.scss
│ │ ├── _footer.scss
│ │ ├── _header.scss
│ │ ├── _hero.scss
│ │ ├── _menu.scss
│ │ ├── _nav.scss
│ │ ├── _news.scss
│ │ ├── _submit.scss
│ │ └── _toggle-button.scss
│ └── utility
└── app.scss
これでもちゃんと出来てるかは分からないんだよなぁ・・・。
まぁ。慣れだニャ
ってことで、「いやいや、これおかしいやろ。」って部分があればご教授くださいませ。