CSSの書き方は自由!だからこそルールが大切
CSSを記述していて、良くあることとして
- クラス名のルールが無く、後で読み返した時に、どこで使われているスタイルなのかわからない
- クラス名が以前記述した物と被っていて、指定していないプロパティが勝手に適応されてしまう(汚染が発生している)
- 1つのクラス名を別々の場所で複数回使っており、編集したいプロパティがどこに書いてあるかわからない
- レスポンシブに対応するため、タブレット・スマホの画面幅のスタイルを記述したが、記述場所が離れていて、探すのが大変
CSSはそれ自体に記述ルールがあまり多くないため、書く人によって、内容がばらつきがちです。
書く人ごとに違いが出るのに、その時その時の気分でクラス名などを決めていては、同じ人でも違いが発生してしまい、もう目も当てられない状態です。
そこで、CSSは自由である反面、自らを律する強いポリシーが必要となります。
CSSを全部importantで記述してるやつは本当に他人に迷惑かけてる自覚を持ってくれ
CSSの優先度は以下の順に優先されてスタイルが有効となる
- !important
- タグにstyleで記述
- タグの詳細度が高い
でも、だからって全部importantで記述してるやつを見たことがあるんだけど、そんな乱暴な仕事の仕方はもってのほかで、後々誰かが編集しようと思ったときに、絶対に邪魔になる。
人に迷惑をかけるような仕事は、仕事ではない。
CSSの記述にはルールを設定しましょう
CSSは記法の制約が少ないため、昔から記述ルールを検討されてきました。
その中で生まれた物が「OOCSS」や「SMACSS」、「BEM」などです。
CSSの記述にはいくつかのレイヤーがあると考える
CSSは何気なく使用していると、ただ羅列していくだけですが、CSSの記述に慣れてきて、無駄なコードが減り、機能ごとにスタイルを分けられるようなってくると、CSSはいくつかの役割に分けることができると気づきます。
- Reset
- Base
- Module
- Layout
CSSのReset
Resetは、既にCDNで提供されているResetCSSを使っているかもしれません。
Resetする理由ですが、pタグやinputタグなどのタグ要素には、ブラウザごとに基本スタイルが設定されています。
例えば、あるブラウザではinputとselectが同じサイズなのに、あるブラウザではselectのborderが少し広いせいで、特定のブラウザだけ入力フォームの角がそろわないという事態が発生します。
そこで「要素のスタイルを一旦リセットしてから、スタイルを組みなおしましょう」という目的で作られたのがResetCSSです。
「一旦リセットしてから」と書いてあるように、ResetCSSは最初に読み込ませます。
CSSのBase
そして、上記のResetCSSでリセットされた要素自体のスタイルをBaseで再設定します。
ここではクラス付きのスタイルではなく、あくまでも『要素に対してのみ』です。
このBaseでがっつり見出しデザインやボタンデザインを作ることはほとんどありません。
全要素をbox-sizing: border-box;にしたり、画像をブロック要素に変えたり、pタグのmargin、inputタグやtextareaタグの余白を定義しておきます。
CSSのModule
Moduleでは、繰り返し使用するスタイルを定義しておきます。
innerの余白やセクションの見出し、ボタンデザインなどがそれにあたります。
ここからそのサイト特有のスタイルが入ってきます。
また、複数カラム表示するためのクラスや、中央寄せ・右寄せなどのどのサイトでも使いそうなスタイルも、繰り返し使うので、ここで定義しておきます。
CSSのLayout
Layoutでは、ページごとの固有のスタイルを定義します。
Moduleで部品は書き出したけど、それでもこのページでしか使わない固有のスタイルやModuleに定義したスタイルよりも少しだけ余白が大きい箇所などがあると思います。
そういった調整をLayoutに記述していきます。
現代ではさらにレスポンシブ対応も求められる
上記の構成は1画面作る場合の構成で、現代ではさらにPC表示はこう、タブレット表示はこう、スマホ表示はこうと細分化してやる必要があります。
私のCSS構成は以下の通りです。
これだけのファイルを通過して、ブラウザ上に表示されるスタイルが決まります。
なお、Layoutの所、『なぜタブレットとスマホでは、一度PC用を読み込んでから、それぞれのサイズ用のスタイルを読み込んでいるか』ですが、これは開発効率の問題です。
完全にそれぞれのLayoutで独立させた方が無駄なコードが減り、通信のデータ量が圧縮できますが、非常に開発効率が悪かったため、PC用Layoutを元に、違う部分だけスタイルを上書きするようにしています。
クラス名の命名規則(BEM)
クラス名は記述者が自由に命名できます。
英語で書く人が居れば、ローマ字で書く人も居たり、勝手に省略して暗号のようにしてみたりと本当に様々です。
しかし、これを自由にしてしまうと、CSSの汚染は必ず発生します。
CSSの汚染を防ぐためにも命名規則は非常に重要です。
例えば、以下の例
.error {
display: block;
margin: 0px auto;
padding: 20px 35px;
max-width: 640px;
border: 1px solid red;
border-radius: 10px;
}
/* 見出しデザイン */
.headline {
display: block;
margin: 0px -20px;
padding: 10px 20px;
color: white;
font-size: 20px;
font-weight: 700;
background: gray;
border-radius: 10px;
}
.headline.red { /* ←問題はここと */
background: red;
}
/* テキスト色 */
.black { color: black; }
.blue { color: blue; }
.red { color: red; } /* ←ここ */
実際に組んでみました。
See the Pen CSS汚染例 by Uilou (@uilou754) on CodePen.
見出しが真っ赤になって潰れてしまっています。
これがCSSの汚染であり、事例として特に色で発生しやすいです。
このようなCSSの汚染を防ぐために、BEMを活用していく方法をオススメします。
BEMを活用すると以下のような記述となります。
.error {
display: block;
margin: 0px auto;
padding: 20px 35px;
max-width: 640px;
border: 1px solid red;
border-radius: 10px;
}
/* 見出しデザイン */
.error__headline {
display: block;
margin: 0px -20px;
padding: 10px 20px;
color: white;
font-size: 20px;
font-weight: 700;
background: gray;
border-radius: 10px;
}
.error__headline--red {
background: red;
}
/* テキスト色 */
.color--black { color: black; }
.color--blue { color: blue; }
.color--red { color: red; }
BEMはスタイルをBlock・Element・Modifierで切り分け、それを名前で区切る方法です。
上記例では、errorがBlockであり、headlineがElement(Blockを構成する要素)、redがModifier(Emelemtの状態違い)となっていて、それぞれアンダーバーやハイフン2連続でつないでいます。
このようにBEMではクラス名が長くなるデメリットがある物の、CSSの汚染が発生しにくい環境を作ることが出来ます。
また、Tailwindなどを見ていると、1クラスにあまりスタイルを詰め込まず、1つの要素に複数クラスを指定するのが最近のトレンドなのかなって思います。
BEMについては以下の記事でも触れていますので、読んでみてください。
プロパティの記述にもルールを設ける
ここまで読み進めてきて、プロパティにもいくつかパターンがあるのに気づきませんか?
- 要素の大きさや余白、配置を決めるプロパティ
- 要素の色やフォントや文字サイズなど見た目を決めるプロパティ
この2種類があるはずです。
私はこのプロパティの記述順もルールを設けています。
たまに以下のような状態がありませんか?
.headline {
font-size: 20px;
font-family: serif; /* ←ここと */
color: white;
display: block;
padding: 10px 20px;
font-weight: 700;
margin: 0px -20px;
font-family: serif; /* ←ここ */
background: gray;
}
記述場所がバラバラだから、一度書いたプロパティを見逃して、また同じプロパティを記述してしまう。
これは「書き換えてるのに、見た目が変わらない!」という凡ミスも発生しますし、2重定義していると、その分データの転送量の無駄です。
.headline {
/* 大きさや配置に関わるプロパティを先に */
display: block;
margin: 0px -20px;
padding: 10px 20px;
/* フォントの色や形に関わる物を次に */
color: white;
font-family: serif;
font-size: 20px;
font-weight: 700;
/* 背景色や枠線、要素の変形に関わる物を最後に */
background: gray;
}
このようにしていけば、関連したプロパティ同士の距離が近くなるので、見落とすことはほとんどありません。
もしお困りごとがありましたら、お問い合わせフォームよりご相談ください。