Help us understand the problem. What is going on with this article?

はじめてのCSS設計

More than 5 years have passed since last update.

少し前からBEMやSMCASSなどのCSS設計などを知り、なるほどこういう方法があるのかと、苦戦しながら実践していました。
そんな中@hiloki@githubさんが自前でFLOCSSというCSS設計思想をGithubで公開していたので、
自分もこういうの作ってみたい!と思いたち、
稚拙ながら設計を考えてみました。

OOCSS,SUIT,SMACSS,FLOCSSあたりを参考にしています。

CSSのカテゴライズ

  1. Base
  2. Component
  3. Unit
    • layout
    • pack
  4. Asset
    • utility
    • assist

CSSをこのように分割します。

Base

SMACSSのBaseにあたるものです。

Component

ページを構成するパーツのすべてです。
再利用しやすいよう、親に依存せず、Component単独でスタイルを維持できるように設計します。
Componentは自分自身の見た目のみを司り、位置関係に関しては、後述するUnitクラスがすべて受け持つようになります。

命名規則

  • ComponentName
  • ComponentName--skinName_[n]
  • ComponentName-descendentName_[n]

Componentはskeletonとskinに分けて記述します。

ComponentNameがスケルトンになり、そのComponentに形作るための必要最低限のスタイルを司り、
ComponentName--skinNameが、そのComponentのskin(modifier)のスタイル司っています。
また、Componentを作るモジュール群に関しては、ComponentName-descendentNameで記述します。

Componentの子要素にはすべてクラス名でスタイル当てていきます。(構造とスタイルの分離のため)
親コンポーネントによって、子コンポーネントの形が変わる場合には親コンポーネントと同じskinNameを付与し対応します。

例を示します。

<div class="Island Island--notify">
  <div class="Island-head">
    <h3 class="Heading Heading--h3"></h3>
  </div>

  <div class="Island-body">
    <ul class="LinkList LinkList--notify">
      <li class="LinkList-item"></li>
    </ul>
  </div>
</div>

セマンティックに名前を付けられない場合、またはパターンがあるものに関しては、コンポーネント名(または、skinName,descendentName)の最後に_[value]を追加し対応します。

<a href="#" class="TextLink TextLink_1"></a>

Unit

Unitにはページで一つだけしか使えないLayoutクラスと、汎用的に使えるPackクラスが存在します。

先述したように、
Componentは、そのComponentがどのような見た目をしているかだけを司り、
そして、その親のUnitが、そのComponent(またはComponent群)が、どのような位置関係にあるかを司ります。

これによって、Componentがどの位置にあるかについては全く関与しないで、自分自身の見た目だけを司ることができます。

Layout

ページに唯一のUnitとしてはプリフィックスとしてl-をつけます(Layout)
LayoutはSMACSSでいうThemeの役割も担っており、ページごとにオリジナルなComponentにしたい場合のフックに利用します。

.l-header {}
.l-sidebarRight {}
.l-specialPage {}

Pack

汎用的に使えるUnitとしてプリフィックスとしてp-をつけます(Pack)

.p-container {}
.p-streamCard {}

Asset

Assetはグローバルに使えるUtilityクラスと、コンポーネントを補助するAssistクラスが存在します。

Utility

marginやpadding、そしてclearfixなどグローバルに使える、単一のスタイルが付与されたクラスがここに分類されます。
プリフィックスとしてu-をつけます。
スタイルには明示的に!importantを付与します。

.u-mb10 {}
.u-clearFix {}

Assist

Assistクラスは必ずコンComponentとセットで利用します。
必ずCSSはComponentとの結合セレクタで定義します。

.has-border {}
.has-header {}

タブがアクティブ、非アクティブやモーダルが、表示、非表示などコンポーネントの状態を示すときis-を使います

.is-hidden {}
.is-error {}
.is-active {}

.Tab-button.is-active {}

ボーダーがある場合、ない場合やアイコンをある場合、ない場合などコンポーネントのパーツを拡張したり、修飾する場合has-を使います

.has-border {}
.has-header {}
.has-icon {}

.Panel.has-header {}

skinとほぼ同じ役割のように見えますが、クラス属性が冗長になるのを防ぐために、モジュールの追加(パネルのヘッダ)やグローバルなモジュール(枠線など)の場合はhas-を使います。

<div class="Panel Panel--primary has-header"></div>

以上です。

不満な所

  • 制約が多くて覚えにくい(致命的)
  • の割に、複雑なUIを形成する際に詰まりそう

そして

心安らかに、拡張していけるようになりたい。

あとは、とにかくプロジェクトメンバーとの思想の共有と、コードレビューを徹底する。

作ってみて思ったのですが、
設計はメンバーで徹底する事が大事なので、もう少し、軽めに分かりやすくシンプルにするのが、寿命が長い設計のためには必要だなと思いました。

はじめて、こういうものを作ってみましたが、
これから、自分の成長とともにアップデートしていきたいなと思います。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away