【暫定】コーダー歴2年で辿り着いた保守しやすいコーディング手法

18 min read読了の目安(約16300字 2

未経験からコーダーとして仕事をし始めて2年が経過しました。

最初の頃はとにかくスピードややりやすさ、デザインの再現などを重視し、保守性は特に考えていませんでしたが、ページが多くなってきたり自分以外の人と一緒にコーディングする機会が増えるにつれ、当初とはまるで違う意識で書くようになった気がします。

自分のコーディング手法もまだまだ発展途上だとは思いますが、自分なりに保守しやすいであろうコーディング手法が確立されつつあるので、コーディングルールも兼ねて記事に残しておこうと思いました。

デザインが再現できればOKというコーディングから一歩進んだコーディングを目指す方の参考になれたら嬉しいです。

この記事の前提

コーディングに付随するいろんな用語が出てくるかと思いますが、詳しくは説明していません...。なので、今コーディングを勉強中であったり仕事でコーディングしたことない人にとっては、理解しづらい内容になっているかもしれません。

仕事でコーディングしたことあったり、CSS設計の概念が理解できている方でしたら、ちょうど読めるコンテンツになっている気がします。

また、コーディングに対する考え方がメインになっていて、具体的な手法はほぼ紹介していません。なので、こういう考え方もあるんだなって感じで読んでもらって、良さそうなところがあれば取り入れてもらえたらと思います。

基本的に紹介しているサンプルコードは、要素を標準化するリセットCSSが当たっていることが前提となっています。

用語

コンポーネントという言葉がたくさん出てくるかと思いますが、ホームページ内で使いまわしできるパーツの1単位といった感じで捉えてもらえたらと思います。

コーディングにおける保守しやすいとは?

コーディングにおける保守性の話は基本的にはCSSの保守と捉えても差し支えないほどにCSSの割合が高いです。

そんなCSSの保守のしやすさを表す指標として、「予測できる」「再利用できる」「保守できる」「拡張できる」の高さが挙げられます。
参考:https://philipwalton.com/articles/css-architecture/

  • 予測できる・・・クラス名からどういった振る舞いをするかが想像できる
  • 再利用できる・・・他の場所でも同じよう使いまわしできるパーツがある
  • 保守できる・・・要素を追加・削除した際に他の要素に影響を及ぼさない
  • 拡張できる・・・誰が携わっても同一の品質でコーディングできる

これらがベースとなり、CSS設計であったり、クラス名のルールが決められていたりするわけですね。個人的には再利用性を重要視していて、使い回しのしやすいコンポーネントが多くかつ参照しやすくなっていればいるほど、他の人が携わっても管理しやすいホームページになると思っています。

使い回せることが正義

コンポーネントはどこに配置しても影響を与えない粒度で設計してあげます。影響を与えないためには、

  • 幅や高さを持たせない
  • 外側に余白を持たせない
  • 要素タグに影響されない

主にはこの3つの考え方が重要になってきます。

コンポーネントはボタンや見出しなど、1つのパーツの単位ということで捉えてください。

幅や高さを持たせない

コンポーネントを作成したページでは、2行だったテキストが、他のページだと3行になるケースも往々にしてあります。その場合に高さや幅が固定されていると、文字がはみ出てしまったり、コンポーネントが崩れてしまうといった可能性が出てきてしまいます。

幅や高さは中の要素によって柔軟に変更できるように設計しておくことで、使われ方によって影響を受けない再利用性の高いコンポーネントにすることができます。

外側に余白を持たせない

コンポーネントの外側に余白をもたせてしまうと、他のページで余白なしで使いたいときに打ち消す作業が必要になってきます。基本的にコンポーネントは拡張することはあっても打ち消すことはない粒度で設計するのが好ましいです。

どこに顔を出しても悪影響を及ぼさないコンポーネントにするためにコンポーネント自体の外側には余白を持たせないように設計しましょう。

以下のコードで仮にボタン自体にmargin-top: 32px;としてしまってはサンプルに書いたような16pxでの表現が難しくなってしまいますよね。なのでコンポーネント自体に外側の余白に対する主張は持たせず、利用側で決めるようにしましょう

要素タグに影響されない

コンポーネントの中にh2タグなど特定のタグに依存してコンポーネントを作成してしまうと、他のページでh3タグで囲った場合に、コンポーネントが崩れてしまいます。

変更する可能性のあるHTML要素に対してCSSを当てる際は、HTML要素が変更されても問題がないようクラスを指定して、HTMLタグを変更してもコンポーネントの見栄えが変わらないように設計することが大切です。

コンポーネントはBEMの概念で作る

BEMはCSS設計の1つの技法ですが、BEMを覚えることでコンポーネントを作りやすくなるかと思います。覚えるといってもほぼ覚えることはないのですが...。

BEMを簡単に紹介すると、以下の3つの頭文字をとったCSS設計の考え方ですね。

  • Block ・・・ コンポーネントの単位となる塊
  • Element ... コンポーネントを構成する要素(これ自体は単体で動作しないし、コンポーネントにならない)
  • Modifier ・・・コンポーネントのあしらいを変えた別パターンの定義

先ほどのカードは、まさにBEMで書いた例になります。

cardがBlock、card__imgcard__titleといった2つのアンダースコアで繋がれた要素がElementの役割となります。

このように、Blockを定義し、Blockを構成する要素を2つのアンダースコア(__)で繋げてコンポーネントしてまとめるのがBEMの書き方です。Blockがコンポーネントの1つの単位になるようなイメージとなります。

ちなみにModifireは別パターンのような意味で捉えてもらえればOKです。2つのハイフン(--)でつなぎ、色などの別パターンを作ることができます。

(背景色とボーダー色を変えたパターン)

BEMでBlockを作る際に意識すること

BEMはコンポーネントを作る基本となります。Blockで定義するところはコンポーネントの単位となる部分です。ボタンであったり、カードであったり、見出しであったりするわけですね。

そして、Elementでコンポーネントを構成する子要素を明示しますよね。子要素だからといって、なんでもかんでもElementにするのではなく、親のBlockを起点に考えたときに、本当に直近の親はそのBlockでいいのかの指標として考えることが重要です。

BlockとElementの関係性が正しくマッチしているかを考える癖をつけることで、最適な粒度でコンポーネントを作ることができるようになると考えています。

BlockとElementの関係だけでも理解できればBEMは概ねOKです!(わたしの基準、低い...)

Blockで定義する基準

コンポーネントの粒度を決めるのは自分なので、全部をElementで定義することもできれば、ほぼすべての要素をBlockにすることもできてしまいます。

適切な粒度の判断は難しいと思いますが、1つの基準として自分が設けているのは、Elementが入れ子になりそうになったらBlock化するというものです。

例えば、一覧用のアイテム群があって、その中のアイテム、その中のリンクってなったとして、Elementが.cardsの起点でなくなったときにBlock化することを検討しています。

.cardsを起点に考えたら以下のような作りになりそうだ...、ってなったら__linkの親である.cards__itemをBlock化できないかと考えるわけですね。

  • .cards
  • .cards__item
  • .cards__item__link

.cards__linkのように書けばいいのでは?と思う方もいるかもしれませんが、Elementを作る際は、どのBlockが起点となっているか常に意識すること大事です。

「一覧をもっと見る」のような役割のリンクであれば、.cards__linkも正しいと思いますが、.cards__itemごとのリンクを示している場合は、.cards__itemに対するリンクと考えるべきで、.cards__itemのElementとしてBlock化した作りにしてあげると、自然なコーディングとなるはずです。

日本語で表現するなら、「〇〇(Block)の〇〇(Element)」が成り立つと思っています。(__は「〜の」と捉えています)

「カード群のアイテム」は自然ですが、「カード群のリンク」という表現は、果たして配置場所と日本語の表現が一致しているかで判断できるはずです。「カードのリンク」の方がしっくりくるならカードをBlock化したほうがいいといった感じですね。

先ほどの画像の例だと、自分は以下のようにクラスを設計します(1つのカードに対する〇〇の要素という考え方ですね)

外側の余白を定義できるのはElementだけ

Blockはコンポーネントの塊なので、外側に余白を持たせません。外側の余白はどこで持つかというと、Elementの部分ですね。

なので、Blockの外側に余白を作りたくなったら、Blockの外側を囲むBlockを作成して余白を与えたいBlockに対してElementを定義してあげればOKです。

先ほどのカード群の例だと、わたしなら以下のように書きます。

.cardというBlockをコンポーネントとして用意しておき、.cardsというBlockのElementとして配置するようなイメージです。.cardsのElementで余白を調整していることが分かるかと思います。

さらに新たなBlockである.cardsにも外側の余白を付けていないことに注目してください。このようにBlockに対して外側の余白を付けないことで、Elementに付与しやすく余白のつけしろがあるコンポーネントを作ることができるようになります。

こういった感じで、Blockでコンポーネントを作成しつつ、Block間のレイアウトを調整したい場合はさらに大きなBlockを用意してElementで余白を調整していくという方法が基本的なHTML、CSSの組み方となります。

余白をつける要素に配慮する

Elementに余白を付けていくのですが、保守性を考えると余白を付ける方向も意識するといいかもしれません。以下の状態になったときも見栄えが崩れないかを考えて余白の向きを決めていきます。

  • 消える可能性がある方
  • 改行しても影響のない方

例えば、日付とラベルが横並びになったコンポーネントがあったとして、日付側から余白を与えるか、ラベル側から余白を与えるか、どちらから付けるべきでしょうか...?

個人的には、ラベル側から余白を与えると、仮にラベルが改行されてしまったときに右側に不自然な余白が付いた状態になってしまうので、以下のように日付側から押してあげるのがいいかなと思っています。

コンポーネント → 大きめのコンポーネント → レイアウトの順番で作る

小さいBlockを大きいBlockで覆いながら1つのページができていくような感覚です。

まずは、使いまわせそうな最小単位のBlockを作っておきます。次に、BlockをまとめたBlockも使いまわせそうなら作っておきます。カードを束ねたカード集みたいなコンポーネントですね。

さらに大きなBlockの単位としてセクションのレイアウトBlockであったり、ページのレイアウトBlockでコンポーネント化していくといった流れになります。

大量のブロックが入れ子になったり、それぞれのBlockのElementで余白を調整したBlock群でまとまっているのが1つのページというイメージです。

具体的なコンポーネントで紹介すると、以下のようなイメージですね。

  1. ボタン
  2. ボタンを内包したカード
  3. カードを内包したカード群
  4. カード群を内包したセクション
  5. セクションを内包した下層コンテンツ

ボタン

ボタンはこれ以上分割できないレベルの最小単位のコンポーネントですね。BEMでBlockを作る際にElementが存在しないと思いますが、そのレベルのBlockは最小単位と捉えていいかと思います。

ボタンを内包したカード

先ほど作成したボタンを内包する形でカードを作成しています。

カードを内包したカード群

カードを並べたカード群も他のページでも使いそうなコンポーネントですね。カードのコンポーネントを束ねる形でカード群のコンポーネントは出来上がっています。

カード群を内包したセクション

カード群を内包する形でセクションが作られたりしています。見出しとカード群、もっと見るボタンの位置関係を整える意味でコンポーネント化してしまいます。

セクションを内包した下層コンテンツ

画像は省略していますが、、、下層コンテンツはセクションのコンポーネントをまとめたコンポーネントと考えます。小さい単位から積み上げるイメージでどんどんコンポーネントを大きくしていくような形で1つのページが出来上がっていきます。

Blockにはコンポーネント目的とレイアウト目的の2つがある

この感じで実際にコーディングしていると、汎用的でなさそうなBlockがたくさん出来上がることが分かります。

最小単位から2つ目(か3つ目)くらいまでが現実的に使い回せるコンポーネントですが、4つ目や5つ目で作られるBlockは、よほどホームページ全体のデザイン設計ができていない限りはあまり使い回すことはなかったりします...。

Blockには大きくは2種類あると考えています。

  • コンポーネント目的
  • レイアウト目的

コンポーネント目的のBlock

コンポーネント目的のBlockは、今までずっと紹介してきたように、ページをまたがっても使い回せるような汎用的なコンポーネントですね。

汎用性のある単位で設計し、どこでも使いやすいように余白を付けなかったりするわけですね。

レイアウト目的のBlock

そして、もう一つ必要なBlockとしてレイアウト目的のBlockがあります。これは、使い回せるなら使いましますが、主にはコンポーネント目的のBlockの位置調整に使う目的ですね。

外側の余白はElementしか付けられないルールがあるので、余白の調整のためにこういったブロックも必要になってくるということですね。

セクション用のレイアウトは使い回せる可能性もあるかもしれませんが、ページ毎に共通のレイアウトってほぼないので、基本的にはページ単位でページ内のコンテンツを調整するためのレイアウトBlockが作れられるイメージです。

Modifierの使いどころ

Modifireも使い方を間違えると逆に複雑なCSSが出来上がってしまいます。条件を加えすぎて、いろんなパーツに派生しすぎると、つけ外しの判断が難しくなるからですね...。個人的には役割が明確なコンポーネントがたくさん合ったほうが管理しやすいなって思います。

Modifireで条件を加えたい際は、以下の基準で考えるといいかもしれません。

  • 見栄えを変える → OK
  • 構造を変える → NG

見栄えを変える

見栄えに関して具体的には以下のようなCSSプロパティですね。色違いのボタンであったり、アイコン違いのボタンを定義する際はModifireが丁度いいと思います。

  • background
  • box-shadow
  • border-color
  • color
  • など

逆にこれ以上のプロパティの変化をさせるなら新たにコンポーネントとして定義したほうがCSSがゴチャゴチャになりづらく、あとあとも使い回ししやすいコンポーネントになるかと思います。

構造を変える

構造を変えるものは基本的にはしないほうがいいかと。影響の及ぶ範囲でModifireによって対応できる変化の度合いが大きくなりすぎてしまいためですね...。

  • width
  • height
  • line-height
  • margin
  • padding
  • border-width
  • など

こういったものを変化させる場合は、新たにコンポーネントを用意したほうが無難です。

ただし、レイアウトを変更するだけの役割であればOKです。例えば、2カラムを1カラムにするためのModifireであったり、左右の配置を反転させるためのModifireなどです。

こういった役割が明確で限定的にできるModifireであれば使っていったほうがいいと思います。

親Blockから子Block(最小単位)への上書きは許容範囲

親Blockに内包された最小単位のBlockの書き換え程度は別に問題ないのかなと思ったりしています。使い所によって、ボタンの大きさを○pxにしたいとか、文字サイズをちょっと小さくしたい、、、とか出てくるかと思います。

ちょっとした違いを構造的に変更したい場合は、親Blockから上書きするような形で作ることが多いです。

BEMとコンポーネントの概念のまとめ

長くなってきたので、一旦まとめます。

  • コンポーネントの単位はBEMのBlock
  • BEMの作り方(特に親子関係)を理解する
  • 再利用できるBlockから作る
  • 外側の余白は原則Elementだけが持てる
  • Blockを大きなBlockで囲んで、さらに大きなBlockで囲んでの繰り返しでページが出来上がるイメージ

次からはより具体的なファイル名やフォルダ構造などの話です。

CSSのクラス名はどう決める?

CSSの保守しやすさの1つにある「予測しやすい」のほとんどはCSSのクラス名に集約されると思います。なので個人的に略すのは基本NGです。

単語を略して意図が分からないよりは、長いけど内容が分かるほうがいいと思っています。

命名規則はFlocssをベース

個人的にはFLOCSSが最も馴染みやすかったです。日本人の方が考案されていて、ドキュメントも日本語なので馴染みやすいと思います。
FLOCSS → https://github.com/hiloki/flocss

クラス名に役割に応じた接頭辞をつけるところが特徴です。

  • レイアウト ・・・ .l-hoge
  • コンポーネント ・・・ .c-hoge
  • プロジェクト ・・・ .p-hoge

といった感じですね。

接頭辞を見るだけで、どういった役割のブロックかがひと目で分かるようになっています。コンポーネントはAtomicデザインで言うところの「atom」に相当する部分と捉えて役割を分けるといいかもです。分かりづらい人は、ボタンと見出しはコンポーネントという分け方でも十分だったりします。
Atomicデザイン → https://bradfrost.com/blog/post/atomic-web-design/

アンダーバー2つ(__)はElement

FLOCSSはBEMと同じ命名規則なので馴染みやすいです。.p-cardというBlockに対して見出しエリアを定義するなら、.p-card__headingといった感じです。

ハイフン(-)は単語の区切り

ハイフンは単語の区切りを表します。メインビジュアルのレイアウトを定義する際は、.l-main-visualとして、.main-visualの単語が1つの言葉であることを定義しています。

ハイフン2つ(--)はModifire

ハイフンを2つ後ろに付けると、Modifireを意味します。例えば、.p-cardが選択された状態を定義したい場合は、.p-card--activeのようなクラスを定義します。

Modifireは、.p-cardに対するふるまいの追加なので、CSSで定義する際は.p-card.p-card--activeとして上乗せすることが自然だと自分は考えています。

省略は禁止

BEMのネーミングルールで作っていると、Blockに対するElementという構図は揺るがないため、Sassの&で繋ぐ書き方があったりします。

個人的にこの書き方はあまり好きではなく、理由としては3点です。

  • 入れ子が1つ深くなることが確定する
  • クラス名のファイル検索で見つけづらい
  • 親クラスの状態変化から参照しづらい

ELementに対してブレークポイントの入れ子が入ることもほぼ確定なので、&で入れることで、3階層までが確定しまいます。

Block分けがしっかり出来ていればファイル名から辿れると思いますが、Block内のElementを探すのが手間で、クラス名から一発でたどり着いてくれほうが個人的には楽です。

Sassの入れ子が個人的にはあまり好きではなく(それがメリットかもしれませんが、、、)、自分はElementをBlockと並列で書きます。同じファイル内でBlockの後ろに書いておけば問題ないので。こうやって入れ子が複雑にならないように気をつけつつ、親からの状態変化があった際も以下のような参照の仕方で状態を管理することができます。

.p-block__element {
	.is-active & {
		/* hoge */
	}
}

1つのBlockに対して1ファイル

クラス名によって起こりうる問題の最たるものがクラス名の衝突ですね。クラス名かぶりを回避するために、あの手この手でCSS設計の命名規則が考えられているわけです。

クラス名かぶりを物理的に防ぐ方法の1つとして、ファイル名として定義しちゃうというものがあります。

ファイル名が被るとエラーになりますよね。その特性を利用すれば、被ったクラス名を作った際に物理的にアナウンスが出て気づくことができます。

この方法を取ってから、クラス名が被っているかどうか心配することがなくなりました。一方でファイル名が多くなりすぎるので、そこは仕方ないところであります...。

(案件ご一緒した時にまささんに教えてもらいました。ありがとうございます!)

Block毎にSassファイルを分ける管理上のメリット

さらにBlock毎にSassファイルを分けることで、複数人で管理してもバッティングしづらくなるメリットがあります。例えば、複数人で新規でコーディングする際も、

  • 使い回せるBlockがあればそのまま使う
  • 新たなブロックがあればBlockファイルを新規追加

といった運用ができるため、同時にコーディングしていても1つのファイルでバッティングする可能性が少なくなります。

Block単位でのコーディングとBlockに対して1ファイルの作り方は、複数人でコーディングする場合にも威力を発揮するものと思っています。

FLOCSSの接頭辞の決め方

  • コンポーネント目的のBLock
  • レイアウト目的のBlock

の2つがあると紹介しました。

FLOCSSの接頭辞でいうと、他のページでも使い回せるコンポーネント目的のBlockは、.c-.p-で作り、レイアウト目的のBlockは.l-で組むような感覚です。

.c-.p-の違いは、.c-だけがやんわり決まっていて、ほかは.p-に突っ込むイメージです。

  • .c- ... これ以上分解できないような最小コンポーネント(Elementがないようなコンポーネント)か、それに近いコンポーネント
  • .p- ・・・ .c-以外のコンポーネント目的のBlock

ページごとにレイアウトを作る

.l-でBlockを作る際はそれほど汎用性を考えていません。どちかというと、デザインカンプを再現するためにページごとにしっかり定義してあげます。

ヘッダーやフッターなどの共通パーツを除けば、下層のコンテンツ内のレイアウトが余白まで他のコンテンツと統一して設計されていることはあまりないような気がしていて、ページごとに調整できるようにページを示す.l-page-nameのような形でコンテンツを覆って調整すると作業しやすくなるかと思います。

JavaScriptと紐づく要素はjs-の接頭辞

JavaScriptの起点となるIDやクラスは.js-という接頭辞をつけてJavaScriptが関わっていることを明示します。

JavaScriptと関わる要素は重要な要素であるため、不用意なクラスの削除(変更)を防ぐ目的があります。また、CSSとの役割を分けるため、js-の接頭辞にはCSSのスタイルは当てないこととしています。(JavaScript内で参照して変更はOK)

スマホ時のドロワーメニュー等を無理に1ソースにする必要はない

HTMLで1ソースになることが理想ですが、条件分岐がごちゃごちゃしたり、処理が複雑になるのは返って保守性を低くしている気がするので、無理に1ソースにする必要はないと思っています。

CSSやJavaScriptでの管理のしやすさ、読みやすさを重視して、HTMLの方を諦めるようなイメージでいます。

外部ライブラリ参照の際もjs-の接頭辞と、上書き用クラスの指定

外部ライブラリを用いて動作を定義する際もjs-の接頭辞を使って参照するようにします。マニュアルのまま参照してしまうと、同様のパーツが複数あったときにバッティングしてしまう可能性が高いからですね...。

また、ライブラリが用意したCSS値を変更する場合も独自のクラスを付与します。理由は上記と同様で、複数のパーツを配置したときに最初に定義したクラスに影響を受けてしまうからです。

意図しないバッティングを防ぐために、ライブラリで参照するクラス名をjs-で定義することと、独自のクラス名の定義は行ったほうが無難だと思います。

Sassで共通定義する値

個人的にSassで最低限で定義しておくべきだと思う値です。

インナー幅

インナー幅とは平たく言うと、PC画面時に担保する幅ですね。基本的にはページ間で共通した値のはずなので、定義して使い回せるようにしておきましょう。

ブレークポイント

ブレークポイントは全体で共通で定義して使う値です。以下のように定義しておけば、各BlockやElementに対して共通で使うことができるようになります。

以下のような感じで定義して使います。

$layout-width-inner: 1024px;
$breakpoints: (
  "sp": "screen and (max-width: 767px)",
  "tab": "screen and (max-width: #{$layout-width-inner - 1px})",
  "pc": "screen and (min-width: #{$layout-width-inner})"
);

@mixin mq($breakpoint: sp) {
  @media #{map-get($breakpoints, $breakpoint)} {
    @content;
  }
}

.hoge {
  font-size: 16px;
	
  @include mq("sp") {
    font-size: 12px;
  }
}

重なり順(z-index)

ごちゃごちゃしがちなので、要素が重なる順番ですね。これはブロック単位で重なり順を定義しておくと管理が楽になります。

レイアウト単位で浮く要素を洗い出し、それぞれにz-indexの値を定義しておくような感じですね。

  • ヘッダー
  • フローティング(トップへ戻る)
  • ドロワー
  • スマホ時のフッターメニュー
  • モーダル

自分は$layerで一括で定義しておき、入れ替えたい場合はこの定義値を変更することで簡単に変更することができるようになっています。

$layer: (
  modal: 100,
  drawer: 40,
  sp-menu: 35,
  floating: 30,
  header: 20,
  default: 1
);

.hoge {
  z-index: map-get($layer, "header");
}

また、ドロワーの中でもハンバーガーアイコンとドロワーコンテンツ、背景エリアなどでも重なり順があるかと思いますが、ここはブロック内での相対的な順番なので、共通定義したドロワーの値からz-index: map-get($layer, "drawer") + 1;あるいはz-index: map-get($layer, "drawer") - 1;などして制御しています。

メインカラーとアクティブカラー

色については、以下の3点だけあれば十分という印象です。

  • メインカラー
  • アクティブカラー
  • ベーステキストカラー

ほかも細かく指定したい気持ちは分かりますが、あとになって影響範囲が読みづらいのが正直なところです。なので、変更したときに全体が変わっても問題ない範囲でカラーなりを設定するのがいいと思います。

上記3つはホームページ全体で確定して決めているはずなので、定義しておくべき色になります。

英字フォント

フォントについては、上書きの可能性のある(かつ変更の可能性のある)英字フォントは変数として持っておき一括で変更できるようにしておくと便利です。

$font-english: sans-serif;

.hoge {
  font-family: $font-english;
}

画像

画像の拡張子については、以下のようなルールでやっています。

PNG

背景が透過している画像を扱う場合。

JPG

背景が透過されていない画像。背景透過が必要ない画像は全部JPG。軽い(らしい)から。

SVG

HTMLでインライン的に使いたい場合のインラインsvgはOKですが、画像の扱いで使う場合は基本はpngにしています。svg画像による非表示などので不具合が起こる場合があって原因探しが面倒くさいので、、、。

どうしてもsvg画像でないと駄目な部分のみsvg拡張子としています。

画像のファイル構造

画像には以下の2つがあります。

  • ホームページ全体で共通で使う画像
  • 特定のページだけで使う画像

ファイルの分け方としては、以下のような感じで配置できるとアクセスしやすくなるかと思います。

  • /img/
    • /common/ ・・・ 共通で使う画像
    • /page01/ ・・・ page01だけで使う画像
    • /page02/ ・・・ page02だけで使う画像

複数ページあるようなサイトだと/img/直下には何も置かない方が役割が明確になって管理しやすいです。

Sassのファイル構造

基本的にはFLOCSSに則ったファイル構成となります。

  • setting ・・・ 変数の定義
    • _color.scss ・・・ 色の定義
    • _size.scss ・・・ 大きさの定義(幅やz-indexなど)
    • _typography.scss ・・・ フォントの定義
  • function ・・・ 関数やmixinの定義
  • foundation ・・・ リセットCSSの役割
  • layout ・・・ レイアウトBlockの定義(インナー幅など)
  • component ・・・ コンポーネントBlockの定義(ボタンや見出しなど)
  • project ・・・ プロジェクトBlockの定義(その他Blockすべて)
  • external ・・・ 外部クラスを上書き(定義)する用(WordPressのクラスとかライブラリのクラスのベースの上書き)
  • utility ・・・ 汎用クラスの定義
  • style.scss ・・・ 1つにまとめるSassファイル

layoutやcomponent、projectの中は1Blockに対して1ファイルが格納されていくようなイメージです。特にprojectの中はめちゃくちゃファイル数多くなります...笑

コンパイル後は納品用ファイルだけ出力

フロントエンドエンジニアにとっては当たり前にやっていることだと思いますが、自分は最初のころできていなかったので、一応共有します。

コーディングするにあたって、SassやEJS、node_modulesなど開発用のファイルがたくさん生成されると思います。コンパイル後にこれらのファイルと混ざって出力させてしまうと、納品用のファイルがどれか探すひと手間が発生してしまいます。

ということで、納品用のファイルは特定のフォルダにまとめて吐き出しましょう、という当たり前の話です。

静的なHTMLファイルの場合は、/public/のようなフォルダを用意してHTMLファイル、CSSファイル、JavaScriptファイル、画像など必要なものをコンパイル時に格納されるようにしてあげましょう。

WordPressの場合は、コンパイル時のテーマファイルが生成されるように、1個手前のthemeフォルダを管理すると運用しやすくなりました。開発用のファイルはthemeフォルダに格納されているようなイメージですね。

どういったタスクランナーの記述をしているかは、冗長になる気がするので、また別の記事で書けたらと思います。

おわり

思いのほか長文になってしました...。

今と2年前が全然別の考え方であったように、コーディングの考え方は今後も変わり続ける気はしますが、コーダー歴2年目のリアルな考え方を書いてみました。

たぶん今後も基本となるのは、この考え方で、

  • 予測できる・・・クラス名からどういった振る舞いをするかが想像できる
  • 再利用できる・・・他の場所でも同じよう使いまわしできるパーツがある
  • 保守できる・・・要素を追加・削除した際に他の要素に影響を及ぼさない
  • 拡張できる・・・誰が携わっても同一の品質でコーディングできる

特に再利用のしやすい設計のサイトはめちゃくちゃ管理しやすいなって思います。

基本的な説明のないまま書いていたので、初心者の方には難しかったかもしれませんが、今コーディングしていて、デザインが再現できればOKから一歩進んだコーディングを目指す方の参考になれたら嬉しく思います。

この記事に贈られたバッジ