CSS設計完全ガイド メモ

この記事は約27分で読めます。
  1. CSS設計の実践と8つのポイント
    1. 1. 特性に応じてCSSを分類する
      1. 分類の例
      2. ポイント・メモ
    2. 2. HTMLとスタイリングが疎結合である
    3. 3. 影響範囲がみだりに広すぎない
      1. ポイント
      2. スコープを絞る場合
    4. 4. 特定のコンテキストにみだりに依存しない
      1. コンテキストに依存していることの問題
    5. 5. 詳細度がみだりに高くない
      1. 詳細度が高いCSSとは
      2. 詳細度を低くするためのコツ
    6. 6. クラス名から影響範囲が想像できる
      1. ポイント
      2. どうすればわかるか
    7. 7. クラス名から見た目・機能・役割が想像できる
      1. クラス名から見た目・機能・役割が想像できない例
      2. 見た目・機能・役割が想像できる例
      3. わかりやすいモジュール名を
      4. クラス名をつけるポイント
    8. 8. 拡張しやすい
      1. 「拡張しやすさ」とは
      2. シングルクラスとマルチクラス
      3. モディファイアをつけるコツ
  2. モジュールの粒度について
    1. モジュール粒度の指針
      1. カラムを形成するパターンの場合のおすすめ
  3. BEM
    1. 基本規則
    2. Blockの基本
      1. Blockの命名規則
    3. Elementの基本
      1. Elementの命名規則
      2. 注意事項
    4. Modifierの基本
      1. Modifierの命名規則
      2. 「それがどうであるか」のパターン
      3. Modifierのタイプ
      4. Modifierの注意点
      5. Modifier名は省略せずに書く
    5. Mix
      1. Mixを使うメリット
      2. Mixを使うかModifierを使うか
      3. グループセレクターの代わりにMixを使用する
      4. Mixでは対処できない場合
    6. BEMのその他の命名規則
      1. ハイフンが二つのスタイル
      2. キャメルケースのスタイル
      3. リアクトスタイル
      4. ネームスペースのないスタイル
      5. MindBEMding
    7. BEMを成功させるコツ
  4. PRECSS
    1. 基本的な指針
      1. 命名規則
      2. 汎用的に使用可能な単語
      3. 単語を省略する場合
      4. シリーズを形成する場合(同じ要素が連続で続く場合)
    2. ベースグループ
    3. レイアウトグループ
    4. モジュールグループ
      1. ブロックモジュール
      2. エレメントモジュール
      3. モディファイア
    5. ヘルパーグループ
      1. ヘルパーの拡張グループの作成
      2. モジュールの上下間の余白を実装するヘルペークラス
    6. ユニークグループ
    7. プログラムグループ
    8. オリジナルグループ

CSS設計の実践と8つのポイント

  1. 特製に応じてCSSを分類する
  2. コンテンツとスタイリングが疎結合である
  3. 影響範囲がみだりに広すぎない
  4. 特定のコンテキストにみだりに依存していない
  5. 小サイドがみだりに高くない
  6. クラス名から影響範囲が想像できる
  7. 拡張しやすい

1. 特性に応じてCSSを分類する

分類の例

  • リセットCSSや「リンクテキストは赤にする」など、サイト全体の下地となるベーススタイルを「ベースグループ」とみなす
  • ヘッダーやフッター、コンテンツエリアを京成するスタイリングを「レイアウトグループ」とみなす
  • モジュールに関わるCSSを「モジュールグループ」とみなす

ポイント・メモ

  • 「サイト内共通であるべきもの」「サイトのベースとなってほしいもの」もベースグループに該当
  • モジュール自体にはレイアウトに関する指定は基本的に行わない
    • 具体的には
    • position(static, relativeを除く)
    • z-index
    • top/right/bottom/left
    • float
    • width
    • margin(margin-bottom,top程度ならモジュールにつけてもok)

2. HTMLとスタイリングが疎結合である

☆HTMLの要素名をなるべくセレクターとして使用しないようにするのがベストプラクティス

  • ただし、ある程度範囲が絞られている要素については、HTMLの要素名をそのまま使用しても差し支えない
    • 例)imageWrapper img など
  • ↑しかし、 div要素p要素span要素はモジュール内でよく使用されるので、これらについてはきちんとクラス名を設計しておくと、後々モジュールを回収する必要が生じた際も困らない
  • 属性セレクターの特定の値を使用してスタイリングすることも、基本的には避けるべき
    • 例)a[href="https://google.co.jp]{ color: red; } (このurlなら赤文字にする)
    • これだと、赤文字にしたいURLを増やすたびに記述が増えて不便

3. 影響範囲がみだりに広すぎない

ポイント

  • まず、スコープを絞れないか検討する
  • 影響範囲の広いCSSに含めるスタイルングは、なるべく最小限に留める

のいずれか

スコープを絞る場合

  • なるべく直近の親要素までセレクターに含めて記述する
  • 子孫セレクターではなく子セレクターが使用できないか検討すること
  • ただ、疎結合を避けるために、それ用のクラスを作ってスタイリングするのが一番いいことが多い

4. 特定のコンテキストにみだりに依存しない

コンテキストとは「場所や状況」

コンテキストに依存していることの問題

☆コンテキストが変わったとたん、コードが動かなくなる

  • モジュールには前提として「サイト内全体でどこでも使いまわしたい」意図があるので、特定のid内で適用されないようなコードは避ける

5. 詳細度がみだりに高くない

詳細度が高いCSSとは

  • セレクターの見通しが悪くなりがち
  • 他の要素(親要素など)に対する依存が多くなりがち
  • 上書きが難しい
  • ゆえにメンテナンスの工数が増える

詳細度を低くするためのコツ

☆セレクターはクラスセレクターを使用することが基本

idセレクターをスタイリング目的に使用するメリットはあまりない

6. クラス名から影響範囲が想像できる

ポイント

☆「影響範囲が広いか狭いか、クラス名からきちんとわかるようにする」ことが大事

どうすればわかるか

☆HTMLだけ見て予想した影響範囲が、CSSでのスタイリングと一致しているかどうか

  • class="title"など、タイトルとしてどこでも使えそうなクラス名にしない
  • モジュールの子要素には、モジュールのルート要素のクラス名を継承させる
    • ルート要素とは、モジュールの起点となる(一番上の親)要素のこと
    • 例)title→ bl_module_title
  • 代わりに、外でも使える汎用的なクラスならtitleのままにしとけば見分けつく

7. クラス名から見た目・機能・役割が想像できる

クラス名から見た目・機能・役割が想像できない例

  • title1
  • title2
  • title3

どのタイトルがどのような役割を果たすのか、全く想像がつかない

見た目・機能・役割が想像できる例

  • page-title
  • section-title
  • sub-title

わかりやすいモジュール名を

  • bl_card
  • bl_media
  • bl_list

クラス名をつけるポイント

  • 名前から見た目・機能・役割が想像できる
  • 具体性と汎用性のバランスがとれている
「具体性と汎用性のバランスが取れている」とは
  • 特定のページや、特定の部分にかかわらず、Webサイト内のどこからでもモジュールを使えることがわかる名前になっているか
  • これがあまりにも具体的な名前だと、「ここでしか使えないのかな」となる
  • 一般的な呼称を使うことが大事
    • media, accordion, sliderなど
    • ない場合は見た目から着想を得た命名にする

8. 拡張しやすい

「拡張しやすさ」とは

  • 拡張しやすいクラス設計を行う(マルチクラス設計を採用する
  • 拡張用として作成したクラスは、機能・役割に応じて適切な粒度・影響範囲を保つ

シングルクラスとマルチクラス

  • あるモジュールの、スタイルが少しだけ異なるバリエーションを作成する
  • あるいは状態の変化を実現する

のに、対応する方法

シングルクラス設計とは

HTMLにつけるモジュールのクラスを常に一つに絞る方法

HTML

<a class="el_btnTheme" href="#">標準ボタン</a>
<a class="el_btnWarning" href="#">色違いボタン</a>

上のようにスタイルの違うボタンクラスを別々に用意して両方1から作る

問題は、CSSの方で多くのコードが重複し、バリエーションが増えるほどコードが肥大化すること。柔軟性も低い。

マルチクラス設計とは

モジュールに関するクラスを見た目や機能・役割に応じて適宜分割し、HTMLに複数つけることを許容する設計方法

HTML

<a class="el_btn" href="#">標準ボタン</a>
<a class="el_btn hp_warning" href="#">色違いボタン</a>

例えば、ボタンのボックスシャドウがないパターンや、シャドウあり、文字色が反転したパターンはほしいとなったら、

HTML

<a class="el_btn" href="#">標準ボタン</a>
<a class="el_btn hp_warning" href="#">色違いボタン</a>
<a class="el_btn hp_bxShNone" href="#">色違いボタン</a>
<a class="el_btn hp_bxShNone hp_textWhite" href="#">色違いボタン</a>

のようにかけて、これだとCSSのシンプルさも保てる(ただし、HTMLは複雑になりがち)

また、hp_warningなど既存のクラスに対して何か変更を加える、上書きするためのクラスを「モディファイア」と呼ぶ

また、主にひとつのプロパティを変更するだけのクラスを「ヘルパークラス」と呼ぶ

モディファイアをつけるコツ

モディファイアをつける箇所(作成するモディファイアの数)は、変更を加える要素数と一致させるのではなく、提供する機能(または役割)ひとつにつきひとつのモディファイアを作成する

例)mediaモジュール(左に画像、右にタイトルとサブタイトル)の画像と文の位置を反転させるとき、画像・タイトル・サブタイトルごとにクラスを設けるのではなく、これらの親要素に1つのクラス(bl_media__revなど)を設置し、cssbl_media__rev .bl_media_title{ }のように書く。

(これでモディファイアをひとつに絞る。htmlにクラスを1個追加するだけで済む)

※変更が画像に枠線をつけるなど1要素で済む場合は、わざわざ親要素にモディファイアつけない

モジュールの粒度について

モジュールとは、「使い回すことを前提としたひとかたまりの単位」

粒度とは、大きさ、単位のこと

モジュール粒度の指針

※絶対な回答はない

が、以下の2つの単位を強く意識しておくこと

最小モジュールボタンやラベル、タイトルなどのシンプルな要素
複合モジュールいくつかの子要素をもつ、ひとかたまりの要素

カラムを形成するパターンの場合のおすすめ

☆カラムを形成する場合は、繰り返し登場するモジュールと、カラムを形成するためのモジュールを別のものとして考えること

例)3つカードモジュールが入ってるカラム
→「3つのカードを入れるモジュール」、「それぞれ個別のカードのモジュール」にわける

BEM

モジュールを

  • Block
  • Element
  • Modifier

という単位で分解。また、これらまとめて「BEMエンティティ」

基本規則

  • 要素型セレクターやIDセレクターの使用は非推奨→クラスセレクターの使用が基本
    • 詳細度を均一にし、ModifierやMixしやすくするため
  • HTMLに複数のクラスがついている場合でも、詳細度は均一にする
    • × .button.button_theme_caution{...}
    • ○ .button_theme_caution{...}
  • クラス名は半角英数字の小文字で、複数の単語はハイフンでつなぐ

Blockの基本

Blockの定義=「特定のコンテキストに依存していない、どこでも使いまわせるパーツ」

  • Block自体にレイアウトに関するスタイリングをしてはいけない
    • (周りに影響を及ぼすpositionやfloat, marginなど)
  • レイアウトに関する指定が必要な場合は、Mixで実装

Blockの命名規則

命名規則
単語が一つの場合blockmenu
単語が複数の場合block-nameglobal-nav
  • クラス名は「それがなんなのか」を表すようにする
    • 見た目でつけるのはダメ
    • 「何であるか」「何のために使用されるのか」を表す
    • × red-text/ ○ error

Elementの基本

Elementの定義=「Blockを構成し、Blockの外では独立して使用できないもの」

Elementの命名規則

Blockの名前を継承し、アンダースコアふたつを記述した後にElementの名前をつける

 命名規則
単語がひとつの場合block__elementmenu__item
単語は複数の場合block-name__element-nameglobal-nav__link-item
  • Blockと同じく、「それが何なのか」を表す単語を使用する

注意事項

  • Elementの中にElementがネストされた命名は非推奨(Block内の構造が変わったときに反映されない可能性)
<!-- × a要素が menu__link ではなく、 menu__item__linkと、link がitemの中にネストされたクラス名になっている -->
<li class="menu__item"><a class="menu__item__link" helf="#">...

menu__item__linkではなく。menu__linkとするのが好ましい

  • 同様に、CSSにおけるセレクターについても子(孫)セレクターは使用せず、詳細度を均一に保つこと
  • ElementにElementがネストされた”クラス名”があかんのであって、Elementの中にElementが入っているのはいくらでもOK
  • Elementは必ずブロックの中で配置する
  • Elementはなくてもよい(Blockが必ずしもElementを持つ必要はない)
  • Blockの中にBlockをネストするのもOK
  • Elementの数が多く複雑なら、ElementをBlockに昇格させるのもOK(コードがスッキリするし、どこからでも利用できるようになる)

Modifierの基本

Modifierの定義=「BlockもしくはElementの見た目や状態、振る舞いを定義するもの」

また、BlockもしくはElementに対するオプション要素という位置づけ(よって必ずしも必要なわけではない)

  • Modifierを単独で使用することはできない
  • 必ずBlockかエレメントのクラス名がある状態で、二つ目以降のクラス名としてModifierをつける
    • 例)class="btn button_size_s"
  • アクティブ表示(activedなど)だけでなく、レイアウトをがらっと変えるのにも使える
  • ひとつのBlockに複数のModifierつけるのOK(ただし、相反するのは×)

Modifierの命名規則

Modifierを適用したいBlockまたはElementの名前を継承し、アンダースコアひとつを記述したあとにModifierの名前をつける(単語が複数ならハイフン)

 命名規則
単語がひとつの場合block__element_modifiermenu__item_activated
単語は複数の場合block-name__element-name_modifier-nameglobal-nav__link-item_activated-and-focused
  • ただしModifierが「キーと値の組み合わせ」の場合、キーと値を_で区切るスネークケースを利用(ハイフンではない)
    • menu__item_text-large x →正 menu__item_text_large o
  • Modifierの命名は「それがどうであるか」を重視
    • (Block、Elementは「それが何であるか」を重視)

「それがどうであるか」のパターン

パターン説明
見た目どんなサイズか?どの色か?どのテーマに属するか?などsize_s,
theme_caution
状態他のBlock(or Element)と比べて何が違うか?などdisabled, focused,
actived
振る舞いそれがどのように振る舞うか?などdirections_right-to-left,
(文章は右から左に)
position_bottom-right
(ポジションは右下)

Modifierのタイプ

  • 真偽値
  • キーと値のペア

☆真偽値のModifier=概ね一語で完結。状態に関する指定が多い。

☆キーと値のペア=主に見た目と振る舞いに関する指定の際に使用される。(そのBlockの「何」(キー)が「どう」(値)であるか)

Modifierの注意点

  • Modifier名とスタイルコントロールの責任範囲をはっきるさせる
    • btn_redというModifierでサイズを指定すると矛盾や衝突が起きやすい
    • サイズなら、サイズ用のModifierをつくる
    • また、btn_redだけどラベルは白みたいなことがあるので、読み取れるようにbtn_cautionのようにする
  • ひとつのModifierで複数の要素を変えられる
    • ひとつのModifierから子(孫)セレクターを使用して変更する
    • 詳細度が高くならないよう、ネストは最小限にとどめる

Modifier名は省略せずに書く

Modifierを省略してはいけない理由

  • 名前が衝突することによりModifierの詳細度がます
    • size_sという名前だと、imgでもbtnでも使ってしまい衝突
    • 結果、.user_img .size_sという指定の仕方になる
  • どのクラスに対するModifierか見分けがつかない
    • Mixしてて、.img と .btn__img がある要素に、size_sだと、どちらに対する指定かHtmlからわからない
  • コードが検索しづらい

Mix

Mixの定義=「ひとつのHTML要素に、役割の異なる複数のクラスがついている状態」

Mixを行うことにより、以下のことができる

  • コードを複製することなく、複数のBEMエンティティの振る舞いやスタイルを組み合わせる
  • 既存のBEMエンティティから、新しいモジュールを作成する

例えば、

<header class="head">
     <div class="menu head__menu">...</div>
     <div class="logo head__logo">...</div>
     <div class="search head__search">...</div>
     ...
</header>

上記の、head__menuなどがMix(headクラスとmenuクラスのミックス)。子セレクターを使用した .head .logo { ... } で指定する方法を使わない。このhead__menuなどにレイアウトのスタイリングする

Mixを使うメリット

  • 詳細度をなるべく高めないのに便利
  • Blockの再利用性を高められる
  • Blockの独立性が保たれる
    • ロゴのクラス名がlogo→company-logoになった場合、子セレクターのレイアウト指定だと、機能しなくなるが、Mixならhead__logoがついたままなので変わらず機能する
    • →ヘッダーBlockとロゴブロックは「お互いに必要以上に依存し」なくなる

また、上の例だと、BlockとElementのMixだったが、BlockとBlock、ElementとElementのMixもできる。

Mixを使うかModifierを使うか

Mixを使用する場合positionやmarginなど、「レイアウト(他の要素との位置関係を調整する)に絡む」変更の場合
Modifierを使用する場合レイアウトではなく、そのBlock(またはElement)内で完結する変更の場合
Mixの例).logo と .search の間に余白を開けたい
Modifierの例).logoに枠線をつけたい

グループセレクターの代わりにMixを使用する

ヘッダーとフッターのテキストのスタイルが同様で、グループセレクターを使った場合

<header class="header">...</header>    
<footer class="footer">...</footer>
.header,
.footer {
    font-family: serif;
    font-size: 14px;
    color: #000;
}

だと、途中からヘッダーだけフォントサイズを大きくしたいと思ってもフッターも連動する

Mixにした場合

<header class="header text">...</header>    
<footer class="footer text">...</footer>
/* 文字に関する指定は text Blockが担うようになった */
.text {
    font-family: serif;
    font-size: 14px;
    color: #000;
}
/* headerだけ個別の指定が可能になった */
.header {
    font-size: 16px;
}

※上記の場合、CSSのルールセットの順番に注意して書く(.headerを下に書くのは違和感=>非推奨)

  1. グループセレクタの代わりにMixを使うか(著者非推奨)
  2. そもそも最初からグループセレクターを使わず、無理にMixも行わないか
  3. Mixをするのであれば、上書きはMixをしたBlockのModifierで行うか

2の場合、header , footer ごとにそれぞれCSSの記述をする

3の場合、

<header class="header text text_size_l">...</header>    
<footer class="footer text">...</footer>

と、text_size_l クラスを作り、.textのあとにCSS記述(順番管理が楽)

Mixでは対処できない場合

  1. スタイルが衝突する場合や、見た目的にボックスの中に配置したい場合は、Elementを新たに作り、その中に他のBlockをネストする
  2. クライアントが更新する場合などどうしてもMixを使えない場合は、コンテキストに依存するスタイリングを行う

BEMのその他の命名規則

まず、いままでの命名規則のまとめ

  • 英数字の小文字
  • Element と Modifier はそれぞれBlockの名前を継承する
  • それぞれの区切りの中に複数の単語がある場合はハイフンひとつ
  • Block と Element の区切りは、アンダースコアふたつ
  • Modifier のキーの区切りは、アンダースコアひとつ
  • Modifier の値の区切りもアンダースコアひとつ

☆ただし、Block・Element・Modifier・単語のそれぞれがきちんと区別できれば命名規則をカスタマイズしても良い。

ハイフンが二つのスタイル

block-name__elem-name--mod-name--mod-val

(ブロック名)__(エレメント名)--(モディファイアキー)--(モディファイア値)

※HTMLのコメント内に--いれるとエラーでるので注意

キャメルケースのスタイル

blockName__elemName_modName_modVal

リアクトスタイル

BlockName-ElemName_modName_modVal

  • Block と Element はアッパーキャメルケース
  • Modifier はローワーキャメルケース
  • Block と Element の区切りはハイフン一つ

ネームスペースのないスタイル

_disabled

これはModifierに限定される規則。(非推奨)

MindBEMding

block-name__elem-name--mod-name (--val)

  • Modifier の区切りはハイフンふたつ
  • Modifier のキーは省略可能
    • 本来の button_size_s から button--s に(シンプルだが想像つく)

BEMを成功させるコツ

  • DOMモデルではなく、Block という単位をベースに考える
  • IDセレクターと要素型セレクターは使用しないようにする
  • 子(孫)セレクターでネストされるセレクターの数は、なるべく少なくする
  • 名前の衝突を避けるために、またコードから情報が読み取れるように、命名規則にきちんと従ったクラス名をつける
  • Block なのか、Element なのか、Modifier なのかを常に意識する
  • Block または Element で変更が頻繁に起こりそうなスタイルのプロパティは、Modifierに移しておく
  • Mixを積極的に使用する
  • 管理性を高めるために、Block はひとつひとつがなるべく小さくなるように分割する
  • Block を積極的に再利用する

PRECSS

prefixed CSS (接頭辞付きのCSS)
すべてのクラス名に役割に応じた2文字の接頭辞をつけるのが特徴

CSSの役割に応じた6つのグループ

  1. ベース
  2. レイアウト
  3. モジュール
    1. ブロックモジュール
    2. エレメントモジュール
  4. ヘルパー
  5. ユニーク
  6. プログラム

なお、独自のグループを作ることもOK(2文字の接頭辞を新たに作る)

基本的な指針

PRECSSで推奨する記法

基本的にGoogle HTML/CSS Style Guide、Principle of writing consistent, idiomatic CSSに則る

Google HTML/CSS Style Guide
GitHub - necolas/idiomatic-css: Principles of writing consistent, idiomatic CSS.
Principlesofwritingconsistent,idiomaticCSS.Contributetonecolas/idiomatic-cssdevelopmentbycreatinganaccountonGitHub.

命名規則

  1. 各グループにおける2文字の接頭辞の後は、アンダースコアを使用し、その後にクラス名を続ける。また、接頭辞のあとだけでなく、各モジュールの子要素の命名にもアンダースコアを使用

つまり、PRECSSでは、アンダースコアは構造的な階層を表す

  1. ひとつの階層に複数の単語を含んでいる場合は、ローワーキャメルケースを使用
    • 例)bl_halfMedia
  2. 基本的にIDセレクターは使用しない(詳細度の管理が複雑になるから)
  1. 各モジュールの子要素は、基本的に親の名前のみを継承し、アンダースコアの後に子要素の名前を続ける
    • ただし、以下の場合はネストされた子要素の直近の親要素の名前含んでOK
      • 親子関係を意図を持って明確に定義したい場合
      • モジュールが大きいため、子要素の名前の重複を避けたい場合

4の例

<!-- それぞれの子要素はネストの階層にかかわらず「bl_halfMedia」のみを継承している -->

<div class="bl_halfMedia">
    <img class="bl_halfMedia" src="#" alt="" >
    <div class="bl_halfMedia_desc">
        <h3 class="bl_halfMedia_ttl">タイトルが入ります</h3>
        <p class="bl_halfMedia_tex">説明文</p>
    </div>
</div>

汎用的に使用可能な単語

  • _wrapper
  • _inner
  • _header
  • _body
  • _footer

bl_halfMedia_wrapper>bl_halfMedid など

単語を省略する場合

PRECSSでは、意味や可読性が損なわれない限り、単語を省略することを推奨

指針は、Google HTML/CSS Style Guide 「4.1.3 ID and Class Name Style」に基づく
https://google.github.io/styleguide/htmlcssguide.html#ID_and_Class_Name_Style

また、2語以上でひとつのまとまりを表す語群は、それぞれの頭文字の大文字のみで表現することも推奨
例)mainVisal → MV

よく使われる省略後

省略前省略後
category(ies)cat(s)
columncol
content(s)cont(s)
levellv
versionv
sectionsect
descriptiondesc
buttonbtn
clerafixcf
imageimg
numbernum
titletil
texttxt
leftl
rightr
smallsm
mediummd
largelg
reverserev

シリーズを形成する場合(同じ要素が連続で続く場合)

連番(item1, item2,,, )をつけてOK

ただし、ひとつ目のものには連番をつけない(× item1, item2... →o item, item2, ...)

ベースグループ

ベースグループは、リセットCSSのルールセットや、その他プロジェクトにおいて標準となるスタイリングを行う。
例)font-familyやリンクの下線、imgのmax-widthなど

また、PRECSSでは、特定のスコープ内における限定的なベーススタイルの適用も許容
例)

/* ヘッダー内のリンクはすべて白色だが、フッター内は青色に統一したい場合  */
.ly_header a {
    color: white;
}
.ly_footer a {
    color: blue;
}

ただし、詳細度が高くなるので、使用には注意

レイアウトグループ

接頭辞 : ly_

  • ヘッダー、ボディエリア、メインエリア、サイドエリア、フッター等の大きなレイアウトを形成する要素に使用
  • 原則としてレイアウトに関するスタイリング(width, margin, padding, floatなど)しか行わない
    • あくまでコンテンツが入る「枠」を定義するだけ (コンテンツはモジュールグループ)
  • ただし、「ヘッダーの背景色は黒」など「枠」と「あしらい」の粒度が一致している場合は、必要に応じてレイアウト以外のスタイリングを行うことも許容

モジュールグループ

PRECSSでは再利用性の高いコードをモジュールと呼び管理する。

モジュールは大きさによって

  • ブロックモジュール
  • エレメントモジュール

の2つの粒度に分けて定義する

ブロックモジュール

接頭辞: bl_

  • ブロックモジュールはそのモジュール特有のいくつかの子要素を持ち、またエレメントモジュールや、他のブロックモジュールを含むことができる
  • それら複数の子要素やエレメントモジュールをひとつの塊としてまとめ、さまざまなページで利用できるようにすることがブロックモジュールの基本的な考え方
  • 詳細度は基本的にクラスセレクターひとつの均一な状態を保つようにするが、BEMほど厳格ではない
    • .bl_card_imgWrapper img のようにスコープが絞られていれば子(孫)セレもOK
  • ブロックモジュールにレイアウトに関するスタイリングは行わない
    • ブロックの幅はなるべく初期地のまま(多くは親要素いっぱい)
    • レイアウトの指定が必要な場合は、ブロックモジュールが使用されるコンテキストのElementとしてStyle適用
    • 例)親要素(class="bl_3colCardUnit), 子要素(class="bl_card bl_3colCardUnit_item")
      • bl_3colCardUnit_itemエレメントを追加し、bl_cardではなくそこにレイアウトを適用
      • ブロックモジュール(.bl_card)が使用されるコンテキスト(= .bl_3colCardUnit)のElement(= bl_3colUnit_item)としてスタイルを適用する
      • これによって、bl_cardはとても再利用性が高くなる
    • また、上記の例程度なら、子セレクターとしてスタイリングすることも許容
      • 例).bl_3colCardUnit > .bl_card { ... } で指定
  • 例外として、”上下間の余白” の実装に関しては、以下のどちらも許容している
    • モジュールに直接指定するか
    • モジュールには設定せず、逐一ヘルパークラスをHTML側につける
  • 命名に役立つ指針
    • Block - ブロックモジュールの基本単位。そのモジュール特有の複数の子要素や、エレメントモジュールを含む
    • Unit - Blockの集まり(先ほどの例の「 .bl_3colCardUnit 」など)
    • Container - Unitの集まり
    • ただし、Blockは省略して良い(bl_cardBlock → bl_card)

エレメントモジュール

接頭辞: el_

  • ボタンやラベル、見出し等の「最小単位のモジュール」で、どこにでも埋め込むことが可能なモジュール
  • 名前は極力、汎用的なものにする
    • 汎用的でない→ .el_newsLabel, .el_submitBtn
    • 汎用的→ .el_label, .el_btn
    • これはどのようなものがコンテンツとして入ったとしても、クラス名と内容が乖離しないための措置(newsLablだとニュース以外の場所で使いづらい)
  • 背景色が変わるなどは、モディファイアを使用
    • 命名規則
    • 該当モジュールの名前を継承し、その後にアンダースコアふたつをつけ、モディファイア名を続ける形
    • (モジュール名)__(モディファイア名)
  • レイアウトに関するスタイリングは基本行わない
    • ただし、ブロックモジュールに比べ、エレメントモジュールはバリエーション数多くならない
    • よって、エレメントモジュールに直接 width を指定すること
    • 及び、モディファイアでサイズの変更を制御すること
    • は許容
    • ※名前には注意(w200というモディファイア名なのにwidth以外指定すると衝突が起こるので、その場合は名前をsmallやsなどにする)
  • これはBlockかElementかの指針
    • 例えば、どっちか採用してみる
    • 「他の色々なモジュールの中に埋め込まれる」= Element
    • 「ルート要素と子要素を含め、おおよその要素数が3つ以内」= Element

モディファイア

命名規則: 基となるクラス名__モディファイア名
※ダブルアンダースコア(_2つ)なので注意

  • あしらいが変わる
  • 大きさが変わる
  • 一定の規則に従って振る舞いが変わる(カラムなど)

などの場合は、モディファイアによる上書きを行う

モディファイア名の付け方
  • __keyValue の形を基本
  • ただし、おおよそ想像がつくのであれば、keyの省略は可能(el_btn__redなど)
  • BEMではすべてに意味がわかる命名が必要があったが、PRECSSでは見た目通りでもわかれば許容
モディファイアの適用対象と詳細度
  • 多くは、モジュールグループ(ブロックモジュールとレイアウトモジュール)に使用
  • レイアウトグループなど、他のグループに対しても使用できる
  • モディファイアでスタイルを上書きする場合は、基本的にセレクターに複数クラスを使用して、詳細度を高めることを推奨(順番で上書きされるのを防ぐ)
  • 子要素にモディファイアを適用する際
    • 対象の子要素のみにモディファイアを適用する
      • 複数クラス指定で詳細度高める
    • ブロックモジュールのルート要素にモディファイアを適用する
      • モディファイア名と子(孫)セレクタを使用することで詳細度高める
      • 複数の子要素のスタイルを変更したい場合に最適

ヘルパーグループ

接頭辞: hp_

規則

  • 基本的にひとつのスタイルのみで、「ここのスタイルだけ調整したい」というような場合に用いるグループ
  • !important を付加することを推奨(意図的であり確実に適用させるため)
  • 命名規則はモディファイアと同様、「keyValue」の形

その他の規則

  • px以外の単位の場合はEmmetのショートハンドで表現(Emmetにない場合はわかりやすい頭文字を使用)
    • .hp_mt2e { margin-top: 2em !important }
  • 小数点はアンダースコアで表現
    • .hp_mt2_5e { margin-top: 2.5em !important }
  • ネガティブな値は key を大文字で表現
    • .hp_MT2e { margin-top -2em !im... }

こちらの規則はモディファイアの命名にも概ね有効。

ただし、ひとつの要素に対しヘルパークラスを多用しすぎない(2つ以内)
3つ以上ならそれらのヘルパークラスのスタイリングを最初から含んだ形のモジュールを検討するべき

ひとつのスタイルのみなので、CSSを一行で書くことを許容

ヘルパーの拡張グループの作成

独自のグループとして、デスクトップ幅用のヘルパーグループと、タブレット幅用のヘルパーグループをそれぞれ

「 lg_ 」、「 md_ 」というので設定することよくある

モジュールの上下間の余白を実装するヘルペークラス

例えば、「カードモジュールの次にテキストが続く場合は余白を20pxにしたいが、それ以外の場合は40pxにしたい」場合

ヘルパークラスを用いて実装

ただし、これが頻出する場合は、それらの値を組み合わせてひとつのクラスにまとめることもある。

ユニークグループ

接頭辞: un_

ある1ページでしか使用されないことを明示するグループ

そのページにしか使われないので、回収や運用の際に影響範囲を気にせずにスタイルを編集して良い目印になっている。
また、モジュールの大きさも自由。

つまり、あらゆるイレギュラーのための万能な回避策

ユニークグループをスタイリングしているCSSには、どのページで使用しているかコメントを残しておくこと

プログラムグループ

PRECSSでは、JavaScript等のプログラムで要素にタッチする際、または状態を管理する際、専用のクラスを付加し、モジュールとしてのスタイリングとは分離することを推奨。

接頭辞

  • js_ (JavaScriptの略)
    • JavaScriptにて要素を取得するためのクラス
  • is_ (英語 be 動詞のisから)
    • 要素の状態を管理するためのクラス
    • 状態のスタイリングは必ず適用される必要があるので、!important を推奨

必ず、セレクターは複数のクラスにする(他の箇所にも影響を及ぼさないため)

また、対応ブラウザや状況によっては、JavaScript用のクラスではなく、カスタムデータ属性やWAI-ARIAを使用して状態を管理することも許容

javaScriptファイルでは、js_ と is_ 以外の接頭辞には依存しないようにする

オリジナルグループ

柔軟に接頭辞とともにグループを追加してよい

  • グリッドレイアウト= .gr_4, .gr_6
  • コラム= .cl_3
タイトルとURLをコピーしました