🎉 お知らせ:サイト名が『webkore』から『模写修行 media』に変更になりました。6月以降にドメインも『moshashugyo.com/media/』へ変更する予定です。

HTML/CSS

【CSS設計入門】class名の決め方(命名規則)から具体的な書き方まで詳しく解説

Author:Gaku(gaku92014091)

この記事の目次

実務でリニューアル案件や改修案件をやると、他人が書いたコードをよく見ることになります。これは"ヤバイ"と思うコードもたくさん目にします。

HTMLは色々な書き方があってOKというわけではなく、正しく意味付けするものなので、ちゃんと書いていれば人によってあまり差が生まれません。一方で、CSSは人によって書き方はかなり様々です。

  • どんなサイトを作るのか
  • 誰が作るのか
  • サイト公開後は誰が保守・運用するのか

これらによって最適な書き方は変わってきます。正解はありませんが、CSS設計を理解して、自分の中でどんなCSS設計を採用するかは決めておくべきです。

この記事では、CSS設計に関して、具体的なサンプルも用いて解説します。

CSS設計が大事な理由

小規模案件やLPなどでは、それほど明確なCSS設計をしなくても問題は起こらないかもしれません。

書き方によってサイトのパフォーマンスが変わるなんて話しもありますが、昨今のブラウザではその差はほんの誤差程度なのでその点も無視して良いでしょう。

ただ、規模が大きくなるとHTMLもCSSもかなりの量になり、CSS設計をせずに書くといずれ破綻します。

また、複数人で制作する場合も、CSS設計がないとほぼ確実にひどいコードになります。

ココ重要!

webサイトやwebサービスは公開してからがスタートです。公開後の運用も考えて、良いコードを書くことはとても重要です。

良いCSSとは?

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

Googleのエンジニアである、Phil Waltonさんが自信のブログで、良いCSSとしてこの4つを上げています。

参考記事

翻訳したものを記載します。CSS設計を初めて勉強する方は、ざっと目を通すだけでも良いです。しっかり勉強した後に見直すと、理解が深まると思います。

予測しやすい

Predictable CSS means your rules behave as you’d expect. When you add or update a rule, it shouldn’t affect parts of your site that you didn’t intend. On small sites that rarely change, this isn’t as important, but on large sites with tens or hundreds of pages, predictable CSS is a must.

予測可能なCSSは、ルールが期待どおりに動作することを意味します。 ルールを追加または更新するときに、意図しないサイトの部分に影響を与えないようにする必要があります。 変更されることはめったにない小さなサイトでは、これはそれほど重要ではありませんが、数十または数百ページの大きなサイトでは、予測可能なCSSが必須です。

再利用しやすい

CSS rules should be abstract and decoupled enough that you can build new components quickly from existing parts without having to recode patterns and problems you’ve already solved.

CSSルールは抽象的であり、十分に分離されている必要があります。これにより、すでに解決したパターンや問題を再コーディングすることなく、既存のパーツから新しいコンポーネントをすばやく構築できます。

保守しやすい

When new components and features need to be added, updated or rearranged on your site, doing so shouldn’t require refactoring existing CSS. Adding component X to the page shouldn’t break component Y by its mere presence.

サイトで新しいコンポーネントや機能を追加、更新、または再配置する必要がある場合、既存のCSSをリファクタリングする必要はありません。 コンポーネントXをページに追加しても、コンポーネントYが存在するだけで壊れてはなりません。

拡張しやすい

As your site grows in size and complexity it usually requires more developers to maintain. Scalable CSS means it can be easily managed by a single person or a large engineering team. It also means your site’s CSS architecture is easily approachable without requiring an enormous learning curve. Just because you’re the only developer touching the CSS today doesn’t mean that will always be the case.

サイトのサイズと複雑さが増すにつれて、通常、より多くの開発者が維持する必要があります。 スケーラブルなCSSは、1人または大規模なエンジニアリングチームが簡単に管理できることを意味します。 また、膨大な学習曲線を必要とせずに、サイトのCSSアーキテクチャに簡単にアクセスできることも意味します。 今日CSSに触れている開発者があなただけだからといって、常にそうなるとは限りません。

カスケーディングと詳細度の理解は必須!

駆け出しの方々のコードを見て、1番問題だと感じるのが、『カスケーディングと詳細度』を意識していないことです。

カスケーディングと詳細度を理解して、その上で適切なルールで書けば、大きな問題は防げます。

カスケーディングとは?

Cascadeとは日本語で滝という意味です。CSSのカスケーディングとは、滝のように上から下へ連鎖的に伝わる仕組みのことです。

わかりやすく言うと、先に宣言されたものが継承されたり、上書きされたりする仕組みのことです。

例を紹介します。


継承される例

css
body{
  font-size: 18px;
}

.service-text{
  color: blue;
}

.service-textは文字色が青色になるだけでなく、bodyに指定したフォントサイズも継承されます。

※継承されるかどうかはプロパティによります。


上書きされる例

css
.service-list{
  color: red;
}

.service-list{
  color: blue;
}

.service-listに対して同じプロパティ(color)が指定されています。この場合、後に書いたものが先に書いたものを上書きするので、color: blue;が適応されます。

詳細度とは?

CSSは単に後に書いたものが先に書いたものを上書きするわけではなく、詳細度という優先度のルールがあります。

  1. !important
  2. インライン記述
  3. IDセレクタ
  4. クラスセレクタ、属性セレクタ、擬似クラス
  5. 要素セレクタ、擬似要素
  6. ユニバーサルセレクタ

詳細度はこれらの順に高くなります。

css
#service .service-list{
  color: red;
}

.service-list{
  color: blue;
}

このコードでは、後に書いているcolor: blue;で上書きされません。それは先に書いている方が詳細度が高く、優先されるからです。

ルールを設けずにCSSを書くと、この詳細度が複雑になります。

詳細度のルールはもう少し複雑ですが、長くなるのでここでは解説は避けます。ただ、後述しますが、基本は単体のクラスセレクタに対してスタイリングすれば複雑になることはありません。

詳細度の計算ができるサイトを載せておきます。

参考サイト

CSSでidは使わない方が良い?

前述した詳細度の仕組み的に、idは基本使いません。

有名なCSS設計で、特定条件では使っても良いとしているものもありますが、使うことのメリットは特にありません。

ただし、もちろんページ内リンクの飛び先になるタグにはidが必要です。それでもidにはスタイリングしな方が個人的には良いと思っています。

html
<header id="header" class="header">...</header>

スタイリングが必要な場合、このようにして.headerに書きます。

また、JavaScriptのフックに使う方もいます。

html
<div id="js-kv-slider">...</div>

JavaScriptを書く際にはこのidを指定します。この使い方は特に問題ないと思います。ただし、#js-kv-sliderにスタイリングをするのはNGです。あくまでJavaScriptのフックのためのidです。

因みの僕はJavaScriptのフックもclass=”js-kv-slider”のようにclassで指定しています。従って僕の場合は、idを使うのはページ内リンクのためだけです。

CSSの命名規則

命名規則に関しては正解はありませんし、ルール化されていればなんでも良いです。好みの問題も大きいと思います。

ルール化されていればなんでも良いですが、その中で気をつけた方が良いことを紹介します。

classの単語名に困った時に参考になる記事も載せておきます。

命名規則は統一する

  • キャメルケース
  • スネークケース
  • ケバブケース

この3つは命名規則でとても有名です。

html
<!-- キャメルケース -->
<div class="cardTitle">...</div>

<!-- スネークケース -->
<div class="card_title">...</div>

<!-- ケバブケース -->
<div class="card-title">...</div>

どれを採用するかは好みの問題です。

html
<!-- アンダーバーを2つ使う -->
<h2 class="card__title">...</h2>

<!-- モディファイヤー(ハイフンを2つ使う) -->
<h2 class="card-title card-title--large">...</h2>

<!-- モディファイヤー(ハイフンから始まる) -->
<h2 class="card-title —large">...</h2>

また、後述しますが、CSS設計によっては、アンダーバーやハイフンを2つ使うものがあったり、ハイフンから始まるclassがあったりもします。

class名は意味のわかる名前にする

良い例
  • contact
  • kv-main-copy
  • submit-btn
悪い例
  • otoiawase
  • aaa
  • btn1

ローマ字や意味のない文字列は辞めましょう。

連番に関しては、ルールが決まってれば良いと思います。僕は1番目には連番は付けず、2番目から.hoge02のように付けるルールでやっています。

単語はできる限り省略しない

良い例
  • title
  • text
  • button
悪い例
  • ttl
  • txt
  • btn

わかるものは省略可としてる方もいると思うので、この辺も個人差はあります。

ただ、わかりやすいに越したことはないので、一切省略しないルールにしたほうがより無難ではあります。

見た目や場所ではなく意味でつける

良い例
  • footer-site-info
  • text-attention
悪い例
  • footer-left
  • text-red

もしかしたらやむ終えない場合もあるかもしれません。どうやっても色や場所でしか区別しようがない...なんてこともあります。

ただ、見た目や場所は後で変更になった時に、名前と合わなくなる可能性があります。出来る限り意味で付けるのがベストです。

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

マルチクラスとシングルクラスでどちらを採用するかも、各プロジェクトごとに統一させるべきです。

どちらが良いかはそのプロジェクトによります。マルチクラスの場合はHTMLが複雑になり、シングルクラスの場合はCSSが複雑になります。どちらもシンプルに書く方法はないので、トレードオフです。

マルチクラス

html
<div class="col-md-4 text-muted bg-success"></div>

マルチクラスとは1つの要素に対して、複数のclassを指定するものです。

BootstrapやTailwind CSSはマルチクラスです。

Tailwind CSSのスクリーンショット

こちらはTailwind CSSのサイト内で紹介されているサンプルです。ちょっと僕はHTMLがこんなことになるのは気持ち悪くて無理です。笑

管理画面など、コンポーネント(同じ見た目の部品)化できるパーツが多いサイトでは、マルチクラスで運用した方がコード量は少なく、綺麗に書けるかもしれません。

逆にページごとにレイアウトが大幅に変わるようなwebサイト制作では、マルチクラスだと上書きが多くなったり、classが大量にできてしまったりする可能性があります。

シングルクラス

html
<div class="header-item"></div>

シングルクラスとは1つの要素に対して、1,2つ程度のclassを指定するものです。

僕は元々web制作から始まってweb開発もやるようになったので、シングルクラスの方が馴染みがあります。後述する有名なCSS設計の1つであるBEMはシングルクラスです。

よく見るダメな書き方

よく見るダメな書き方を紹介します。

HTML・CSSの入門書でも平気でこれらの書き方をしていることもあるので注意が必要です。

要素セレクタに対して装飾している

css
p{
  text-align: center;
  font-size: 20px;
}

このように要素セレクタに対してCSSを書くと、全てのpタグにこのスタイルが効きます。

ある所では違う装飾をしたい場合、それを打ち消すために上書きする必要があります。結果、コードが複雑になり、コード量も多くなります。

リセットCSSを除けば、要素セレクタに対して装飾する必要があるケースはかなり限られます。

要素セレクタに対して装飾するケースの例

css
body {
    line-height: 1.8;
    font-size: 14px;
    color: #333;
    font-family: ...;
}

a {
    text-decoration: none;
    color: inherit;
}

img {
    width: 100%;
    height: auto;
    vertical-align: bottom;
}

HTMLに依存している

css
.contact > div > div{ ... }
.contact h2{ ... }

例えばこのようなコードがあるとします。

今は問題なくても、今後HTMLの修正が入った際にCSSも修正しないといけなくなる可能性があります。また、タイトルがh3に変わるケースも考えられます。

なるべく修正箇所が少なくなるように、CSSはHTMLに依存しない書き方をするべきです。

無駄に詳細度が複雑になっている

css
#service .service-item{}
li.service-item{...}

これらの書き方は詳細度を複雑にするだけで、良いことは何もありません。

css
.service-item{...}

このように基本は全て単体のクラスセレクタに対してスタイリングすれば、詳細度は複雑になりません。

サンプルを交えて代表的なCSS設計を紹介

  • OOCSS
  • SMACSS
  • BEM

ここではこれらの代表的なCSS設計を紹介します。日本で生まれたFLOCSSとPRECSSも使っている方が多いイメージです。FLOCSSとPRECSSに関しては最後の『おすすめの書籍や記事』で紹介します。

しっかり解説するとかなりの長さになってしまうので、概要だけ紹介します。興味がある方は公式のドキュメントなどで勉強してみてください。

独自のCSS設計を採用している方も、ここで紹介する考え方を一部採用していたり、組み合わせていることが多いです。

OOCSS

OOCSSはObject Oriented CSSの略で、オブジェクト指向にもとづいたCSS設計です。

Twitter、Github、Youtubeなどで採用されているCSS設計で、普段Bootstrapを使っている方は理解しやすいかもしれません。

レゴのパーツのようにはめていきながら、webサイトを作っていくような設計になっています。

  • 構造(structure)と見た目(skin)
  • コンテナ(container)とコンテンツ(contents)

OOCSSではこのような分け方をします。

例を用いて説明します。


構造(structure)と見た目(skin)で分ける

html
<button class="button submit">送信</button>
<button class="button return">戻る</button>
css
.button{
  width: 200px;
  height: 60px;
  line-height: 60px;
  ...
}

.submit{
  background-color: #333;
  color: #fff;
}

.return{
  background-color: #ddd;
  color: #333;
}
  • 構造:button
  • 見た目:submit / return

このように分けることになります。


コンテナ(container)とコンテンツ(contents)で分ける

css
/* NGな例 */
.contact button{
  ...
}

/* OKな例 */
.button{
  ...
}

コンテナ(container)とコンテンツ(contents)で分けるということは、使用する場所を限定させないということです。

NGな例では、.contactの中でしか使えず、再利用性出来ません。


  • 構造と見た目で分ける
  • コンテナとコンテンツで分ける

表現は違くても、これらの考え方は他のCSS設計でも使います。

デザインのルールがしっかり決まっているサイトはOOCSSのようなマルチクラスと相性が良いでしょう。

SMACSS

SMACSSはScalable and Modular Architecture for CSSの略で、OOCSSやBEMを参考に作られています。

  • Base
  • Layout
  • Module
  • State
  • Theme

SMACSSではコードをこの5つのカテゴリに分類します。

コードを役割ごとに分類する考え方は、他のCSS設計での採用されています。個人的にも分類はした方が良いと思います。

css
/* Base */
...

/* Layout */
...

/* Module */
...

/* State */
...

/* Theme */
...

コードを書く際は、このように分類ごとにコメントで区切ると良いでしょう。

5つのカテゴリについて紹介します。


Base

css
body {
    line-height: 1.8;
    font-size: 14px;
    color: #333;
    font-family: ...;
}

a {
    text-decoration: none;
    color: inherit;
}

img {
    width: 100%;
    height: auto;
    vertical-align: bottom;
}

デフォルトスタイルやリセットCSSなどが入ります。


Layout

css
.l-header{
  ...
}

.l-sidebar{
  ...
}

.l-footer{
  ...
}

.l-container{
  ...
}

headerやfooterなどのページのレイアウトを作る要素が入ります。接頭辞にはl-をつけます。


Module

css
.button {
  ...
}

.title {
  ...
}

.card {
  ...
}

再利用可能なパーツが入ります。モジュールはコンポーネントと同じ意味です。


State

css
.is-menu-active {
  ...
}

.is-text-hidden {
  ...
}

JavaScriptの操作などによる、特定の状態を示すスタイルが入ります。接頭辞にはis-をつけます。


Theme

css
.theme-dark {
  ...
}

サイトテーマを切り替えられるような仕様にする際に使います。接頭辞にはtheme-をつけます。

例えば、ダークモードに対応したサイトでは、ダークモード適応時にbody.theme-darkをつけて、スタイルを変更することになります。

BEM

BEMはBlock Element Modifierの略で、おそらく1番有名で使われているCSS設計手法だと思います。

  • Block:大枠となる独立した要素
  • Element:Blockを構成する要素
  • Modifier:バリエーションクラス

Block / Element / Modifierをどう区切ってclass名にするかは、人それぞれですが、Block__Element–-Modifierのように区切る方が1番多い気がします。単語の区切りはハイフンを使います。

html
<li class="header__item">トップ</li>
...
<li class="header__item">会社概要</li>
<li class="header__item header__item--contact">お問い合わせ</li>
  • Block:header
  • Element:item
  • Modifier:contact

この例ではこのように分類できます。Modifierでcontactを作ったのは、contactだけ重要なリンクとして他より目立つスタイリングをするためです。

👇 使用例です。

sample

html
<header class="header">
  <h1 class="header__logo">
    <img src="..." alt="...">
  </h1>

  <nav class="header__nav">
    <ul class="header__list">
      <li class="header__item">トップ</li>
      ...
      <li class="header__item">会社概要</li>
      <li class="header__item header__item--contact">お問い合わせ</li>
    </ul>
  </nav>
</header>

どこをブロックでどこをエレメントにするかの判断は人それぞれです。この例では、header__navをブロックと捉えて、header-navとするのも間違いではありません。ブロックの中にブロックが入ることも問題ありません。

ブロックとエレメントの分け方の基準として、参考になるサイトを載せておきます。

自分の関わるプロジェクトや好みに合わせてカスタマイズするのがベスト

CSS設計にはどのプロジェクトでも最適な唯一無二な正解はありません。

  • アニメーションが多いリッチなサイトを制作する機会が多い
  • 業務系の管理画面を作ることが多い

極端な話し、これらの2パターンでは、良いCSS設計は変わってきます。

この記事ではいくつか有名なCSS設計を紹介しましたが、それらをそのまま使っている方は少ない印象です。多くの人が少なからず、自分好みにカスタマイズしているのではないでしょうか。

勉強中の方はいきなりCSS設計を取り入れると混乱するかもしれません。いずれしっかり学ばないといけないこととして、頭に入れておくだけでも良いでしょう。

CSS設計に加えて、SCSSやタスクランナーも学べば、保守性も担保した上で効率の良い開発が出来るはずです。

こちらの記事では、コーディング学習教材の『模写修行』で採用する予定の具体的なCSS設計手法を紹介しています。(サービスのローンチは2021年6月予定)

おすすめの書籍や記事

おすすめの書籍や記事を紹介します。


書籍はこの2冊がおすすめです。この2冊を読んで、あとは実践で考えながらコーディングをすれば、”良い書き方”が見えてくると思います。

『Web制作者のためのCSS設計の教科書』を書いた谷拓樹さんはFLOCSSの考案者で、『CSS設計完全ガイド』を書いた半田惇志さんはPRECSSの考案者です。


吉本さん(@tsuDoi220)のサイトです。ここまで詳しく自分の手法を公開している方はいないと思うので、現役バリバリの方の方法を見れるのはとても参考になります。


TAKさん(@tak_dcxi)の500円の有料noteです。1から学ぶ系の記事ではありませんが、かなり実務向けで500円と価格も安いので、おすすめです。


はにわまんさん(@haniwa008)のzennの記事です。はにわまんさんはブログも運営しています。

駆け出しエンジニアのためのコーディング練習教材

Coming Soon
© 2021 模写修行 media.