#はじめに
株式会社サイシードのインターンシップにて、CSSを設計する際の規則をまとめました。
本稿で記述している設計規則に基づいての開発は、始めてから日が浅いです。
実際に使用していく中でさらに改善を進めて行く予定です。
設計規則を考えるに当たって**「Web制作者のためのCSS設計の教科書」**を参考にさせて頂きました。
より詳しくCSSの設計方法について学びたい方はぜひ手にとってみてください。
本設計規則は、上記の書籍で紹介されている中でも特にBEMとFLOCSSに影響を受けています。
本稿が少しでもみなさまの参考になれば幸いです。
###スタイルの役割の分類
####1.構造
形や大きさなどを指定する。
家で言うところの骨格。
例: width
, height
, border
, padding
, margin
, font-size
など
####2.見た目
色や太さなどを指定する。
家で言うところの外見。
例: color
, border-color
, background-color
など
###CSSの性質
####1.カスケーディング
**CSS(Cascading Style Sheets、カスケーディングスタイルシート)**の名前の由来で、
カスケーディングとは 何段も連なった小さな滝という意味。
あるHTML要素に対して複数のスタイルが適用され得る時に、どのスタイルを適用するか
決めるための仕組み。
適用される得るスタイルの強さは以下のように決められる。
######カスケーディングの3大原則
1.ウェブブラウザによって与えられたスタイルよりもウェブブラウザのユーザーによって
与えられたスタイルのほうが強く、ウェブサイトのスタイルはそれよりも強い。
2.宣言に対応するセレクタによる絞り込みが強い(詳細度が高い)ほど,すなわち,
特殊性の高いセレクタを持っているほど強い。
3.最後まで強さがつけられないときは,後に書かれたスタイルほど強い。
####2.一部のプロパティで親要素のプロパティが継承される
プロパティには、親要素に指定した値が子要素に継承されるものと継承されないものがあり、
文字色や文字サイズに関するプロパティなどは継承される。
一方、border
、margin
、padding
、背景画像などは継承されない。
####3.CSSは右から左に読み込まれる
数の多いものが右にある(数の多い子孫セレクタを記述する)と、
それだけ多くの要素を探し出すことになり、パフォーマンスが下がる。
そのため、できる限り下のような子孫セレクタ用いずに、
# 例
div#wrapper div#main ul.list li {}
上の例のli
にclassを振って以下のようにするほうが良い。
# 例
.item-list {}
####4.idやclassには要素名をつけないほうが高速
div#foo {}
やli.item {}
などとはせずに#foo {}
や.item {}
などのようにする。
#CSS設計規則
###基本
####1.構造化はFLOCSSを参考にする
レイヤーごとに詳細度に関するルールを定義することで、カスケーディングを管理するCSSの設計手法。
FLOCSSはFoundation、Layout、Objectの3つのレイヤーから構成され、
ObjectレイヤーはさらにComponent、Project、Utilityの3つの子レイヤーに分けられる。
同じような設計手法に、OOCSSやSMACSSなどがある。
####2.命名規則はBEMを参考にする
構造化と命名規則との違いがあいまいになりやすいので気をつける。
構造化ではいくつかのレイヤーを考えるが、
どのレイヤーであっても命名規則にはBEMの考え方を利用する。
####3.CSSのセレクタにidは使わない
idを用いると詳細度が高くなるため、スタイルの上書きがしにくくなり、目的のスタイルが
適用できなくなるため。
idはCSS以外(javascriptなど)で用いるようにすることで、役割の違いがわかりやすくなる。
####4.単語の省略はなるべくしない
他の開発が見たときにでも、その意味がわかるようにして、誤解を招かないようにする。
####5.マルチクラスを用いる
役割を分けたclassを用意し、それら複数のclassをHTML要素のclassに与え、目的のスタイルを適用する。
ただし、@extend
や@mixin
など(SCSSの機能)も活用して、付与するclassが多くなりすぎないようにする。
####6.構造と見た目とは明確に分ける
構造のスタイルを指定するclassと見た目のスタイルを指定するclassは分ける。
構造のスタイルを指定するclassと見た目のスタイルを指定するclassを組み合わせて適用する
ことによって、目的のスタイルを適用する。
####7.HTML構造に依存しないCSSを書く
HTMLのデフォルトスタイルを初期化する場合以外で、HTML要素をセレクタに用いない。
####8.HTMLのタグによるスタイル適用はなるべくしない
基本的にdiv
タグを用いて、そのdiv
タグにclass
を付与することでスタイルを適用する。
small
タグやh
タグ、strong
タグなど、フォントサイズやフォントスタイルを
変化させるHTML要素は使わない。
####9.基本的にimportant!は使わない
ただし、FLOCSSのUtilityレイヤーなどでは許容する。
####10.上の親要素であるほど適用するスタイルは必要最小限にとどめる
一部のプロパティは子要素に継承されるため。
####11.できる限りjavascriptを用いない
レスポンシブルデザインやモーダルもcssで実装するようにする。
誤動作を防げるだけでなく、実行速度の向上も見込める。
####12.インデントはスペース4つ分
スペースが少なすぎると、インデントがわかりにくいし、多すぎるとエディタ上で折れ曲がってしまい
見にくくなる。
####13.再利用は基本的に考えない
ただし、基準として、3回程度同じ構造が出てきたら、それらを共通化させてもよい。
####14.セマンティックなclass名をつける
見た目や振る舞いからではなく、目的や役割に基づいて名前をつける。
<div class="red pull-left"></div>
<div class="grid row"></div>
<div class="col-xs-4"></div>
<div class="header"></div>
<div class="basket"></div>
<div class="product"></div>
####15.CSSフレームワークを用いる
BootstrapなどのCSSフレームワークを用いる時は、まずはそこで提供されているスタイルだけを
用いて、UIを作る。
その後に、足りないところを独自のスタイルを適用することで、より細かいUIを作っていくようにする。
####16.便利なツール
(1)OneClickCSS
HTMLを入力またはコピペしてやると、それに応じてセレクタを生成してくれる。
(2)Emment
HTML構造を効率よく生成できるようになる。
######参考:
1.Emmetでマークアップを効率化しよう
2.EmmetをSublime Text 3で使ってみよう
3.cheat sheet
###構造
####1.brタグなどで要素間の隙間を調整してはいけない
margin
やpadding
などで調整する。
####2.マージンについて
要素間の間隔の指定は、あわせるようにする。
そうしなければ、相殺が起き、期待したデザインにならないことがある。
(1)上下の要素間の隙間を空ける時は、下にだけ適用する
つまり、margin-bottom
だけを用いる。
(2)左右の要素間の隙間を空ける時は、右にだけ適用する
つまり、margin-right
だけを用いる。
(3)上下の要素を重ねる時は、上にだけ適用する
つまり、margin-top
でネガティブマージン(マイナスのマージン)を用いる。
(4)左右の要素を重ねる時は、左にだけ適用する
つまり、margin-left
でネガティブマージン(マイナスのマージン)を用いる。
###見た目
####1.サイズについて
基本的には、em
か%
を用いる。
レイアウトやボックスなど大きい範囲のサイズ指定(特に、width
)は、%
を用い、
文字の大きさやちょっとした隙間などはem
を用いる。
基本的にはem
を用いることになる。
迷ったら、em
。
#####1-1.emと%の相対指定の基準となる相手について
(1)font-size(フォントサイズ)
em
でも%
でも親要素のフォントサイズが基準。
もっと正確に言うと、親から継承している自分自身のフォントサイズが基準。
(2)line-height(行の高さ)
em
でも%
でも自分自身のフォントサイズが基準。
自分自身にfont-size
を指定してる場合は、そのサイズが基準。
font-size
を指定していなければ、親のフォントサイズを継承したときの自分自身の
フォントサイズが基準。
(3)margin 、padding 、width 、height(要素間の間隔や要素の大きさ)
em
なら自分自身のフォントサイズが基準。
%
だと親要素のフォントサイズが基準。
#####1-2.%指定の注意点
%指定すると、親をたどっていって、絶対値がわかるところからの相対指定となるので、
最悪、html要素までさかのぼり、その大きさからの相対指定となることで、予想外の大きさに
なることがある。
#####1-3.フォントサイズの基準
一番最初に基準になるフォントサイズは、<html>
要素のフォントサイズ。
PCブラウザでの<html>
要素のデフォルトのフォントサイズは、font-size : 16px
。
どのPCブラウザでもこれがデフォルト。
ちなみに、行高さのデフォルトは、line-height : 24px
。
24pxはつまり、1.5em(デフォルトのフォントサイズの1.5倍)。
#####1-4.em、%、pxの使いどころ
(1)em を使うところ
フォントサイズを基準にしたサイズ。
例えば、2emだと基準の文字サイズに対して、2倍の大きさになる。
フォントサイズが変わると影響を受ける部分、文字の大きさに対するサイズが
重要なところで用いる。
######** emを用いる具体例:**
・font-sizeや line-height(行の高さ)はem
PCブラウザのデフォルトの16px
を基準に、まず<body>
のfont-size
をem
で決める。
これが本文の文字サイズになる。
これをもとに、見出しはでっかく、コラムの本文は小さくなどと、
文字の大きさのバランスをem
で設計していく。
・line-heightもemで指定
ボックスのpadding
やmargin
も、font-size
の変更によって調整が必要になりそうな
padding
やmargin
はem
で相対指定する。
フォントサイズを変更したら自動変更してくれるから。
%
は使わない。
(2)%を使うところ
ボックスのサイズ指定(特に、width
)でよく使う。
ページ全体に対してどれくらいの大きさにするかが重要なところで用いる。
例えば、親要素に対して左右いっぱいにしたいボックスはwidth:100%
で指定。
レスポンシブレイアウト(ウィンドウサイズによってサイトの幅が可変する)で%
をよく使う。
(3)px を使うところ
フォントサイズ、ボックスサイズに関係なく、サイズを固定したいところで用いる。
######** pxを用いる具体例:**
・border-width(border の幅)
もっとも良く使う。
・border-radius(ブロック要素の角丸)
正円や楕円形の場合以外はpx
で指定
・サイトのメインボックスの幅
メインボックスの幅をpx
で固定してしまい、端末ごとにメディアクエリで幅を切り替える。
・デザイン上、サイズを固定したい部分もpx
で指定
グローバルナビや、<h1>、<h2> を、背景画像と一緒に作り込むような場合などは、
ガッチリpx
で固定する。
この場合も、メディアクエリで切り替えが必要。
####2.見た目の変更
#####2-1.State
状態を表す。
Stateとして作成したセレクタ単体に対しては、スタイルを適用してはならない。
他のclassと組み合わせて使う。
接頭辞としてis-
をつける。
######** 例:ボタンが押された状態になっているかどうか**
<div class="button button-primary is-active">
.button-primary.is-active {・・・}
#####2-2.Theme
Stateのような小さい範囲でのスタイル変更ではなく、ページ全体のテーマなどより大きい範囲での
スタイル変更時に用いる。
接頭辞として、**t-
**をつける。
###命名規則
####id名、class名に使用する接頭辞一覧
接頭辞 | 用途 | 使用例 |
---|---|---|
js- | javascriptの対象となる要素につける |
id="js-move-icon" |
l- | Layoutレイヤー(FLOCSS)の要素につける | class="l-header" |
c- | Componentレイヤー(FLOCSS)の要素につける | class="c-btn" |
p- | Projectレイヤー(FLOCSS)の要素につける | class="p-btn--primary" |
u- | Utilityレイヤー(FLOCSS)の要素につける | class="u-clearfix" |
t- | 比較的広い範囲の状態変更を伴う要素につける | class="t-blue-sky" |
is- | 比較的狭い範囲の状態変更を伴う要素につける | class="is-active" |
a- | ページ内リンクのアンカー要素につける | id="a-page-top" |
m- | modal要素につける(※Bootstrap使用時など) | id="m-edit-prfile" |
cl- | collapse要素につける(※Bootstrap使用時など) | id="cl-tag-options" |
####id名、class名のつなぎ方 | ||
#####1.-(ハイフン) | ||
名前の区切り。 |
例: class="p-edit-modal"
#####2.--(ハイフン2つ)
BEMの命名規則のModifier(後述)で用いる。
例: class="p-edit-modal--primary"
#####3.__(アンダースコア2つ)
BEMの命名規則のElement(後述)で用いる。
例: class="p-edit-modal__header"
####BEMについて
BEMでは、次の3つの要素を考える。
#####1.Block
最も基本的な要素。
あるUIを作る時の一番上の親要素をBlockとする。
Blockは単独で機能するようにし、他のBlockに依存させない。
SCSSファイルとして分割する時は、この要素の名前と同じ名前にすると良い。
そうすることで、ネームスペースの重複が起きないようにする。
仮にネストされていたとしても、親の構造に依存しない構造が入る時は、
新しいBlockを考える(例としては、下の"例:モーダル"のp-panel
)。
######** 例:モーダル**
以下の例におけるp-modal
、p-panel
がBlockにあたる。
<div class="p-modal p-modal--primary">
<div class="p-modal__header">
・・・
</div>
<div class="p-modal__body">
<div class="p-panel">
<div class="p-panel__title">
・・・
</div>
<div class="p-panel__body">
・・・
</div>
</div>
</div>
<div class="p-modal__footer">
・・・
</div>
</div>
#####2.Element
Blockを構成する要素。
Blockの中の一つ一つの要素がElementとなる。
Elementは、Blockを起点として、_(アンダースコア)2つで役割となる名前をつなげる。
色や大きさなど見た目を表すものを含んではならず、あくまで構造的なもので、
Blockに自然と含まれるものにする。
ElementにElementをつなげることは極力避ける。
HTMLの構造でElementを考えるのではなく、Blockに対するElementとModifierの関係性を示すようにする。
例えば、ElementのさらにElementであるときは、subやchildといった名前によってBlockとの関係性を示す。
######** 例:モーダル**
以下の例におけるp-modal__header
、p-modal__body
、p-modal__footer
、
p- modal__child-form
がElementにあたる。
<div class="p-modal p-modal--primary">
<div class="p-modal__header">
・・・
</div>
<div class="p-modal__body">
<div class="p-modal__child-form">
・・・
</div>
</div>
<div class="p-modal__footer">
・・・
</div>
</div>
#####3.Modifier
BlockまたはElementのバリエーション違いの要素。
色や大きさの違いなど見た目を含む。
Modifierは、BlockあるいはElementを起点として、-(ハイフン)2つで
役割となる名前をつなげる。
Elementは構造、Modifierは見た目と考えておけばよいが、あいまいなものもある。
あいまいなものは、バリエーションの違いとして適切かどうかで判断する。
######** 例:モーダル**
以下の例におけるp-modal--primary
、p-modal__header--default
がModifierにあたる。
<div class="p-modal p-modal--primary">
<div class="p-modal__header p-modal__header--default">
・・・
</div>
<div class="p-modal__body">
・・・
</div>
<div class="p-modal__footer">
・・・
</div>
</div>
#####※ ElementとModifierの覚え方
次のようなイメージを持っておくと覚えやすい。
Elementは**_(アンダースコア)2つで、Blockに対して一段下がっている
つまり親子関係であるというイメージ。
Modifierは-(ハイフン)2つで、バリエーション違いとしてBlockやElement**に対して
対等の関係にあるというイメージ。
#まとめ
この設計規則でどこまで通用するかは、今後の運用次第なところはありますが、
とりあえずの設計規則を決めました。
今のところの不安要素には以下のようなものがあります。
・BEMの考え方を使うことでclass名をつけやすくなる一方で、class名が長くなってしまう。
・ある構造をどのレイヤーに含めるか、またその構造の中の要素がそれぞれBEMのどの要素に該当するか、
といったことはあくまで主観的である。
こうした問題をどのように解決するかが、本稿の設計規則を用いる上での課題となってきそうです。
#参照
1.[カスケーディングの基礎](http://www.tg.rim.or.jp/~hexane/ach/lbcs/lbcs2-05.htm
http://d.hatena.ne.jp/amachang/20080407/1207594307)
2.スタイルの継承
3.ほんっとにはじめての HTML5 と CSS3
4.hiloki/flocss
5.CSSの設計 – FLOCSSをベースにしたファイルの構成と命名規則を考える
6.manabuyasuda/styleguide
最後に
オリジナル音楽の投稿配信サービスMicstackを運営しています。
よろしければご利用ください。