概要
- きっかけ/目標
- CSSの問題
- 5つのルール
- まとめ
きっかけ
ここ1年、毎日CSSを書いてきましたが、分かったことを伝える機会はなかなか来ないです。
目標
- めったにフロントエンドに手を加えない方でも、維持しやすいCSSが書けるように。
- そして、これから発表する点について議論を始めたいです。
前提
Fire-and-forget(ファイア・アンド・フォーゲット?)ではないプロジェクトです。
CSSの問題
CSSは客観的に難しいです。
- 新しいプログラミング言語ばかりか、超独特!
- 関心の分離(viewとmodel)はしたいですが、混ぜるの方がなぜか維持しやすい?
- ブラウザー互換性の落とし穴。
上記の3点が生み出すのは危険な開発環境です。
5つのルール
- CSSフレームワークを使いまくる
- 互換性を
autoprefixer
に任せる -
*
スタイルを使わない - 横幅と高さを固定しない
- ルート要素にpadding/marginを付けない
#1 CSSフレームワークを使いまくる
ミシャが好きなことわざ:「一番(形容詞)なコードは存在しないコードです。」
CSSフレームワークとは、よく使われるスタイルをクラス化したライブラリーのことです。最近ハマっているのはTailwindCSSです。
- CSSはほとんど構成によらなくなる
- CSSの構文、詳細が無視できる - 抽象化
- 修正する時はテンプレートより深く調べなくてよくなる
今のプロジェクトは、スタイルタグがないコンポーネントは**48% (69/146)**に止まっています。
要するに、一番維持しやすいCSSは存在しないCSSです。
#2 互換性を(ある程度)autoprefixer
に任せる
ブラウザー互換性は複雑です。ブラウザーによってCSS機能のプレフィクスが異なることは多いです。
@mixin placeholder($color) {
&::-webkit-input-placeholder { /* Chrome/Opera/Safari */
color: $color;
}
&::-moz-placeholder { /* Firefox 19+ */
color: $color;
}
&:-ms-input-placeholder { /* IE 10+ */
color: $color;
}
&:-moz-placeholder { /* Firefox 18- */
color: $color;
}
}
普段はcaniuse.comを参考しながら解決できますが、誰もそれぞれのプレフィクスが覚えられません。
でも、ブラウザーのCSSタグの差分をある程度自動的にカバーできます。そこをautoprefixerに任せましょう。例えば、上のコードはこうなります。
@mixin placeholder($color) {
&::placeholder {
color: $color;
}
}
自分でブラウザータグを書いていることに気付いたら、やめてください。
#3 *
スタイルを(基本的に)使わない
*
は再起的に子供にスタイルを付ける機能です。例えば、プロジェクト全体のフォントサイズを設定するには:
* {
font-size: 16px;
}
プロジェクトを始めていない限り、使わない方が良いです。
- 将来、コンポーネントは
<slot>
が必要になったら、内容がそのスタイルと闘うことになります。 - コンポーネントの柔軟性はある程度なくなります。
- たまに、スタイルバグを隠してしまいます。
特にpadding、margin、と色を設定するのは危ないです。共有性が破壊されます。
#4 横幅と高さを(基本的に)固定しない
罪です。
- コンポーネントの内容が変わった -> 変更
- コンポーネントに親のスペースを全部取って欲しい -> 変更
- 中身にスタイルを付けて、空に見えないように縮んで欲しい -> 変更
- …
次回は必ず固定された数字を更新するハメになります。「維持しやすい」の正反対です。
例外
- テキストと一緒に現れるコンポーネント(アイコンなど)には使うべきです。特に
em
で。 - レスポンシブウェブデザインを気にしない、アプリ全体の横幅を設定する時は使っちゃいます。
残りはほぼ全部比率あるいは内容/親の大きさに応じて決めれば良いです。見た目は自然に更新されます。
#5 ルート要素にpadding/marginを付けない
ErrorCard.vue
<template>
<div class="mb-2">
{{ error }}
</div>
</template>
App.vue
<template>
<div>
<ErrorCard class="mb-1" />
<MyForm class="mb-1" />
<MyFooter />
</div>
</template>
上記のmb-*
はmargin-bottom-*
の省略で、下のmarginを設定するCSSクラスです。
この例では:
-
mb-1
かmb-2かのどちらかが勝つから
!important`を使うことになる、あるいは使っている方を合わせる。 - 書き直すには、そのコンポーネントが使われているところを全部修正するハメになる。(テストしきれない!)
marginとpadding以外でのスタイルも、ルート要素なら慎重に付けましょう。どんなに経験を積んでも、コンポーネントの使い方はめったに予想できません。
まとめ
ルールは2種類ありました。
#1 ツールに頼る
- CSSフレームワークを使いまくる
- 互換性を
autoprefixer
に任せる
#2 コンポーネントの使い方を前提にしない
-
*
スタイルを使わない - 横幅と高さを固定しない
- ルート要素にpadding/marginを付けない
そこはコツだと思います。後はCSSを学習することです。
以上。