小〜中規模サイトのフロントエンド・コーディング規約　HTML編

2021/03/15
初めて記事を書いてから３年以上経過してしまったので、
内容を見直ししました。

---

関係者が10名以下の小〜中規模案件の開発・保守が多い弊社のHTMLコーディング規約です。
とても長いのですが、ここでは開発時に知っておいて欲しいことの概要を書きました。

前提知識としてちゃんと理解し、案件仕様にあわせて対応してもらえれば幸いです。
オライリー本はほんと勉強になるので、ぜひ読みましょう…！

関連ページです↓
[環境構築編](http://qiita.com/d2cs-kimura/items/8b8a5f60556580bc4934)
[CSS・JavaScript編](http://qiita.com/d2cs-kimura/items/1ed0e93f3eea26080cf4)

---
# 小〜中規模サイトのフロントエンド・コーディング規約　HTML編

## マークアップ言語仕様

| 項目 | 定義内容 |
|:----|:----|
| HTML規格 | HTML5 |
| DOCTYPE宣言 | <!DOCTYPE html> |
| 文字コード | UTF-8 |
| 改行コード | LF |
| 静的ページ 拡張子 | .html(.htmなどは使わない) |
| viewport(width) | width=device-width,initial-scale=1 |
| lang | ja |
| 正規化 | canonicalタグで絶対パスを記述してください |

## 動作保証対象OS・ブラウザ

基本的には、**公式サポート有効内のOS・ブラウザ**をのみ対象にします。
サポート対象外のOS・ブラウザを使うことは

- セキュリティパッチの無償提供が停止
- 以後に発覚した脆弱性は修正されず、セキュリティ面でひどく脆くなってしまう
- 攻撃を受けた際、その責任はブラウザ提供側でなくwebサービス提供側になる恐れがある
- 古い環境ではできることが限られるため、開発＆保守の難易度が上がる

上記のリスクを含むことを確認してください。

現時点でのサポート対象は
[各OSのリリース日とサポート終了日を表にまとめてみた](https://qiita.com/yunano/items/4757f86f9e92bb4f503f) で確認できます。

IE11 は windows 10 のサポート終了が2029年のため、
まだしばらくセキュリティアップデートが続くと思われますが
Microsoft のアプリケーションや YouTube、Twitter などでサポートが
終了しているので、特別な理由がない限り対象外にしてください。


## アクセシビリティ

最低限として、下記に配慮してください。

- コンテンツに見合った自然なコーディング<br>（厳格でない程度のセマンティックさを意識する）
- 見出しの構造化
- ユーザが操作できる要素は、フォーム要素以外では ```<a>``` もしくは ```<button>``` でマークアップする
- 装飾以外の ```<img>``` には alt を設定する（alt 属性の省略は行わない）
- フォームの要素がどんな役割をもつか明示するために、<br>要素ごとに ```<label>``` で関連づける
- 実装後に明らかに使いづらい機能は、代替の方法を模索する

公的機関はもちろんですが、特に公共性が高い案件は下記も顧慮します。

- 2016年4月に施行された「障害者差別解消法」によって、国の行政機関・地方公共団体などのwebサイト新規制作はJIS X 8341-3の適合レベルAAに準拠することが求められる（[みんなの公共サイト運用ガイドライン（2016年版）](http://www.soumu.go.jp/main_sosiki/joho_tsusin/b_free/guideline.html)）ことを理解し、適切なコーディングを行う
- WAI-ARIA をつかった情報補足を行う
- VoiceOver（Mac、safari）などによる挙動確認をする 

WAI-ARIA の実装は [bootstrap の components](http://getbootstrap.com/components/) が参考になります。

### 集客や周辺コンテンツへの誘導に効果的な施策
こちらは案件内容によって適宜対応してください。

- SNS へシェアさせる（meta ogp も設定）
- AMP 対応を行う
- JSON-LD を用いたページデータ構造化を行う
- ディープリンクの設置


## ページパフォーマンス最適化

ユーザの使い勝手向上やページのCVRアップにもつながるので、
パフォーマンス最適化は必ず行うようにします。

### O'ReillyハイパフォーマンスWebサイトで挙げている14のルール
1. HTTPリクエストを減らす
2. CDNを使う
3. Expiresヘッダを設定する
4. コンポーネントをgzipする
5. スタイルシートは先頭に置く
6. スクリプトは最後に置く
7. CSS expressionの使用を控える
8. JavaScriptとCSSは外部ファイル化する
9. DNSルックアップを減らす
10. JavaScriptを縮小化する
11. リダイレクトを避ける
12. スクリプトを重複させない
13. ETagの設定を変更する
14. Ajaxをキャッシュ可能にする

> - [O'Reilly ハイパフォーマンスWebサイト](https://www.oreilly.co.jp/books/9784873113616/)
> - [O'Reilly 続・ハイパフォーマンスWebサイト](https://www.oreilly.co.jp/books/9784873114460/)

**この14のルールは現在では古く、使われていないもの・効果が薄いものもあります。**
ですが、「何を目的にして項目化されたのか」を理解することはとっても大切です。

上記の中でも効果が高い施策は、
**HTTPリクエストを減らす** ことと
**レンダリングブロックを最小限に抑える** ことです。


### HTTPリクエストを減らす

- Expireヘッダの設定（リソースのブラウザキャッシュ設定）
- Service Worker のキャッシュを行う
- DNSルックアップを減らす(プリフェッチはHTTP1.xでは有効)
- 画像のCSSスプライト作成

CSS や JavaScript の結合は有効ですが、
やりすぎるとリソース自体が肥大し、古いブラウザなどで描画が遅くなる場合があります。

### レンダリングブロックを最小限に抑える

- SNSプラグインなど初期表示に関わらないリソースの読み込みを非同期にする
- 正しいHTMLマークアップを行う
- CSS のパースはページロードを止めてしまうので、\<HEAD> 内で JavaScript の読み込みより前に行う


> - [知っておきたいブラウザについての基礎入門](https://speakerdeck.com/pastak/zhi-tuteokitaiburauzanituitefalseji-chu-ru-men)
> - [サイトのパフォーマンス改善で重要なクリティカル レンダリング パスについて](http://coliss.com/articles/build-websites/operation/work/about-the-critical-rendering-path.html)
> - [ブラウザってどうやって動いてるの？（モダンWEBブラウザシーンの裏側）](http://shanon-tech.blogspot.jp/2011/09/web.html)

### 画像最適化

web ページの転送データの半分以上を、画像が占めることが多々あります。
必ず画像は適切な形式を選んで、圧縮するようにしてください。

#### 画像形式の選び方
- アニメーション ... gif
- 色数の多い画像 ... jpg
- 色数が少なく、形状が単純なもの ... svg
- それ以外、透過データがあるもの ... png
- jpg, png-24 で大きな画像 ... WebP

WebP は safari で現状未対応のため、フォールバックを用意してください。
CSS スプライトや、base64 は HTTP リクエストを減らします。
工数の複雑化や記述量が増えることもありますが、通信を抑えるのは有効な時があります。

また、古いブラウザでCSSの描画コストが高くなる、
「border-radiusとbox-shadowの組み合わせ」を画像に代替すると
結果的に描画が早く終わることがあります。

複数サイズや WebP が用意できる運用だったら srcset 属性でマークアップします。

```html
<picture>
  <source type="image/webp" media="(max-width: 600px)"
          srcset="./img/kv_sp.webp">
  <source media="(max-width: 600px)"
          srcset="./img/kv_sp.jpg">
  <source type="image/webp" media="(min-width: 601px)"
          srcset="./img/kv.webp">
  <img src="./img/kv.jpg"
       alt="キービジュアル" width="1500" height="900">
</picture>
```

#### 画像圧縮
タスクランナーで画像圧縮するのが漏れがなく確実ですが、
下記の場合は手動で圧縮したほうが調整が効き、よかったです。

- モバイル用の画像が1ファイルで100k を越えたら、少しでもサイズを減らせないか工夫する
- PNG24形式の画像は減色ツールで劣化を確認しながら減色する

### コードの圧縮

リリース版では JavaScript, CSS を圧縮してください。
HTML は案件仕様にあわせて判断してください。

gzip が有効なサーバ環境だったら、ソースコード圧縮のついでに gzip を生成するようにすると良いです。 webpack では、[compression-webpack-plugin](https://github.com/webpack-contrib/compression-webpack-plugin) があります。
zopfli や Brotli はまだ試したことがないので圧縮・解答のコストがどれくらいあるのか未知数です。。


### パフォーマンス最適化にあたっての注意点

- ページ表示速度改善と運用コストはトレードオフの関係にあるので、できる範囲で行う（努力はもちろんする）
- じっくり本格的に最適化を行うなら、まずは**一定期間で計測を行い、ボトルネックの発見**から始める

chrome の開発者ツールの Lighthouse は手頃な計測ツールとして有効です。
参考：[Lighthouseの計測結果を見ていく](https://qiita.com/nightyknite/items/22d9f818dbab9bf171a3)

他にも最適化に関する実装方法
■ [最近の Web パフォーマンス改善について知っておきたいコト](https://speakerdeck.com/ahomu/zui-jin-false-web-pahuomansugai-shan-nituitezhi-tuteokitaikoto)
■ [Web Speed Hackathon Online 出題のねらいと解説](https://github.com/CyberAgentHack/web-speed-hackathon-online/wiki/Web-Speed-Hackathon-Online-%E5%87%BA%E9%A1%8C%E3%81%AE%E3%81%AD%E3%82%89%E3%81%84%E3%81%A8%E8%A7%A3%E8%AA%AC)

### Core Web Vitals

google が提唱した、ユーザーエクスペリメンスを図る指標です。
モバイル検索の順位を決める要素の一つとして使うとアナウンスされています。
[Web Vitals の概要: サイトの健全性を示す重要指標 _ Google Developers](https://developers-jp.googleblog.com/2020/05/web-vitals.html)

・ページ読み込み時間
・ページが表示されてから入力可能になるまでの待機時間
・操作の邪魔にならない視覚の安定性
の３項目からなり、それぞれ web 全体の 70% 以下のスコアなら Good とされます。

前述の Lighthouse や 
[PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights/) 、[WebPagetest](https://www.webpagetest.org) のサービスから確認することができます。



## コーディングルール

| 項目 | 定義内容 |
|:----|:----|
| インデント | 半角スペース2つ |
| 要素、属性 | 小文字で記述<br>（非推奨：```<A HREF="">```　推奨：```<a href="">```） |
| id 名 | キャメルケース |
| css 名 | キャメルケース、-（ハイフン）_（アンダーバー）使用可能 |
| コメント | おおまかな機能ごとにコメントで区切る |
| 画像 | 基本的に、差し替えの多いキービジュアルやシステムで動的に出力される画像のみ HTML 内に記述する |
| リソースのプロトコル | 省略する |


```HTML
<!-- 非推奨 -->
<SECTION id="profile-section" class="profile">
  <H1>プロフィール</H1>
  <img src="https://dummy.site/profile.jpg" alt="著者近影">
  <p class="profile_name">作者 太郎</p>
</SECTION>
```

```HTML
<!-- 推奨 -->

<!-- 著者プロフィール -->
<section id="profileSection" class="profile">
  <h1>プロフィール</h1>
  <img src="://dummy.site/profile.jpg" alt="著者近影">
  <p class="profile_name">作者 太郎</p>
</section>
<!-- // 著者プロフィール -->
```


:sunny::sunny::sunny:

画像についての補足：

```HTML
<!-- 非推奨 -->
<h1><img src="./img/logo.png" alt="サービスロゴ"></h1>
<button>
  <img src="./img/button.png" alt="ボタン">
</button>
```

↑でももちろん問題ないのですが、
仕様が激しく変わる案件や長期保守を行う場合は
システムから出力される画像以外は CSS で管理したほうが都合良い場合が多かったです。

```HTML
<!-- 推奨 -->
<h1 class="service_logo">サービスロゴ</h1>
<button class="button__primary">ボタン</button>
```

後でプログラムを組み込む場合なども、見通しが良く作業負担が減ります。


## ツール

### 静的ページ

共通項目の多いサイトなら、eleventy、pug、EJS、または Nunjucks を推奨します。
eleventy は pug や EJS に対応した HTML の生成に特化した静的サイトジェネレータです。
コンテンツになるデータの扱い方が柔軟なので eleventy を使って
得意のテンプレート形式を使う方法がやりやすいと感じています。

アプリケーションの性質が強ければ、JavaScriptフレームワーク（vue.js）の利用を推奨します。

「コーディングミスを減らし、管理が楽にする」「技術要求に応える」という目的から外れていなければ、ツールにこだわりはありません。


### jamstack

ページ数や更新頻度の少ないサイトでは jamstack を採用することがあるかもしれないです。
コンテンツ管理をどうするか、長くなりがちなビルド時間を減らすにはどうしたらいいか
など悩ましいポイントも多いですが、
ページ表示最適化やセキュリティで恩恵が大きい制作方法です。

フロントエンドで使う Next.js や Gatsby、Next.js は開発がどんどん進んでいて、
それに応じて対応できる案件の幅が変わってきそうです。
（2021/3/9 に Gatsby がローカルの increment build に対応しました）

現時点では WordPress と同じことをやろうとすると、
WordPress でやったほうがいいです。

静的サイトを構築する時の手法の一つとして jamstack を捉えていると
フレームワークの使い勝手と制作コストの差が少ないと思います。