CSSコンポーネント設計のアイデアの活かし方について考えてみた

  • 18
    いいね
  • 1
    コメント

Sketchy Talks #1 CSSについて学ぶの登壇資料として。
(ここに書いてたらスライドを作る時間がなくなりました。)

なぜ”設計”が必要か?

良いCSSを作るため。
この一言に集約されるかなと思います。
htmlをイケてる感じにしてくれるCSSですが、そのイケてる感を出そうとすればするほど記述はどんどんと長くなり複雑化してきます。
では、「良いCSS」とは何なのか?

良いCSSの定義

この本の記載内容によると以下の4つ。

  • 予測しやすい
  • 再利用しやすい
  • 保守しやすい
  • 拡張しやすい

正直、結構ムズイ

言われてみれば納得。でもこれを全て叶えるCSSをつくるのってなかなか大変。
まだまだ経験値の浅い私がアレコレ意識しすぎると

「ここってこういう風にしたほうが良かったかな・・・でも今直したら大変やんなぁ〜・・・でもでもあとあと"やっぱりこうしたい!"ってなったら大変やし・・・」

とパニックになって本当に良いことがない(笑)

「保守のしやすさ」「拡張のしやすさ」は作るモノの規模や今後の展望と関係するような気がするので、個人的にはまず 予測しやすい こと 再利用しやすい の2点ぐらいを意識してやるのがいいかなと思ってます。

とりあえずコンポーネント設計について調べてみた

参考図書はこれ

「予測しやすい」「再利用しやすい」の2つだけを意識する、とは言ったってそれだってなかなか簡単じゃない。
そこで参考になるんじゃないかとコンポーネント設計のアイデアについての章をチェックしてみたところ、「これは私もやってるわー」ってこともあれば「あーなるほどね」ってこともあったのでとりあえず OOCSSSMACSS についてまとめてみる。

OOCSS

このルールを頭にいれるだけでもかなり見やすいCSSになりそう

Object Oriented CSSの略で、 オブジェクト指向プログラミング(OOP) の概念を取り入れてる。
Wikipediaによると

オブジェクト指向プログラミング(オブジェクトしこうプログラミング、英: object-oriented programming, OOP)とは、相互にメッセージ (message) を送りあうオブジェクト (object) の集まりとしてプログラムを構成する技法である。

らしいけど、まぁ細かいことはさておき。
私はOOPを 「よく使うヤツは塊にして、足りないものはその場で追加」みたいな概念なのかなーと解釈しています。

構造と見た目(スキン)をわける

こんな感じの3種類のBoxがあったとき。

無題のプレゼンテーション.jpg

見ての通り 色が違うだけほぼ同じ形 なわけです。
これを

  • 見た目(ボーダーの色)
  • 構造(Boxの幅、テキスト中央揃え、角丸)

と分けて書く。

common.css
/*見た目*/
.red {
    border: 1px solid red;
}
.blue {
    border: 1px solid blue;
}
.yellow {
    border: 1px solid yellow;
}

/*構造*/
.box {
    width: 10em;
    text-align: center;
    border-radius: 6px
}
index.html
<div class="red box">redBox</div>
<div class="blue box">blueBox</div>
<div class="yellow box">yellowBox</div>

メリット

greenBox

 

reversalGreenBox

こんな色違いとか反転したやつとかが出てきたときに 見た目 のスタイルだけ追加すればいいのでラク。

common.css
/*見た目*/
.green {
    border: 1px solid green;
}
.reversalGreen {
    border: 1px solid green;
    background-color: green;
    color: white;
}
index.html
<div class="green box">greenBox</div>
<div class="reversalGreen box">reversalGreenBox</div>

コンテナーとコンテンツを分離

(.redBox)
文章がはいります

 


(.blueBox)

文章がはいります
html.index.html
<div class="redBox">
    <p>文章がはいります</p>
</div>
<div class="blueBox">
    <p>文章がはいります</p>
</div>

2つのdivに内包されているpタグ "文章がはいります" のスタイル

  • font-weight: bold;
  • font-size: 1.5em

を指定するとき、私の今までならコードはこんな感じ。

common.css
.redBox p, .blueBox p {
    font-weight: bold;
    font-size: 1.5em;
}

増えたらどうする?

(.greenBox)
文章がはいります
html.index.html
<div class="greenBox">
    <p>文章がはいります</p>
</div>

しかも若干文字が大きい。

common.css
.redBox p, .blueBox p {
    font-weight: bold;
    font-size: 1.5em;
}
.greenBox p {
    font-weight: bold;
    font-size: 2em;
}

こう?

また増えたら??

(.orangeBox)
文章がはいります
html.index.html
<div class="orangeBox">
    <p>文章がはいります</p>
</div>

今度は小さいだと?

common.css
.redBox p, .blueBox p {
    font-weight: bold;
    font-size: 1.5em;
}
.greenBox p {
    font-weight: bold;
    font-size: 2em;
}
.orangeBox p {
    font-weight: bold;
    font-size: 1em;
}

ここまでくると今後も 大・中・小 の3パターンを用意しておいたほうがいいのかも、となります。
というわけで、

場所に依存しないセレクタにする

(.greenBox)
文章がはいります

(.redBox)
文章がはいります

(.orangeBox)
文章がはいります
html.index.html
<div class="greenBox">
    <p class="big-p">文章がはいります</p>
</div>
<div class="redBox">
    <p class="middle-p">文章がはいります</p>
</div>
<div class="orangeBox">
    <p class="small-p">文章がはいります</p>
</div>
css.common.css
.big-p {
    font-weight: bold;
    font-size: 2em;
}
.middle-p {
    font-weight: bold;
    font-size: 1.5em;
}
.small-p {
    font-weight: bold;
    font-size: 1em;
}

こうすることで場所(コンテナー)に関係なく使えるようになる、と。

SMACSS(スマックス)

ページ内のどのカテゴリに関する記述なのかがわかりやすくなるルール

OOCSSのコンセプトをベースに作られたフロントエンドに関するガイドライン。
OOCSSをより実践的に学ぶためのアイデアらしい。

カテゴライズ

SMACSSではCSSの記述を次の5つのカテゴリーに分けて考える。

  • Base(全体)
  • Layout(レイアウト)
  • Module(まとまり)
  • State(状態)
  • Theme(テーマ)

Layout、State、Theme についてはそれぞれ接頭語
l-is-theme-を付けることが推奨されている。(理由は後述)

- Base

全体の背景色、フォントの種類などhtmlやbodyに書くようなものが Base

- Layout

ページのレイアウトに関する要素。

今までは #header #footer のように全体のレイアウトに関してはidを使っていましたが、最近社内では詳細度の問題から 「できるだけidは使わない」方針。
とはいえ、やはりclassにすると「他の場所でも使っちゃったらどうしよー」なんて思うわけです。
そこでSMACSSが推奨している接頭語l-を使うといいんじゃないかなーと。

index.html
.l-header {
    background-color: black;
}
.l-footer {
    background-color: blue;
    color: white;
    height: 40px;
}

l-"layout"の意味なので、「これはレイアウトに関するスタイルだな!」とわかり良い感じに。
他にも グリッドレイアウトなんかにも使うといいっぽい。

index.html
<ul class="l-grid">
    <li>てすと</li>
    <li>てすと</li>
    <li>てすと</li>
</ul>
common.css
.l-grid {
    paddin: 5px;
    margin-top: 10px;
}

- Module

その他のまとまり。

ボタンとか見出しとか複数の要素で構成されている 何回も使いそうなやつ、という感じ?

- State

javascriptで変わるような"状態"を表すもの。

display:noneを指定するセレクタとかに。
あと、is-だけじゃ対象がどれなのか分かりにくかったりだとかもあるのでalert-のように少し具体性があったほうがいいっぽい。

common.css
.is-alert-hidden {
    display:none
}   

- Theme

構成は同じで、複数のテーマを持たせたい(色とか)ときに使う。

先述の.l-headerがページによって色を変えたい場合。

.thema-sea .l-header

.thema-sea .l-header
sea.html
<div class=".theme-sea .l-header">・・・</div>
woods.html
<div class=".theme-woods .l-header">・・・</div>

cssは共通のcommon.cssだとしたとき、こうすると良い感じ。

common.css
.l-header {
    height: 60px;
    padding-top: 10px;
    padding-bottom: 15px;
}
.theme-sea {
    background-color: skyblue;
    color: white;
}
.theme-woods {
    background-color: green;
    color: white;
}

まずは「破綻しにくいCSSを作る」という意識が大事そう

あくまでこれらは「良いCSSを作る」という 目的を達成するための手段。
命名規則などの型にとらわれすぎず、ちょっとずつ取り入れていくのがCSS設計初心者には良いのかなーと思いました。