初学者なりに保守しやすいスタイルシートや命名規則について考えてみる

UI開発者 工藤(皐)

この記事はミツエーリンクスアドベントカレンダー2019 - Qiitaの22日目の記事です。

運用案件で気づけた保守性の重要さ

他の人が記述したスタイルシートを編集した際、思い通りのスタイルにならなかったり、思い通りにいかない理由が予測できない...といった問題に直面したことがありませんか?
つい最近、私自身もこのような場面に見舞われ、かなりの時間を費やしてしまったことがありました。
どうすれば「誰が見ても理解のしやすいスタイルシート」を作ることができるのか、UI開発者として半年間、制作現場で過ごしてきて見えてきたことがあります。それは、スタイルシートは「保守性」を最優先に考えて設計を行うべきだということです。そもそも保守性とは、管理や維持のしやすさを表します。スタイルシートの保守性が低ければ、サイトの運用がしづらくなり、保守性が高ければ運用のしやすさが各段に上がります。実際の案件を通じて、初学者なりに保守性の重要さに気づくことができました。
それでは、「保守性」を高めていくためにはどのような方法が考えられるのか、調べてまとめてみましたので、最後まで読んでいただければ幸いです。

保守性の低いスタイルシートとは?

スタイルシートの保守性と言っても、何が保守性を低下させる要因になっているのか、イメージがしにくい方もいるのではないでしょうか。!important宣言や複雑なセレクタが多用されているスタイルシート、HTML要素の命名規則をチームで共有することなく作られたスタイルシートは、保守性が低いスタイルシートの代表例です。

!important宣言

スタイルシートの宣言内で、値の後に!importantを宣言すると、スタイルの優先度を高めることができます。

p { color: red !important; }

例えば、上記のような指定をすれば、段落としてマークアップされたテキストはすべて赤くなり、そのうえスタイルの上書きが起こりにくくなります。
しかし、特定の段落で異なるスタイルに変更したい場合はどうでしょうか?今までの指定を上書きするために、別の!important宣言で上書きをする必要が出てきます。
そうなれば必要以上にコードが肥大化してしまい、スタイルシートが読みづらくなってしまいます。その結果、どのスタイルが正しいかがわからなくなり保守性が低下していきます。

セレクタが複雑になる

特定のスタイルで上書きをする場合、!important宣言を頼らずに優先度を上げる方法があります!それは、セレクタを複雑化させ、詳細度を上げる方法です。

div > ul > li > a { color: red; }

上記のような形でセレクタを複雑化させていくと、スタイルの優先度は上がり、別のスタイルを上書きしやすくなります。しかし、祖先要素すべてをセレクタに並べていくと、やはりコードが肥大化してしまい、保守性の低下につながってしまいます。

共有せずに作成した命名規則

HTMLのclass属性を使用すると、要素に命名できます。例えば、テキストを囲うためのボックスでは、以下のような書き方ができます。

<div class="txt-box">
<p>テキストが入ります</p>
</div>

このように要素に命名をしておけば、セレクタの複雑化を避けつつスタイルシートの保守性を高めることができます。しかし、複数人が同じスタイルシートを編集する場合、命名規則を共有しないと別の問題が発生することでしょう。
ある人が「txt-box」とつけた要素を、別の人は(極端な例ではありますが)「mojinohako」とローマ字でつけるかもしれないですし、もしかすると「box」のみで命名する人もいるかもしれません。
上記のことを考えると、命名規則をあらかじめ定めても、チーム全体でルールを守り続けるよう共有をしなければ、スタイルと要素のひもづけに混乱が生じやすくなり、最終的に保守性の低下につながります。

スタイルシートの保守性を高める設計手法

HTML要素の命名規則やスタイルの指定場所などを共通のルールとして扱うことで、スタイルの衝突を防ぎ、スタイルシートの保守性を高める設計手法があります。その設計手法にはさまざまな種類があり、それぞれに異なる特徴があります。
今回は、中でも代表的な3つをHTML/CSSのサンプルと共にご紹介いたします!

OOCSS

まず、メジャーなものにOOCSSという考え方があります。Object Oriented CSS(日本語に訳すとオブジェクト指向CSS)の略称です。
大きな書き方の特徴は「構造と見た目を切り離す」。つまり、レイアウトに使うものとそれ以外を分けて記述する手法です。
この手法で記述を行うと、同じパーツに異なるclass属性値を与えることにより、カラーなどの見た目を分けて指定でき、再利用がしやすくなります。パーツの基本的な色や形を変更したい場合、大本のスタイルを変更すれば一括して変更できます。

<!-- 通常時のボタン -->
<div class="button">
<button type="button">ボタン</button>
</div>

<!-- 色を変更したボタン -->
<div class="button error">
<button type="button">エラーボタン</button>
</div>
/* レイアウト */
.button {
  width: 300px;
  height: 80px;
}
/* 見た目 */
.error {
  background: #f00;
}

SMACSS

スマックスと呼びます。「Scalable and Modular Architecture for CSS」の略称です。ベース、レイアウト、モジュール、ステート、テーマの5つに分けて記述し、ベースはそのページの基本構成などを表すもの、レイアウトはその名の通りレイアウトを構成するもの、モジュールはボックスやボタンなどのパーツ、ステートはJavaScriptなどで見た目が変化するもの、テーマはサイト全体で指定されているベースカラーやメインカラーなどを指します。

<!-- header要素のレイアウトを変更する場合 -->
<header class="header l-align-center">
<p>テキストを真ん中に寄せる</p>
</header>

<!-- is-activeをJavaScriptでつけて状態を変化させる -->
<div class="button">
<button type="button">JavaScriptで.is-activeを付与すると状態が変わります</button>
</div>

<!-- テキストボックスに色をつける -->
<div class="txt-box base-color">
<p>色のついたボックス</p>
</div>
/* ベース */
* {
  padding: 0;
  margin: 0;
}
/* レイアウト */
.l-align-center {
  text-align: center;
}
/* モジュール */
.button {
  width: 300x;
  height: 80px;
  background: #f00;
}
/* ステート */
.is-active {
  background: #0ff;
}
/* テーマ */
.base-color {
  background: #f0f;
}

BEM

BEMはBlock Element Modifierの頭文字を取ったものです。要素をパーツに分けた際、まとまった塊そのものをBlock、そのBlock内にある要素をElement、BlockやElementの要素を修飾してくれるものをmodifierに分け、その3つのカテゴリーを基準にした書き方です。
一般的な書き方として、この3つのカテゴリーを区別するため、区切りにハイフンやアンダースコアを2つ使います。
また「MindBEMding」という派生した考え方もあります。こちらでは、カテゴリーを分けるときにBlockとElementを「__」、Modifierを「--」、クラス名の単語を分ける場合に「-」で分けることが定義されています。現在、BEMの書き方として多く広まっているのは、後述の「MindBEMding」で記述されたものが大半だと言えるでしょう。
BEMを採用するメリットは、class属性値を見ただけでスタイルの対象がわかることです。これにより、後で編集する必要が出てきた場合に修正しやすくなり、保守性を高めることができます。
しかし、どんどん名前が長くなってしまうので、その点がデメリットになりえます。

<!-- この場合、boxというパーツがBlockになる -->
<div class="box box--color">
<p class="box__txt box__txt--color">Element</p>
</div>
/* Block */
.box {
  width: 300px;
  height: 80px;
}
/* Element */
.box__txt {
  font-size: 1em;
}
/* Modifier */
.box--color {
  background: #f00;
}
.box__txt--color {
  color: #fff;
}

この他にも存在する設計手法

上記の3つはかなりメジャーなものですが、これらを基準にした異なる設計思想も増え始めています。
OOCSSとBEM、SMACSSの考え方をすべて混ぜたような記述が特徴のFLOCSS。OOCSSとBEMのコンセプトをもとにして設計を行うMCSS。BEMとSMACSSを混ぜたような記述が特徴のRSCSSなどなど...
これらの設計手法については、関連する本を探してみたり、Blogやセミナーなどを活用してみるとおもしろい情報を得ることができると思います!

独自の設計手法

保守性の高いスタイルシートを実現するための、比較的よく知られた設計手法を紹介してきましたが、今までの設計手法を採用できない案件も少なからずあると思います。そんなときには、スタイルガイドを作成して、独自の設計手法をチームで共有するのも一案です。

スタイルガイドとは

スタイルガイドというものは、その名の通りスタイルのルールをまとめたものです。
これを作業前に作成しておくと、チーム内でルールを共有することができ、コードの統一化ができます。
手作業で作成することも可能ですが、コードを書きながらスタイルの状態を都度目視で確認しなければならないため、ヒューマンエラーが紛れ込む可能性があります。
スタイルガイドジェネレーターを使用すると、ヒューマンエラーを減らすことができます。

スタイルガイドジェネレーター

Web上にはさまざまなスタイルガイドジェネレーターが公開されています。以下に挙げるものは、よく使われている代表的なジェネレーターです。

これらのスタイルガイドジェネレーターを使うと、以下のようなメリットがあります。

  • 規則やルールを指定しておけば、そのルールに合わせた形で自動出力してくれる。
  • 使うジェネレーターによっては、あらかじめテンプレートが用意されている。
  • ページを量産することが容易になる。

一見すると、スタイルガイドジェネレーターを使うことで、どのようなサイトも保守性を高めることができるかもしれません。
しかし、以下に当てはまるようなサイト構成の場合は、意図せぬ統一化が起こる可能性があり、注意が必要です。

  • ページごとにユニークなスタイルを指定している。
  • 各ページがまるごと違うスタイルで構成されている。

実際に触ってみて、使いやすいものを選んでみることをオススメします。

まとめ

私は現在、BEMの使い方を練習していますが、今後はその他の命名規則も一度使ってみて、自分なりの保守しやすく再利用しやすい設計手法を一度は開発してみたいという夢ができました。
それはさておき、100%保守のしやすいサイトを作成するということは相当な難易度と根気を必要とする作業です。しかし、運用を通じて設計手法(命名規則を含む)を徹底することで、保守性を限りなく100%に近づけられるのではないでしょうか?
もし、メジャーな設計手法を使わず、またスタイルガイドを作成しチーム内で共有せずとも、常に他の人が見ても理解ができるようなきれいなスタイルシートを意識して作成するだけで、保守性を高めていくことができるでしょう!