CSSの記法やルールを運用でカバーしていくのはキツいなと誰しも思っているところだと思います。よく巷ではなんとかlintが流行っていますが、実際導入するときどんなルールで運用すればいいか迷いますよね。自分は迷いました。
そこで、今回は自分が関わっているプロジェクトで採用した stylelint でどんなルールやプラグインを採用しているかを紹介します。
前提
- どんなルールが最適かは各チームによるので、細かい調整はチームメンバーで話し合ってください。
- 採用したルールをすべて記載しているわけではなく、特に良いなと思ったのをピックアップして紹介しています。
stylelintとは
stylelint は、CSSの書き方をプログラマーに指摘してくれるnpmモジュールです。rubyでいう RuboCop と似たものですね。公式ドキュメントによると、160以上のルールが用意されているそうです。デフォルトだと .css のみが対象なのですが、設定をいじくれば、 .scss や <style>
タグ内も対象にすることができます。
使い方
stylelint を実行するには、自前で以下のような設定ファイルを用意する必要があります。
それぞれ、
plugins
… stylelint で予め用意しているルール以外で、有志が拡張して作った独自のルール
rules
… stylelint で予め用意しているルール
を指定することができます。詳細は公式ドキュメントの https://stylelint.io/user-guide/configuration/ あたりを確認してください。
plugins:
- stylelint-declaration-block-no-ignored-properties
- stylelint-no-unsupported-browser-features
rules:
color-no-invalid-hex: true
font-family-no-duplicate-names: true
font-family-no-missing-generic-family-keyword: true
~ 省略 ~
no-eol-whitespace: true
# plugin rules below
plugin/declaration-block-no-ignored-properties: true
plugin/no-unsupported-browser-features:
- true
- browsers: [
"> 5% in JP",
"Last 2 Safari versions",
"Last 2 iOS versions",
"Last 2 Chrome versions",
"Last 2 ChromeAndroid versions",
"IE 11",
"Last 2 Edge versions",
"Last 2 Firefox versions",
"Last 2 FirefoxAndroid versions",
]
- severity: "warning"
なお、 stylelint-config-standard のように、予め必要そうなルールをまとめたものを使うこともできますが、思いの外ルールが多かったので、仕方なくルールを一つ一つ読んで選んでいきました。
良いなと思ったルール
"font-family-no-missing-generic-family-keyword": true
font-family
を書く時、ブラウザに実装されている総称ファミリは末尾につけるようにしようってルールです。総称ファミリーというのは、指定したフォント何もない!って時にフォールバックとして適用してくれるフォントタイプです。 serif|sans-serif|monospace
とかがそれです。
/* bad example */
a { font-family: 'Times'; }
/* good example */
a { font-family: 'Times', sans-serif; }
参考: https://developer.mozilla.org/ja/docs/Web/CSS/font-family
https://stylelint.io/user-guide/rules/font-family-no-missing-generic-family-keyword/
"declaration-block-no-shorthand-property-overrides": true
ショートハンドプロパティで上書きしちゃうの避けましょうってルールです。よくやりがちなのは、 background
プロパティで上書きしてしまう時でしょうか。ショートハンドプロパティで指定しなかった値は初期値になってしまうので、意図しないスタイルが当たってしまう可能性があります。
たとえば、Qiitaのナビメニューの背景色には background-color: #55c500;
が使われていますが、これで background: #55c500;
で上書きすると以下のようになります。
ちなみに、ショートハンドプロパティを一部上書きするのはアリです。
/* bad example */
a {
padding-left: 10px;
padding: 20px;
}
/* good example */
a {
padding: 20px;
padding-left: 10px;
}
"declaration-block-trailing-semicolon": "always"
プロパティの値の末尾には必ずセミコロンをつけておきましょうってルールです。最終行のプロパティの値にはセミコロン要らないって仕様になってる(正確に言うと;
はプロパティ:値
同士を区切るために使っている)んですが、新しい値を書き加えようとする時にエラーになっちゃいます。
/* bad example */
p {
margin: 0 0 20px;
font-size: 1rem /* <- ここセミコロンつけ忘れ! */
color: #555;
}
/* good example */
p {
margin: 0 0 20px;
font-size: 1rem;
color: #555;
}
参考:
https://stackoverflow.com/questions/11939595/leaving-out-the-last-semicolon-of-a-css-block
https://www.w3.org/TR/CSS2/syndata.html#declaration
"selector-pseudo-element-colon-notation": "double"
疑似要素使う時にコロンつけると思うんですけど、コロン1個だけってのは実は古い仕様で、コロン2個が正しいです。擬似クラスと区別するためって意図もあるので、ここはちゃんと書き分けたいですね。
/* bad example */
a:before { color: pink; }
/* good example */
a::before { color: pink; }
※ 以下MDNとW3Cに記載があるので引用しておきます。
https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements
Note: As a rule, double colons (::) should be used instead of a single colon (:). This distinguishes pseudo-classes from pseudo-elements. However, since this distinction was not present in older versions of the W3C spec, most browsers support both syntaxes for the original pseudo-elements.
(意訳: 擬似クラスと区別するために、シングルコロンではなくダブルコロンを使用してください。ただ、W3Cの古い仕様ではこの区別について言及されていなかったため、ほとんどのブラウザは両方の記法をサポートしています。)
Because CSS Level 1 and CSS Level 2 conflated pseudo-elements and pseudo-classes by sharing a single-colon syntax for both, user agents must also accept the previous one-colon notation for the Level 1 & 2 pseudo-elements (::before, ::after, ::first-line, and ::first-letter). This compatibility notation is not allowed any other pseudo-elements. However, as this syntax is deprecated, authors should use the Level 3+ double-colon syntax for these pseudo-elements.
(意訳: CSS Level 1 と CSS Level 2 では、擬似要素と疑似クラスの記法を一緒くたにしていたため、Level 1 とLevel 2 から定義されていた ::before, ::after, ::first-line, ::first-letter に関しては、シングルコロンの記法も許可されています。しかし、他の擬似要素では許可されていません。いずれにせよ、この記法はもう非推奨であるため、擬似要素にはダブルコロンを使用するようにしてください。)
作った人天才か?と思ったプラグイン
stylelint-declaration-block-no-ignored-properties
displayの値によって無視されてしまうプロパティを見つけてくれるpluginです。たとえば、display: inline
の要素にいくら頑張ってもwidthの値はシカトされるんですが、そういう無効な組み合わせを検知してくれるようです。こいつ天才か。
https://github.com/kristerkari/stylelint-declaration-block-no-ignored-properties
stylelint-no-unsupported-browser-features
ブラウザ非対応のプロパティがないかを検知してくれるpluginです。裏ではbrowserslistを使っているらしく、以下のように対応ブラウザのバージョン、地域などを定義すると、それらのブラウザでサポートされていないプロパティを自動的に指摘してくれます。クロスブラウザ対応を漏れなく行うのは結構大変なので、これは助かりますね。
plugin/no-unsupported-browser-features:
- true
- browsers: [
"> 5% in JP",
"Last 2 Safari versions",
"Last 2 iOS versions",
"Last 2 Chrome versions",
"Last 2 ChromeAndroid versions",
"IE 11",
"Last 2 Edge versions",
"Last 2 Firefox versions",
"Last 2 FirefoxAndroid versions",
]
他にもこんなプラグインおすすめです!などがありましたら、ぜひ教えていただけるとありがたいです!☺️