おう※2020/7/14現在:まだ作成途中ですが、概ね定義したつもりなので、公開します。
———————————
※この記事の元になった原稿です↑見づらいのでこの記事に記載することにします
※以下はあくまでも「私なりの」設計・提案であり、
原則、プロジェクトチーム固有の設計手法に完全に従います
————————————————————————————————
大まかなポイントを要約すると、
・FLOCSSのファイルディレクトリ構成を採用
・PRECSSの粒度を採用(FLOCSSのComponent=PRECSSのElementブロック)
→よって、「ComponentかProjectか迷う必要がない」
・命名規則は吉本式BEMとPRECSSを採用
・Modifireは積極的に上書きできる
・&(アンパサンド)は「Modifireと擬似要素のみ」使用可能 (Elementは&を使わない!)
・ネストは最大3階層まで!(Modifireのとき→2階層まで、@media(メディアクエリ)のとき→3階層まで)
・divの閉じタグコメントアウトはしない(主要なBlock要素に「見出しコメント」、わかりずらい時に「小さいコメント」)
他にもありますが、一番大事なポイントは上記です。
FLOCSSに関する規則
Objectの粒度に関して
LayoutとComponentの粒度が使いずらいので変更します
Layout
粒度を下げる(つまり、projectの一つ上の階層として使用する)
※FLOCSS公式では「headerやfooterなどに適用」とされています。
→「sectionやdivも適用」に変更
例)c-btnのレイアウトを変更するためのl-topBtnクラス
→これで、c-btnを他の場所でも汎用的に使うことができる
1 2 |
<div class="l-topBtn"> <div class="c-btn"> |
1 2 3 4 5 |
.l-topBtn { position: absolute; bottom: 0; left: 0; } |
追記:
※Layoutは「あまり多用しないように」します
→参考サイト:FLOCSSを扱いきれないあなたに贈る、スリムなCSS設計の話
Component
粒度を上げる(つまり、PRECSS公式のElement(el-)と同じにする)
※FLOCSSはprojectとcomponentの違いがわかりにくい
→「componentかprojectか」深く迷わなくていいようにする
3-2.エレメントモジュール
接頭辞:el_(elementの略)
ボタンやラベル、見出し等の最小単位のモジュールで、どこにでも埋め込むことが可能なモジュールです。
命名は極力汎用的なものを推奨します。これはどのようなコンテンツが入っても、名前と内容が乖離しないための措置です。
「極力汎用的な命名を」というのはBEMとは真逆の方向を向いている思想ですが、現実として、例えば全ての色に意味を持たせた命名は困難です。
Utility
粒度を上げる(「blockとblockの間隔」・「コンテンツ幅」を調整する)
例)「blockとblockの間隔」のためのクラス(u-middleM)など
1 2 3 4 5 6 7 8 |
<!-- imgCover --> <div class="c-imgCover u-middleM"> <div class="c-imgCover__txtBox -top"> <p class="c-imgCover__outlineLeft -marginNone">甘辛明太子のくせになる味</p> <p class="c-imgCover__outlineRight">お子様に大人気!</p> </div> <img src="./img/sp/jpg/p-secLinkProduct__img04.jpg" alt="" class="c-imgCover__img -height"> </div> |
※このクラスは、「blockとblockの間隔」を調節するためにあるのであって、
element・modifireなどに適用することはできない
※BlockにmarginをつけないことについてはBlockの基本原則へ
例)「コンテンツ幅」のためのクラス(u-contentWidth)など
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<!--------------------------------- secContactFF ----------------------------------> <section class="p-secContact"> <div class="u-contentWidth"> <div class="c-ttl"> <h1 class="c-ttl__h1">お問い合わせ</h1> </div> <p class="p-secContact__txt u-lh17">ご連絡の際は、 以下の電話番号・メールアドレスにてお問い合わせ下さい。 営業時間外の場合は対応できかねます事、ご了承下さい。</p> <ul class="p-secContact__ul"> <li class="p-secContact__li">営業曜日:月〜金(祝日除く)</li> <li class="p-secContact__li">営業時間:午前6時〜午後5時</li> <li class="p-secContact__li"><i class="fas fa-phone"></i> 090-3867-3422</li> <li class="p-secContact__li"><i class="fas fa-envelope"></i> fbf.baguette@gmail.com</li> </ul> </div> </section> |
BEMに関する規則
「シングルクラス・マルチクラス」について
・シングルクラスを基本とする
・例外は2つある
「ちょっとした変化や上書き」を指定するクラス(Modifire)
「BlockとBlockの間隔」を調整するためのクラス(Utility)
命名規則
・単語の連結に使う「-」は、「ローワーキャメルケース」に変更
1 |
<section class="l-secLinkHowto"> |
・Elementの連結は変更なし
※接頭語(-p など)があるため、「_」よりも「__」の方が見やすいと判断しました
NG
1 |
<h3 class="p-secAllergies_h3">イースト菌</h3> |
OK
1 |
<h3 class="p-secAllergies__h3">イースト菌</h3> |
・原則、使用する全要素にクラス名を付与する
※BEMの構造化のために必要
Blockの基本原則
・marginを原則つけない
※例外:絶対に変わることはないであろう、UI要素のmarginは許可する
例)見出し要素
1 2 3 |
<div class="c-ttl"> <h1 class="c-ttl__h1">お知らせ</h1> </div> |
1 2 3 4 5 6 |
.c-ttl { display: flex; align-items: center; justify-content: center; margin: pxtovw400px(40) auto $mgMiddle; } |
理由1:
BEMのBlockにmarginを持たせる
→汎用的に使用できなくなる
blockは一箇所だけでなく複数箇所で使われうるということを念頭に置くべきである.
理由2:
コンポーネントにmarginを持たせる
→変更に耐えられず、他のクラスを追加することになる場合がある
もちろん、例外は存在しますので、例えばLPとかでそのUIにはこのマージンしか絶対に存在しないみたいなことがあれば、直接書いても良いかと思います。
・代わりに以下の1つの方法でつける
1. FLOCSSのUtilityを使用
1 |
<section class="p-secContact u-mbLarge"> |
2. 「Layout専用のHTMLタグとSCSSクラス」を付与する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<del><code><section class="l-secContact"> <div class="p-secContact"> <div class="c-ttl"> <h1 class="c-ttl__h1">お問い合わせ</h1> </div> <p class="p-secAccess__txt u-lh17">ご連絡の際は、 以下の電話番号・メールアドレスにてお問い合わせ下さい。 営業時間外の場合は対応できかねます事、ご了承下さい。</p> <ul class="p-secContact__ul"> <li class="p-secContact__li">営業曜日:月〜金(祝日除く)</li> <li class="p-secContact__li">営業時間:午前6時〜午後5時</li> <li class="p-secContact__li"><i class="fas fa-phone"></i> 090-3867-3422</li> <li class="p-secContact__li"><i class="fas fa-envelope"></i> fbf.baguette@gmail.com</li> </ul> </div> </section></code></del> |
・modifireをつけない(Blockのみ)
NG
1 2 3 |
<div class="c-ttl -ttl"> <h1 class="c-ttl__h1">企業理念</h1> </div> |
OK
1 2 3 |
<div class="c-ttl"> <h1 class="c-ttl__h1 -c">企業理念</h1> </div> |
Blockの命名規則
・「よく使う」と思われる単語には、略称を定義する
何が言いたいかというと「header要素のクラス名はheaderで固定しませんか」ということ。
ただし、ページの中に出てくるheader要素は1つとは限りません。
サイトのヘッダー以外に、コンテンツ内にもヘッダーが必要になる場合があります。
サイトヘッダーのheader要素のクラス名は、先ほど決めたheaderで良いでしょう。
コンテンツヘッダーのクラス名も固定してしまいましょう。
私は、コンテンツヘッダーのクラス名はchと決めています。
このように、サイト内に必ずと言ってもいいほど出てくるBlockのクラス名は固定しましょう。
固定の命名方法
hd
→ヘッダー
top
→ヘッダー直下のセクションなど(ページトップにある大きなくくり)
sec
→セクションタグ(の直下のBlockを代わりに使っても良い)
btn
→ボタンなど
ft
→フッター
art
→アーティクル
tbl
→テーブルタグ
ttl
→タイトル(h1・h2・h3タグ等)
可変
それ以外全て
可変の命名方法
「複数単語」の命名方法
boxBlock
(box = sectionの中の囲い・divの小さい版)
ボックス+命名
tblBlock
テーブル+命名
linkBlock
アンカーリンク+命名
linkBox
リンクの囲い
ttlBlock
タイトル・見出しグループ+命名
secBlock
セクション+命名
outlineBlock
概要
→outline(概要)
explaBlock
説明
→explanationの略
「単一単語」の命名方法
rec
→recruit(採用)の略
募集要項など
link
アンカーリンク
news
ニュース
staff
スタッフ
access
アクセス
phil
企業理念、フィロソフィーphilosophy
FLOCSSのLayoutのBlock命名規則について
※粒度の小さい「Layout」のBlock命名は、なるべくわかりやすくする
(決まった命名方法はない。modifireのようなクラス名の付け方にする ※「-」などはもちろん使わない)
1 2 3 4 5 6 7 |
<!-- btn ----------------------------------> <div class="l-topBtn"> <div class="c-btn"> <div class="c-btn__inner"> <p class="c-btn__txt">開発秘話はこちら</p> |
Elementの基本原則
3-2.エレメントモジュール
接頭辞:el_(elementの略)
ボタンやラベル、見出し等の最小単位のモジュールで、どこにでも埋め込むことが可能なモジュールです。
命名は極力汎用的なものを推奨します。これはどのようなコンテンツが入っても、名前と内容が乖離しないための措置です。
「極力汎用的な命名を」というのはBEMとは真逆の方向を向いている思想ですが、現実として、例えば全ての色に意味を持たせた命名は困難です。
・クラス名を連結しない
NG
1 |
<p class="p-ft__inner__txt">フランスパンの贈り物で毎日を幸せに。</p> |
1 |
<p class="p-ft__txt">フランスパンの贈り物で毎日を幸せに。</p> |
Elementの命名規則
先ほどのBlockと同様に、Elementに関してもクラス名を固定します。
Elementは、要素(タグ)に依存するようなクラス名を設定するので、基本的には全て固定になります。
例えば、h2要素にクラスを設定する際、皆さんはどのようなクラス名を設定するでしょうか。
タグ名をそのまま命名する一覧
テキスト関連
span・h1~h5・a
画像関連
img・iframe
テーブル関連
tbody・thead・tr・td・th
svg関連
svg・line
固定の命名方法
「p要素」一覧
txt
テキスト
catch
キャッチコピー
copy
コピーライト(footerのコピーライトが基本)
expla
説明テキスト ※「explanation」の略
outline
概要テキスト(txtより目立たせたい場合等)
その他の一覧
list
リストを囲むタグ(ul要素)
item
リストアイテム(li要素)
cont
コンタクト(お問い合わせ)
dw
ドロワー
hov
マウスホバー
inner
インナー(1階層目のdiv)
triangle
(SVG等の)三角の図形
arrow
(SVG等の)矢印
border
(SVGのみ)ボーダー
bg
(SVGのみ)背景
・クラス名は最後に連番(もしくは、Right Left)をつける
※原則、つける順番は時計回り(つまり、右→左 上→下)
※1つめはつけない
シリーズを形成する場合
類似しているものはなるべく意味のある、または目的に即した命名を推奨しますが、ときに名前の付け分けが難しい場合もあるでしょう。そのような際は連番を付けて管理することも許容します。ただしその場合、1つ目のものには連番を付けません。
これは、仮に「ひとつ目にすべて連番を付ける」としてしまうと、後からシリーズを形成するようになった際、ひとつ目のものに連番を付け直す手間が発生してしまうからです。
例)クラス名が重複した→クラスを再利用できない(liタグなどではない)→連番をつける
1 2 3 |
<p class="p-secAccess__txt">当店は「イートインスペース」も<br>ご用意しております。焼きたてをそのままその場でゆっくりお召し上がれますので、ぜひご利用下さいませ。</p> <p class="p-secAccess__txt2">※スペースには限りがあります。他のお客様にもご利用頂けるように<span class="p-secAccess__span">「ご利用制限時間(20分)」</span>があります。</p> |
※もし「4」以上の数字が並ぶなら
→「極力、3つ以内で共通化するよう工夫する」 or 「クラス名の命名規則を更新する」 or 「Modifireを検討する」
→万能薬はないので、その都度考えていく方向性を持つ
Modifireの基本原則
・「-mg」や「-pd」など、「修正内容が極力わかりやすいクラス名」をつける
※単語の略称は「Emmetのショートカット名のみ」を使用
例)mg→margin mgb→margin-bottom →padding→pd
3-3.モディファイア
命名規則:基となるクラス名__モディファイア名
既に何度か言及していますが、あしらいが変わる
大きさが変わる
一定の規則に従って振る舞いが変わる(カラム等)
などの場合はモディファイアによる上書きをPRECSSでは推奨
※数字はつけないようにしたい(汎用的に使うので)でも、つけてもOK。
※違いを表す時は、以下のようにつける(これは極端な例であり、ここまでつけるのは望ましくない。ロゴだから許容。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<!--------------------------------- footer ----------------------------------> <footer> <div class="p-ft"> <a class="c-logo" href="./index.html"> <div class="c-logo__inner -mg"> <img class="c-logo__img -wd" src="./img/sp/png/p-logo__img01.png" alt="" srcset=""> <h1 class="c-logo__h1 -fs -c">フランスパン専門店</h1> <h2 class="c-logo__h2 -fs -c"> <span class="c-logo__span">F</span>rance <span class="c-logo__span">B</span>ekery <span class="c-logo__span">F</span>actory</h2> </div> <p class="p-ft__txt">フランスパンの贈り物で毎日を幸せに。</p> <p class="p-ft__copy">©2020 フランスパン専門店 FRANCE BEKERY FACTORY</p> </a> </div> </footer> |
・modifireは上書き可能であることから、「ちょっとした違いを修正するクラス」として扱うことができます。
例)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<!--------------------------------- secHowto ----------------------------------> <div class="p-secHowtoEat u-veryBigM"> <div class="c-ttl"> <h1 class="c-ttl__h1">パンの保存方法</h1> </div> <div class="u-contentWidth"> <h3 class="p-secHowto__h3">・おすすめの保存方法</h3> <li class="p-secHowto__li">1.フランスパンを食べやすいサイズに切る</li> <li class="p-secHowto__li">2.ラップで包む</li> <li class="p-secHowto__li -margin">3.冷凍庫へ保存(1〜2週間以内に食べる)</li> <h3 class="p-secHowto__h3">・自然解凍の場合</h3> <li class="p-secHowto__li">1.ラップに包んだまま、解凍をお待ち下さい</li> <li class="p-secHowto__li">解凍時間の目安:</li> <li class="p-secHowto__li">厚み 5cm → 30分〜 厚み10cm→ 1時間〜</li> </div> </div> |
・modifierで使用した単語が独立して存在するのはNG!!
1 2 |
<div class="-wd"> </div> |
※BlockにmodifireをつけないことについてはBlockの基本原則へ
Modifireの命名規則
・「Chainable BEM modifiers」を使用します
→つまり、「&(アンパサンド)」と「-」を使う
Chainable BEM modifiersの書き方
BEMのModiferを表すクラスセレクタを、接頭辞-に続けて名前空間(key)、値(value)のセットで書きます。
※BlockにModifireをつけてはならない→Blockの基本原則へ
※「ネスト」して記載しなければならない(SCSSに記述する際)
※あくまで一例である(他にも活用方法は考えられうる 例:「HTMLタグにModifireクラスだけをつけてラップする」等 参考サイト)
※Modifireは単独で使用してはならない(グローバルスコープを避けるため→「&」と「-」を使う)
例)
1 |
<p class="p-testBlock__inner <span style="color: #ff0000;"><strong>-testModifire</strong></span>">テストです</p> |
1 2 3 4 5 6 7 8 9 |
.p-testBlock { width: 100%; } .p-testBlock__inner { width: 50%; .&-testModifire { width: 30%; } } |
このModifireの書き方は、FLOCSSの谷さんの書籍でも紹介されていました↓
HTML・SCSSに関する規則
基本原則は Google HTML/CSS Style Guide
※「クラス名は『-』で区切る」という項目以外
コメントアウトについて
divの閉じタグにコメントアウトはしません。
「主要なBlock要素」の前に、
「1番大きい見出しコメント」を入れます。
(つまり、FLOCSSでいうと、「p-」のみ)
1 2 3 4 5 6 |
<!--------------------------------- hd ----------------------------------> <header class="l-hd"> |
「主要なBlock要素」の中に「主要なBlock要素」がある場合、
「2番目に大きい見出しコメント」を使います。
(つまり、「p-hd」の中に「p-hdDrawer」があった場合など)
1 2 3 4 |
<!-- hdDrawer ----------------------------------> <div class="p-hdDrawer"> |
「構造が少し複雑になっていて、わかりずらい」場合に「小さいコメント」を使います。
1 2 |
<-- checkbox (display:none) --> <input class="p-hdDrawer__checkbox" id="drawerCheckbox" type="checkbox"> |
HTMLに関する規則
IDを極力使わない!
※「ドロワー」等を作成する際に、「ページ内リンク」のために使用するのは許可
※idの命名規則は今回のBEMの命名方法には従わない
1 |
<input class="p-hdDrawer__checkbox" id="drawerCheckbox" type="checkbox"> |
画像名はクラス名(Block__img)
※画像名の後に「01」などの連番をつけるのが好ましい
1 |
<img src="./img/sp/jpg/p-top__img01.jpg" class="p-top__img"> |
SCSSに関する規則
@includeについて
@include
理由:必要以上にコードが長くなる大きな原因になる
@extendに関して
・@extendは%(プレースホルダー)使用時のみ使う(原則として)
・同じ.scssファイル内のスコープでのみ、%(プレースホルダー)を使う
※グローバルなスコープで使用すべきでない
・@extendはプロパティの一番最後に記述する(つまり、上書き禁止)
※csscomb(シーエスエスコーム)で自動整形する
※極力、上書きをするような記述を避ける(混乱の防止)
ネストに関して
・ネストは原則2階層まで
・&(アンパサンド)以外はネスト禁止!
※Modifire・擬似要素の場合→2階層まで許可
※@media(メディアクエリ)の場合→3階層まで許可
1 2 3 4 5 6 7 8 9 10 |
.p-tblAllergy__th { height: 62px; @extend %p-tblAllergy__th; &.-wd { width: 50%; } &.-bgc2 { background-color: $base; } } |
マージンに関して
・Layoutに使用するmarginは一方向(bottomにする or topにする)
1 |
margin-bottom: 30px; |
1 |
margin-top: 30px; |
フォルダ構造(ディレクトリ構造)に関する規則
原則、FLOCSSのルールに準ずる
要約
・Block単位で「SCSSファイル(_block.scss)」を作成
→「style.scss」で@importする(つまり、gulpのglob)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
/*--------------------------------- foundation ---------------------------------*/ @import 'foundation/_reset.scss'; @import 'foundation/_function.scss'; @import 'foundation/_variables.scss'; @import 'foundation/_base.scss'; /*--------------------------------- layout ---------------------------------*/ @import 'layout/**'; /*--------------------------------- object ---------------------------------*/ /* component ---------------------------------*/ @import 'object/component/**'; /* project ---------------------------------*/ @import 'object/project/**'; /* utility ---------------------------------*/ @import 'object/utility/**'; |
※現在、「Dart Sass」のアップデートにより、@importが非推奨に変わりつつあります。
今後、変更する予定です。
→参考:Sassを@importから@useに置き換えるための手引き
base.scssについて
baseに記載するのは「必要最低限」でなければならない。
原則として、「font-size」と「color」のみとする。
※必要に応じて、「font-weight:bold」や「display:block」など、
「必要最低限」と思われる項目が増えたら追記可能
例)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
/*--------------------------------- base ---------------------------------*/ svg { color: $third; font-weight: bold; font-size: $veryBigF; } h1 { color: $base; font-weight: bold; font-size: $bigF; } h2 { color: $base; font-weight: bold; font-size: $smallF; } h3 { color: $base; font-weight: bold; font-size: $smallF; } p { color: $base; font-size: $smallF; } span { font-size: $smallF; } th, td { color: $base; font-size: $smallF; } th { vertical-align: top; } img { display: block; } li { color: $base; font-size: $bigF; } |