HTML
CSS

コーディングガイドライン草案

HTML

  • 拡張子は「.html」
  • 文字コードはUTF-8(BOM無し)
  • 改行コードはLF
  • インデントはタブスペース(半角4文字分)が好ましい。が、開発環境次第(Codekitだと半角スペース2つになってしまう)。
  • ファイル名は半角英数字。単語の区切りを「-」にするか「_」にするかは案件次第

CSS

ファイル構造

  • ファイル、ディレクトリ名は半角英数字と「_」
  • 読み込むファイル数は少なく。ツールを使って1つにすることも検討する。裏側でファイルが複数ファイルで管理されている分には全く問題ない。
/css/
/css/pc/
/css/pc/common.css
/css/sd/
/css/sd/common.css

クラス名のルール

  • 後述する接頭辞を必ず付ける。
  • 単語と単語の区切りは「_」。「.p_commonHeader」のようにはしない。「.p_SNSList」など頭文字を連結して作られている単語が読みにくいから。こういうときは「.p_common_header」「.p_sns_list」のように「_」で区切る。

接頭辞(名前系)

「接頭辞(名前系)は<body><div><span>にしか付けることができない」というルールを採用するか検討中。無駄にDOMが深くなるだけならやらない。

.pn_xxxxx

「ページ名(Page Name)」を表します。ページ名クラス。

<body class="pn_index">...</body>

原則<body>につけます。
そのページ内で最上位に位置する場所に記述します。

このページ名クラスは、サイト内でユニークになるようにします。
URLと合わせると自然とそうなるはずです。

これ自体にCSSを定義してはいけません。
適用範囲の絞り込みにのみ使います。

.gn_xxxxx

「グループ名(Group Name)」を表します。グループ名クラス。
原則<body>に、ページ名クラスと一緒に付けます。

<body class="pn_news_top gn_news">...</body>

これは例えば

/news/
/news/list/
/news/detail/

上記のようなURL構造を持ったニュースというコンテンツがあるとき

<body class="gn_news pn_news_top">...</body>
<body class="gn_news pn_news_list">...</body>
<body class="gn_news pn_news_detail">...</body>

のようにつけることで、ニュースコンテンツに共通で適用するCSSを定義できるようになります。

これ自体にCSSを定義してはいけません。
適用範囲の絞り込みにのみ使います。

div[class^="pn_news_"]{}

のように、クラス名の前方一致を使えば、グループ名は不要ですが、前方一致はパフォーマンスが悪くなるといわれているので避けました。
気にする程の影響があるのかは調べてないので不明。

.cn_xxxxx

  • 「コンテント名(Content Name)」を表します。コンテント名クラス。
  • 「.cn_xxxxx」は<div>にしかつけられないこととします(後述)。
<div class="lo_stage pn_news_top .gn_news">
    <div class="lo_stage__header">
        <div class="lo_content cn_header_content">...</div>
   </div>
   <div class="lo_stage__body">
        <div class="lo_content cn_news_list">...</div>
        <div class="lo_content cn_news_ranking">...</div>
        <div class="lo_content cn_news_archive_nav">...</div>
   </div>
   <div class="lo_stage__footer">
        <div class="lo_content cn_footer_content">...</div>
    </div>
</div>

コンテントとは、コンテンツ部分に、ある程度独立して定義できるブロックです。
上記は例としてニュースコンテンツのトップページを定義。
メインコンテンツに新着記事リスト(.cn_news_list)、記事ランキング(.cn_news_ranking)、記事アーカイブへの導線(.cn_news_archive_nav)をコンテントとして定義しています。

<ul class="cn_xxxxx">
    <li><a href="#">A</a></li>
    <li><a href="#">B</a></li>
</ul>

たとえ、コンテントの中身がリストだけだったとしても

<div class="cn_xxxxx">
    <ul>
        <li><a href="#">A</a></li>
        <li><a href="#">B</a></li>
    </ul>
</div>

必ず<div>でラップし、それにコンテント名クラスを付けます。

これ自体にCSSを定義してはいけません。
適用範囲の絞り込みにのみ使います。

接頭辞(レイアウト系)

.lo_xxxxx

レイアウトを表すクラス名です。
現状は.lo_stageと.lo_contentしかありません。

.lo_stage

.lo_stageは、原則変わることのないサイトの骨格に使います。

<div class="lo_stage">
    <div class="lo_stage__header">
        <div class="lo_stage__header_inner">
                        (ヘッダー)
            <div class="lo_stage__section">コンテント</div>
        </div>
   </div>
   <div class="lo_stage__body">
                (ボディ=コンテンツ部)
        <div class="lo_stage__body_inner">
            <div class="lo_stage__body_main">
                (メインカラム)
                <div class="lo_stage__section">コンテント</div>
                <div class="lo_stage__section">コンテント</div>
                <div class="lo_stage__section">コンテント</div>
            </div>
            <div class="lo_stage__body_sub">
                                 (サイドバー)
                <div class="lo_stage__section">コンテント</div>
                <div class="lo_stage__section">コンテント</div>
                <div class="lo_stage__section">コンテント</div>
                <div class="lo_stage__section">コンテント</div>
            </div>
                </div>
   </div>
   <div class="lo_stage__footer">
        <div class="lo_stage__footer_inner">
                       (フッター)
            <div class="lo_stage__section">コンテント</div>
        </div>
    </div>
</div>

上記はPC版を想定、ヘッダー、コンテンツ部、フッターで、コンテンツ部はメインコンテンツとサイドバーを持ちます。

<div class="lo_stage">
    <div class="__header">
        <div class="__inner">ヘッダー</div>
   </div>
   <div class="__body">
        <div class="__inner">
            <div class="__main">メインコンテンツ</div>
            <div class="__sub">サイドバー</div>
                </div>
   </div>
   <div class="__footer">
        <div class="__inner">フッター</div>
    </div>
</div>

上記のように記述しても問題ないです。
上記のように書いた方がHTML的には見やすいし、ファイルサイズも小さくなります。
が、

.lo_stage{}
.lo_stage__header{}
.lo_stage__header_inner{}
.lo_stage__body{}
.lo_stage__body_inner{}
.lo_stage__body_main{}
.lo_stage__body_sub{}
.lo_stage__footer{}
.lo_stage__footer_inner{}

前者のHTMLに対するCSSが上記で、

.lo_stage{}
.lo_stage > .__header{}
.lo_stage > .__header > .__inner{}
.lo_stage > .__body{}
.lo_stage > .__body > .__inner{}
.lo_stage > .__body > .__inner > .__main{}
.lo_stage > .__body > .__inner > .__sub{}
.lo_stage > .__footer{}
.lo_stage > .__footer_inner{}

後者のHTMLに対するCSSが上記になります。
個人の趣向で前者にします。

.lo_stageの構成要素
.lo_stage
.lo_stage__header
.lo_stage__header_inner
.lo_stage__body
.lo_stage__body_inner
.lo_stage__body_main
.lo_stage__body_main_inner
.lo_stage__body_sub
.lo_stage__body_sub_inner
.lo_stage__footer
.lo_stage__footer_inner

※「 inner 」は必要に応じて。
※「 main 」「 sub 」は必要に応じて。(mainは1カラムのときでも書いておいた方が良いとは思う)

.lo_content

.lo_contentは.lo_stageのコンテンツとして収まるブロックです。
 <section>に近いものになります。
.lo_contentは必ず

DOMの深さは最小限に

CSSのセレクタは定義の右側から探される。

<div class="lo_stage pn_news_top">
    <div class="lo_stage__header">
        <div class="lo_content cn_header_content">...</div>
   </div>
   <div class="lo_stage__body">
        <div class="lo_content cn_news_list">...</div>
        <div class="lo_content cn_news_ranking">...</div>
        <div class="lo_content cn_news_archive_nav">...</div>
   </div>
   <div class="lo_stage__footer">
        <div class="lo_content cn_footer_content">...</div>
    </div>
</div>

コンテンツ部で各コンテントを定義するのに使う他、ヘッダーやフッターの中身も1つのコンテントとして扱うのが良いと思います。

.lo_stage__header .p_site_name
.lo_stage__header .p_site_description

のようにヘッダーの中身をヘッダーという構造物の1部として定義するのに違和感があります。

.lo_stage__header .cn_site_header .p_site_name
.lo_stage__header .cn_site_header .p_site_description

のように.cn_site_headerの子要素としてまとめます。

「.lo_stage」は棚で、「.lo_content」は棚に置くものです。
キャビネットの中に小物入れやファイルを置くイメージです。

.lo_content{}

.lo_content__header,
.lo_content > .__header{}

.lo_content__body,
.lo_content > .__body{}

.lo_contentは直接の子要素に.lo_content_header,.lo_contentbodyを持つことが可能です。
.lo_content
header,.lo_content_bodyのいずれも使わないという選択も可能です。

.lo_list

.lo_list > ul
.lo_list > ul > li
.lo_list
.lo_list__item

.lo_item

.lo_item
.lo_item__main
.lo_item__sub

接頭辞(パーツ系)

.p_xxxxx

パーツ名を表すクラスに使います。

<p class="p_description"></p>
<ul class="p_list">
<li>
<a href="#">aaaaaaaa</a>
</li>
<li>
<a href="#">aaaaaaaa</a>
</li>
<li>
<a href="#">aaaaaaaa</a>
</li>
</ul>
.cn_xxxx .p_xxxx{}
.pn_xxxxx .cn_xxxxx .p_xxxx{}

CSSで定義する場合には、必ず「.cn_xxxx」の子要素として定義します。
これにより、少なくとも他の「.cn_xxxx」配下のパーツに影響が及ばなくなります。
意図しない継承や競合が起きにくくなります。

.cn_xxxx .p_section_heading{
  font-size: 2.0rem;
  font-weight: bold;
  text-align: center;
}
.cn_yyyy .p_section_heading{
  font-size: 2.0rem;
  font-weight: bold;
  text-align: center;
}

仮に上記の「.cn_xxxx」と「.cn_yyyy」の「.p_setion_heading」が全く同じものであっても、それぞれ個別に定義します。
この辺りはSassを使ってカバーします。

.cp_xxxxx

共通パーツを表します。
サイト内のどこでも使えるパーツです。

.cp_pager{}
.cp_breadcrumb_nav{}
.cp_share_btn{}

「.p_xxxx」とは異なり、「.pn_xxxx」「.cn_xxx」の子要素として定義する必要はありません。
むしろそのように定義してはなりません。

.cn_news .cp_pager{}

のように定義した場合は、共通パーツをオーバーライドすることになります。

.p_pager{}

という定義は禁止です。
表記上、共通パーツ扱いになりますが、これだと「これは使いまわせるパーツなのか?」ということがすぐにわかりません。

.u_xxxxxx

ユニットを表します。
複数のパーツから構成されるパーツです。

<div class="u_pager">
    <div><a href="" class="cp_pager__prev"></a></div>
    <div>
        <ul class="cp_page_numbers">
            <li><a href=""></a></li>
            <li><a href=""></a></li>
            <li><a href=""></a></li>
        </ul>
    </div>
    <div><a href="" class="cp_pager__next"></a></div>
</div>

例えばページャーです。
ページャーの最低構成要素は「前へ」「次へ」のリンクだと思います。
「1|2|3|4|5」のようなナビゲーションはオプションと考え、別のパーツとして定義します。
「前へ」「1|2|3|4|5」「次へ」のような構造のパーツの場合も十分にあるので、
この場合は「.u_pager」という複合パーツとして定義します。

.cp_pager{}
.cp_page_numbers{}

.u_pager .cp_pager{}
.u_pager .cp_page_numbers{}

「.cp_pager」と「.cp_page_numbers」はそれぞれ、独立して使える形で定義しておいて、
「.u_pager」で拡張します。

.cu_xxxxxx

共通ユニットを表します。
(必要か検討中)

.js_xxxxx

<a href="javascript:void(0)" class="js_toggle_menu">MENU</a>

JSで使うクラス名です。

<ul class="p_tab js_switch_tab">
  <li class="_is_current"><a href="javascript:void(0)">A</a></li>
  <li><a href="javascript:void(0)">B</a></li>
  <li><a href="javascript:void(0)">C</a></li>
<ul>
$(".js_switch_tab a").click(function(){
});

タブ切り替えのロジックなどで使う「._is_current」のようなクラス名は「.js_is_current」とする必要はありません。

.ga_xxxxx

.ga_global_nav__top{}
.ga_global_nav__news{}

Google Analyticsのクリックカウント用のクラス名です。

.ga_[URL]__[任意の名前]

が良いかと思います。

<a href="#" class="ga_news_detail__more_btn">もっと読む</a>

といった具合です。
ものすごく冗長に…。

HTML/CSS記述の原則

  • idはCSSのセレクタとしては使わない。使うのは<input id="a"><label for="a">くらいでしょう。
  • 画像のパスは絶対パス
<img src="/img/pc/logo.png" alt="">
.lo_stage{
    background-image: url("/img/pc/bg_1.png");
}

CSSの記述ルール

.cn_news_list{}
.cn_news_list .p_news_list{}
.cn_news_list .p_news_list_item{}
.cn_news_list .p_news_list_item__img{}
.cn_news_list .p_news_list_item__txt{}

.cn_news_ranking{}
.cn_news_ranking .p_ranking{}
.cn_news_ranking .p_ranking_item__img{}
.cn_news_ranking .p_ranking_item__txt{}

CSSは、原則コンテントレベルで定義します。
これを徹底することで、意図しない継承が起きなくなります。

.pn_news_top .cn_news_list{}
.pn_news_top .cn_news_list .p_news_list{}
.pn_news_top .cn_news_list .p_news_list_item{}
.pn_news_top .cn_news_list .p_news_list_item__img{}
.pn_news_top .cn_news_list .p_news_list_item__txt{}
.pn_news_top .cn_news_archive .p_news_archive_list{}
.pn_news_top .cn_news_archive .p_news_archive_list_item{}

特定のページだけに適用させたいCSSがある場合は
「.pn_xxxxx」と「.cn_xxxxx」を組み合わせて使います。

.lo_content .p_header

のように「.lo_xxxxx」起点で定義をしてはいけません。

.cn_article.lo_content
.cn_article > .lo_content__header
.cn_article .p_header

のように、必ず「.cn_xxx」を起点とします。

オーバーライド

「.cp_xxxxx」「.cu_xxxxx」は共通パーツ、共通ユニットなので

.cp_pager{}

のように定義します。

 .cn_xxxxx .cp_pager{}

上記のように定義すると、共通パーツのオーバーライドになります。
パーツの内容自体は原則変えませんが、周りの余白などはこの形で調整します。

※そもそも「.cp_xxxxx」を作らず、Sassのミックスインで定義、必要な「.cn_xxxxx」内だけで呼び出すという手もあります。が、それをすると、デブツールで「ちょっとこのパーツ当ててみよう」とかができなくなります。

親子関係の定義

<div class="lo_stage">
    <div class="lo_stage__header">
        <div class="lo_stage__header_inner">
        </div>
   </div>
   <div class="lo_stage__body">
        <div class="lo_stage__body_inner">
            <div class="lo_stage__body_main"></div>
            <div class="lo_stage__body_sub"></div>
                </div>
   </div>
   <div class="lo_stage__footer">
        <div class="lo_stage__footer_inner">
                </div>
    </div>
</div>

親子要素であることを明示するために親要素と子要素を「__」で連結します。
上記は.lo_stageです。

.lo_stage{}
.lo_stage__header{}
.lo_stage__header_inner{}
.lo_stage__body{}
.lo_stage__body_inner{}
.lo_stage__body_main{}
.lo_stage__body_sub{}
.lo_stage__footer{}
.lo_stage__footer_inner{}

CSSを書くとしたら上記のようになります。
「.lo_stage」 + 「__」 + 「子要素」の形です。

この時「.lo_stage__footer_inner」のように子要素と孫要素などは「__(アンスコ2つ)」ではなく「_(アンスコ1つ)」で連結します。
個人的に、その方が見やすいと感じたためです。

親子関係を省略して記述

<div class="lo_stage">
    <div class="__header">
        <div class="__inner">
        </div>
   </div>
   <div class="__body">
        <div class="__inner">
            <div class="__main"></div>
            <div class="__sub"></div>
                </div>
   </div>
   <div class="__footer">
        <div class="__inner">
                </div>
    </div>
</div>

「.lo_xxxx」など共通部分を何度も書くのが面倒だと思うかもしれません。
DOM構造上、直接の子要素に対しては省略をしても良いと思います。

.lo_stage{}
.lo_stage > .__header{}
.lo_stage > .__body{}
.lo_stage > .__footer{}

ただし省略形を使う場合、CSSは必ず「>」で適用範囲を限定します。

.lo_stage > .__header > .__inner > .___main{}

こういう定義も可能です。
でも美しくないです。

状態を表すクラス名

「選択された状態」など状態の変化を表したい時があります。

._has_no_result
._is_first
._is_last
._is_current
._is_disabled

その場合、クラス名は上記のように「_」から始まるクラス名を併記します。

.p_switch_item._is_current{}

使うときはのように、クラス名併記の形を取ります。
パフォーマンスが悪い記述と言われていますが

<li class="p_switch_item p_switch_item__is_current">
    <a href="#">A</a>
</li>

のようにクラス名を2つ定義するのは冗長過ぎます。

._current

ちなみに、ただ「._current」などとするのは止めたほうが良いかと。

要素型セレクタは原則使わない

.cn_news h1{}
.cn_news p{}

のように要素型セレクタを使った定義は原則禁止です。

ul{}
ul > li{}
ul > li > a,
ul > li > span{}
dl{}
dl > dt{}
dl > dd{}

ただし、上記のように子要素が限られている場合、
クラス名を付けたほうが上長になる場合は「>」を使って限定することを条件に定義可能。

<div class="cn_list">
    <ul class="p_list">
        <li><a href="#" class="p_list_item"></a></li>
        <li><a href="#" class="p_list_item"></a></li>
    </ul>
</div>
.cn_list .p_list{}
.cn_list .p_list > li{}
.cn_list .p_list_item{}

でも

<div class="cn_list">
    <ul class="p_list">
        <li><a href="#"></a></li>
        <li><a href="#"></a></li>
    </ul>
</div>
.cn_list .p_list{}
.cn_list .p_list > li{}
.cn_list .p_list > li > a{}

でもよしとする。

コーディング時の心がけ

バリデータを通す

納品物はバリデータをかけてエラーをなくしましょう。

PC版のは:hoverとかある

デザインに無かったら戻せばよい話。

画像を圧縮する

tinypngなどを使って画像サイズを小さくするとユーザーに優しいです。

リストページはN件時と0件時がある

検索結果など、結果をリストで表示するページでありがちなのが「0件時の表示」の存在です。

まず起こり得ない文字長のパターンで作る

デザイナーから納品されたデザインは「良い感じ」に収まっているものが少なくありません。
でも実際はそんなきれいに収まらないことが多く、その場合でも崩れないで表示できるHTML&CSSを作る必要があります。

英文対応

だいたいword-break: break-allで解消します。

レギュレーションを設定する

文字サイズ、文字色、罫線の色、余白など、サイト内で共通のルールを設定しておこう。

GA用のクラス名を付ける

GAクリックカウント用のクラス名を付ける癖をつけておくと幸せです。

画像

ディレクトリ

/img/
/img/common/
/img/pc/
/img/pc/news/
/img/sd/
/img/sd/news/

画像は「pc」「sd(smart device)」に分け、それ以下の構造はURLに準ずる。

ファイル名

  • ファイル、ディレクトリ名に利用できるのは半角英数字と「_」のみ
  • 半角英字は小文字のみ。単語と単語の区切りは「_」でどうぞ。
logo_01.png
icon_home_01.png
icon_back_01.png

とか接頭辞のように「.icon_」とか付けるのは…どうなんだろうか。要検討。現状していない。

JS

Pug

//- var root = "/"
- var root = "/test/"

a(href=root+”/”)

のように記述しておくと、環境が変わっても対応し易い。