セマンティック HTML学習の旅　〜初心者がBEMを書けるようになるまで〜

## 初めに
この記事は「[セゾン情報システムズ Advent Calendar 2022](https://qiita.com/advent-calendar/2022/sisco)」22日目の記事です。
完全にIT初心者のため、シニアのフロントエンドエンジニアにセマンティックHTMLとCSS3の基礎的な書き方のレビューを受けましたので共有させていただきます。

初心者がどういう間違いを最初にするか、どういう風にレビュー後に改善していくか、BEMが書けるようになるまでの成長記録です。初心者がどこが分からないのかを理解するための参考にして頂ければと思います。

## レビュー前とレビュー後のソースコード比較
この検索エリアの画面のソースコードを直していく過程を記録します。レビュー前とレビュー後のやり方を比較して記載していきます。
![Screenshot 2022-11-21 at 17.38.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958235/bdbe49bb-6f7c-dcba-2502-87ad8bd80759.png)
## 外枠の構造
本、雑誌、新聞などには適したレイアウトがあります。ウェブページも利用者がわかりやすく、視覚的に魅力的で良いデザインを考えることが大切ですが、さらに重要なのは、他のデベロッパーがソースコードを見た時にもわかりやすく書かれていることです。可読性が高くないとメンテナンスが難しくなるからです。
HTMLには様々な書き方があって初心者としては迷ってしまいます。ブラウザで表示された見た目は同じかもしれませんが、保守性とパフォーマンスの観点から見ると、あまり良くない書き方があります。
以下の画像をご覧ください。左がレビュー前、右がレビュー後のソースコードです。詳細な違いは画像の下の『Table 1』に書いてありますのでご参照ください。
![Screenshot 2022-12-21 at 15.35.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958235/4cd6a163-9576-a8b0-4ff1-67d164210862.png)
![Screenshot 2022-12-21 at 15.37.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958235/08ba5b19-5348-7c5c-4a87-707fa78cd382.png)
<em> Table 1 </em>
| レビュー前(画像左)| レビュー後(画像右) |
| --- | --- |
| 1. 赤枠の箇所について<br>div class=”container”の中をdivとformの２つのブロックに分けていました。検索条件エリアのdiv class=”title"と、formタグの２つです。 | 1. 赤枠の箇所について<br>こちらもdiv class=”grid-container”の中を２つのブロックに分けました。検索条件エリアのdiv　class=”grid”とformタグ、buttonタグが入っているdiv class=”container“です。|
| 2. div class='button"にCSSをかけて、その中にbuttonタグを入れていた。<br>不要なdivでbuttonタグをwrapしていた。 | 2. div class='button"にかけていたCSSを、buttonタグにかけるように修正した |
|3. グリッドでコントロールしていなかったため、div class=”container” に display が設定されていませんでした。|3. formのグリッドをコントロールするために、外側をdivでwrapして、div class=”container”としました。div class=”container” にdisplay:grid を設定したので、row-gapの設定もできました。|

Table 1 の修正点を見て分かる事は、ウェブページを書く前にどのような仕組みでどうやってCSSプロパティを書くか、layout の構造を設計し、計画するべきだという事です。
## 検索条件
内側の検索条件の書き方を見ていきます。レビュー前とレビュー後のソースコードを上下に並べましたので、詳細な違いを『Table 2』でご確認ください。


<ins> レビュー前 </ins>
![Screenshot 2022-12-21 at 15.46.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958235/94f5f843-25e2-bd7b-541f-6c6bbeb2a076.png)
<ins> レビュー後 </ins>
![Screenshot 2022-12-21 at 15.46.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958235/fc5910d1-a04e-d78a-573f-a19b42a138b6.png)
HTMLに対応するCSSの指定を、同じ枠の色で囲んでいます。

<em> Table 2 </em>
| レビュー前(画像上)| レビュー後(画像下) |
| --- | --- |
|1. CSS が多く、必要ではないものがある。|1. 必要なCSSだけに絞っている。|
|2. グリッド化していない状態のため、３つのcolumn に幅を指定せざるを得ず、真ん中の column も空になっている。|2. display:grid にしてグリッド化したので、 justify-content を指定するだけでlayout が出来る。|
|3. div class=”row title “の padding-bottom も設定する必要がある。（layout を親要素に設定していないため）|3. 親要素にrow-gap を設定しているので padding-bottom が要らなくなる。|
|4. 検索条件の隣の icon と右側の filter icon に image タグ を使っているため、サイズや色が固定されて変更で出来ない。|4. 検索条件の隣の icon と右側の filter icon に svgタグ を使用したため、色もサイズも変更出来る。|

Table 2の修正点を見て分かるのは、
１）CSSは必要なもののみ設定する、
２）親要素で layout を決める、
３）デザインファイルからexportして利用するiconやlogoなどはimageタグではなく、svgタグを使うことです。

<ins> FormとButton </ins>

次にform と button の構造について比較します。例) レビュー前とレビュー後の画像と、アニメーションGIFをご覧ください。レビュー前の状態はcolumnを一つづつ分けたのでバラバラな形で分かりにくいかと思います。詳細な比較は『Table 3』に書いてありますのでご確認ください。

<ins> レビュー前 </ins>
![Screenshot 2022-12-21 at 15.50.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958235/827d818c-9350-d63f-9387-0b829607525c.png)
<ins> 全てのdiv </ins>
![search form 1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958235/51d44c5b-32d2-d584-45e3-a00c3f3686b0.gif)
<ins> レビュー後 </ins>
![Screenshot 2022-12-21 at 15.56.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958235/8e15d2d8-4d66-da1c-31b3-09452a69e25f.png)
<ins> 全てのdiv </ins>
![search form 2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958235/f9bd53b4-8e36-20a4-4b81-7739d38d3f52.gif)
<em> Table 3 </em>
| レビュー前(画像上)| レビュー後(画像下) |
| --- | --- |
|1. グリッドを使っていなかったので、すべての div に class=column を指定しており、column の幅、padding、float:left をすべてにかけていた。|1. グリッドを利用するためにform に class をかけて display:grid と grid-template-column を設定するだけで layout が出来た。|
|2. buttonタグをdivでwrapしていた点が、論理構造的に問題が有った。|2. セマンティック的に buttonタグ を使っているので正しい構造になった。|
|3. columnの間の padding のサイズを固定値で記載しており、ハードコーディングになってしまっていたので、 汎用性がなった。|3. grid でレイアウトを決めているため、 自動的に gap が取られている。|
|4. Layoutは親要素で決めるべきだが、buttonタグ のほうにmargin をかけていたため、構造的にあまり良くなかった。|4. div class=”container” の中に formタグ と buttonタグ を入れて display:grid と row-gap で layout を決めているため、marginを指定する必要がない。|
|5. buttonタグにclassをかけずに直接cssをかけていた。複雑なウェブページになると、どこで指定されているのかの可読性が落ちるため、問題が発生しやすくなります。|5. button に CSS class を付けて selector として使ったため、他のデベロッパーが見ても理解しやすくなった。|

Table 3 の修正点を見て分かるのは、
１）セマンティックなHTML タグをなるべく使う、
２）marginとpaddingは子要素に使わないで親要素でlayoutを決める、
３）HTMLタグ自体に直接cssをかけるのではなく、必ずclass名を付けてCSSプロパティを指定することとなります。
## BEM (Blocks, Elements, Modifiers)

ここまでのCSSの書き方を見るとclassの命名規則がなかったため、BEMの学習を始めました。
BEMは名前の通り、blocks, elements, modifiers で論理構造を作る手法です。このBEM の手法により、CSS コードはシンプルで理解しやすい強固な構造になります。ブロック スタイルはページ上の他の要素に依存しないため、カスケードによる問題が発生することはありません。
さらに、完成したプロジェクトから新しいプロジェクトにブロックを流用することもできます。独立したブロックをさまざまな方法で構成し、それらを賢く再利用することで、維持する必要のある CSS コードの量を減らすことができます。スタイル ガイドラインのセットがあれば、ブロックのライブラリを構築して、CSS を効率的に運用することができます。詳細は下の画像をご覧ください。

<ins> CSSの命名 </ins>
![Screenshot 2022-12-21 at 17.39.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958235/08a069b7-3423-a8bd-c338-880e73e0f28f.png)
<em> Table 4 </em>
| BEM前(画像左)| BEM後(画像右) |
| --- | --- |
|classの命名を見るとどれが何を指定されているのかは見るだけで理解できなかった。|classの命名を見るとsearchのblockの中にelementsとしてheader, title, editなどがあり、構造が見るだけで分かりやすくなっています。search__select-wrapにはmodifierとしてhalf-sizeがありますのでsearch__select-wrapをbaseにしてmodifyしたことが理解出来る。|

## CSSのまとめ（SASS-Syntactically Awesome Stylesheetの学習）
BEMで書いたCSSプロパティは重複しているpropertiesもあるので、これらを一ヶ所で管理するためにSASSの書き方を学ぶ必要があります。SASSには１つのファイルで書くのではなく、＠use、@importなどのルールを使って分割することが出来ます。 このルールは、別の SASS ファイルをモジュールとしてロードします。つまり、ファイル名に基づく名前空間を使用して、SASS ファイル内のその変数、ミックスイン、および関数を参照できます。 SASSファイルを使用して自動でCSSをコンパイルすることが出来ます。

例として下のiconのCSSについて見て見ましょう。（『Table ５』 参照）
![Screenshot 2022-12-21 at 13.40.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958235/09fce4ce-1486-35f6-e9b0-22aa7e9b76e6.png)
<em> Table 5 </em>
| BEM前(画像左)| BEM後(画像右) |
| --- | --- |
|1. CSSにwidthとheightが重複していた。|2. 重複しているCSSプロパティを一回だけ書いて、変わるものがfillとpaddingなので@mixinにparameterを指定してSASSのファイルで共有できるようになった。(再利用生が高くなりました)|
|2. 色が16 進数コードになって散らばっているとファインダビリティが悪くなる。|2. 色が一ヶ所で指定されているので何の色か調べたい時、別ファイルで簡単に探せるようになった。|

Table ５ の修正点を見て分かるのは、BEMやSASSでCSSを書くと可読性、再利用生が高くなり、別ファイルでも分けられるためコードが綺麗になります。また、@mixin、@functionも使えるのでループしてCSSを書くことが出来てコードを短く書けます。
## SASS Document 書き方の学習

最後に、SASSでCSSを書く時＠mixin、＠functionなどが多くなると他のデベロッパーが見た時どのパラメーターを設定しているか分からなくなるため、SASSのDocとしてオンライン ドキュメントの書き方を学習しました。下の画像をご覧いただくと左側がSASSファイルの方に書いていたものになっており、右側はブラウザで確認できるSASSの ドキュメントとなります。
![Screenshot 2022-12-21 at 17.42.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958235/95ae7780-141e-a118-64f0-fcd101da86e2.png)
左の画像のように＠mixinごとに書くとSASS Docに纏めて見ることが出来るので非常に理解しやすいドキュメントが出来ます。下の画像をご覧ください。
![Screenshot 2022-12-21 at 16.27.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958235/3c78404a-957a-79b0-0fcc-c63bd6be6513.png)
## まとめ

ここまでお読みいただきありがとうございました。

レビューを受けた後はHTMLとCSSについての知識が前より深くなり大変勉強になりました。

今回学んだことをまとめると以下になります。
・コーディング前には仕組みをちゃんと考えてから始めるのがベストだと理解した
・体系的なCSSの書き方「BEM」や SASSの書き方まで学んだことで、以前より可読性、保守性、再利用生が高いソースコードを書けるようになった
・HTML、CSSでやった方が良いこと、しない方が良いことを理解できた

今後も、他の開発者の方が見てすぐに理解できるような書き方を心がけていきたいと思います。

初心者の方を教えている方や、HTMLとCSSを今から学習しようと考えていらっしゃる方など、多くの方にご参考になれば幸いです。