フロントエンド設計・CSS命名規則の簡単なご紹介/使用する意味について
今回はフロントエンド設計・CSS命名規則についてお話したいと思います。
中規模〜大規模開発は度重なる修正指示がつきものですよね。
そして案件が終盤に近づくほど、
「ああ…どんどん修正が打ち消し合ってゴチャゴチャしていく…
でももうその修正と検証に工数かけられないしリスキーでできない…」
という経験をしたことはありませんでしょうか?
「破綻しないCSS設計」
多少面倒な手間があろうとこれがいかに大事か、フロントエンドエンジニアをしていると膨らむ工数と面倒臭さを回避するためには勉強せざるを得なくなりました。
基本的な考え方の参考になったこちらの記事もぜひ一読してみてください。
参考:https://murashun.jp/article/programming/css/css-design.html
今回の記事では、弊社で使用しているCSS設計について簡単に説明いたします。
ぜひどなたかの参考になればと思いながらつらつらと書いていきます✍️
【全体の設計】
まず、全体的なCSS設計です。
ファイルの構造としては、FLOCSSという命名規則を用いています。
参考:https://qiita.com/super-mana-chan/items/644c6827be954c8db2c0
参考記事より引用した構造が以下になります。
Foundation サイト全体のデフォルトスタイルを管理。
├ reset.scss
├ base.scss
├ variable.scss サイト全体で使える変数
├ mixin サイト全体で使えるmixnを管理
Layout 各ページを構成するサイト全体で共通したエリアを管理。
├ l-header.scss
├ l-main.scss
├ l-footer.scss
Object サイト全体で再利用できるパターンを持つモジュールを管理
├ Component 小さな単位のモジュールを管理(ボタンなど)
├ c-button.scss
├ c-grid.scss
├ …
├ Project いくつかの↑Componentと、他の要素によって構成される大きな単位のモジュールを管理
├ p-card.scss
├ p-profile.scss
├ ...
├ Utility ComponentとProjectのモディファイア(パターン)で解決することができないスタイル、また、調整のための便利クラスなどを管理。
├ u-utility.scss
├ u-color.scss
├ u-margin.scss
├ u-padding.scss
このように全体設計をルールづけることで、複数人での開発時に
どこにファイルが置いてあるか?が迷うことなく探せることが利点になります。
大体の案件は上記の設計とすれば困ることはありませんが、
特筆してお伝えしたいファイル内のルールについて記述します。
1. foundation > var.scss の定義
基本的に変数は本ファイルに定義しています。
変数の種類は以下の用途で用意する案件が多いです。
・breakpoint
・font-weight
・line-height
・letter-spacing
・color
変数として用意するべき一番の理由は、
「一元管理ができ、変数を指定した箇所を確実に一括置換が可能になるから」です。
実装後に値を調整したいって場合に検証も軽くなり、とても便利です。
2. foundation > mixin.scss で有用なもの
scssの機能で「mixin」というものがあります。
機能についてご存知でない方は以下記事などがわかりやすいです。
参考:https://qiita.com/one-a/items/2758511326c09200fded#mixin
どんな案件でも大抵使える!というものについて、
実際に使用するときの
①@mixin文 ②@include文 ③出力結果
の形式でご紹介します。
▼メディアクエリを使用したレスポンシブ対応の記法
■@mixin文
@mixin pc() {
@media screen and (min-width: 768px) {
@content;
}
}
■@include文
@include pc {
width: 700px;
}
■出力結果
@media screen and (min-width: 768px) {
width: 700px;
}
▼aタグではない要素へのhoverアニメーションの付与
■@mixin文
@mixin hover_btn($opacity: 0.6, $transition_sec: 0.3s) {
cursor: pointer;
transition: opacity $transition_sec;
&:hover:not(:disabled) {
opacity: $opacity;
}
}
■@include文
// HTML
<div class="notBtn">ボタンじゃないよ</div>
// include文
.notBtn {
@include hover_btn(0);
}
■出力結果
.notBtn {
cursor: pointer;
transition: opacity 0.3s;
&:hover:not(:disabled) {
opacity: 0;
}
}
3. object > project の扱い
主に「ページ単位」での区切りとして用いています。
大体のサイトを、
<header>
<main> .... </main>
<footer>
という流れで構成していますが、
<header>
<main class="p-top"> .... </main>
<footer>
このように、<main>タグに「class="p-top"」と記述することで
このページのユニークCSSは「class="p-top...hogehuga"」と定義するんだよ〜という意図になります。
4. object > utilityの中身
■どのような案件でもたいてい含めているもの
・clearfix.scss
・device.scss
・clearfix.scss
floatを使用した時などに、要素の高さを取れなくなり要素が重なってしまう場合に有効なものです。(最近じゃあまりfloatの出番はありませんが、出てきたときに便利)
clearfixの参考:https://qiita.com/mariofujisaki/items/2ad1de8432d7249afadc
ファイルの中身はこちら。
.u-clearfix {
&::after {
content: "";
display: block;
clear: both;
}
}
「.u-clearfix」と親要素につけるとfloatしても高さを取得できるようになります。
・device.scss
デバイス(ウインドウ幅)ごとに見せる要素/見せない要素をクラスで定義しています。
中身をお見せした方が話が早そうなのでこちら。
.u-sp {
@include pc {
display: none !important;
}
}
.u-pc {
@include sp {
display: none !important;
}
}
端的にお話ししますと
例えばレスポンシブデザインのブレイクポイントが768pxの場合、
■HTML
<div class="u-pc">要素</div>
こちらのようにクラスを付与すると、
768px未満のデバイスでは非表示になる
(display: none !important;が適用される)といった仕組みです。
「class="u-sp"」が付与された時は上記とは逆になり、
768px以上のデバイスでは非表示になります。
次に、ファイル内での命名規則についてです。
【ファイル内の設計】
全体ルールとは別に、BEMという命名規則を使用しています。
参考記事:https://qiita.com/Takuan_Oishii/items/0f0d2c5dc33a9b2d9cb1
端的に言いますと、例えば
object > project > top.scss のファイル内での記述は
「.p-top__ hogehoge」とするというルールです。
これを外れて名付けることは原則禁止としています。
実際のコーディングは以下のようになっています。
.p-top {
&__kv {
width: 100%;
}
&__about {
display: flex;
justify-content: center;
}
// アンスコは1度のみ使用で、それ以降はキャメルケースの命名
&__aboutHeading {
color: #fff;
font-size: 24px;
}
&__aboutHeadingBig {
font-size: 30px;
}
.
.
.
ファイル内で共通した命名規則を使う理由は、
誰が作成したページでも統一されたルールになっていることに意義があります。
使う命名規則は何でもいいのですが、
複数人開発で命名をばらけさせないということが重要なのです。
これ以降はBEMの命名規則の記事を理解していただいた方向けの補足説明になります。
「__hogehoge」の部分は、BEMのルールで「Element」と呼ばれる部分でして、
「--hugahuga」というBEMのルールで「modifier」をつける時はどんな時かと言いますと、コンポーネントでの状態変化での記述としています。
(なぜコンポーネントと言い切っているかというと、project内のファイルなどで使うと多用しすぎてゴチャついてしまうので、コンポーネント内の使用のみとしています。projectファイル内で状態変化のCSSを付けたい場合は、「.is-selected」など「.is-hoge」の形式で対応してください)
例えば、.c-btnというコンポーネントがあり
色の状態変化をつけるときは以下のようにクラスを定義します。
.c-btn {
&--red {
color: red;
}
&--blue {
color: blue;
}
&--yellow {
color: yellow;
}
}
このように、「--hugahuga」は状態変化と定義づけることで
「__hogehoge」との切り分けをしています。
以上がCSS設計の紹介でした。
流れるように全体をなぞってしまいましたが、これを参考にご自分のしっくりくる開発ルールを探ってみていただけると嬉しいです。