🌊

CSSをメンテナブルにするstylelint入門

2022/07/04に公開約7,200字

はじめに

メンテナンス性の低いCSSに怒りや苛立ちを覚えた方も少なくはないのではないでしょうか。
ですが、CSSの品質管理ツールをどのように活用するのか議論が少ない印象を持っております。
Vue CLICreate React App などのフロントエンド開発ツールには ESLintの設定が含まれていますが、CSS の linter は含まれてないのです。
そこで、stylelint の特徴や機能を使って、エラーを検知、フォーマットの一貫性やスタイリングの重複を防ぐ方法について解説します。

この記事は、stylelint の使い方やあまり知られていないルールやプラグインついても紹介します。

styelintとは?

stylelintの公式ドキュメントから引用すると

A mighty, modern linter that helps you avoid errors and enforce conventions in your styles.

チーム全体で使うCSSのエラーを回避し、コードの一貫性を高めるために役立つ モダンなlinter です。
そして、スタイルのエラーを自動的に修正してくれ、使用したいルールだけを有効にし、好みに合わせて設定することができます。

styelint はモダンなCSS構文を理解し、解析してくれます。
HTML、 Markdown、CSS in JS objects、Template literals などのさまざまな形式のCSSにも対応しています。
エディタタスクランナー, pre-commit, webpackにもプラグインがあるので、導入しやすいのも特徴の一つです。

stylelintでできること

stylelintを初めて利用する方は、stylelintのコアメンバーである David Clark が執筆したこちらを参照するのを薦めます。
ですが、 主に3つほど要点を挙げ説明させていただきます。

  • エラーを検知
  • ベストプラクティスを提供
  • コーディングルールを徹底

エラーを検知する

CSSの syntax error を検知することができます。
テキストエディタでも補完やハイライトは可能ですが、styelintでもチェックするとチームでミスを発見する必要性は限りなく少なくなるでしょう。

具体例として
color-no-invalid-hexルールとproperty-no-unknownを有効にすると
以下の syntax error を検知してくれます。

.class {
 color: #EAE2AE1; /* invalid hex color */
 with: 100px;     /* unknown property  */
}

コーデイング規約を徹底する

stylelintは、コードのスタイル規則を自動的に強制する多くのルールを備えているので、個人で悩む必要はなくなります。 コードが読みやすく、コメントは明確、意図しないエラーを最低限に抑えます。そしてgit diffgit blameなどのコマンドの利点を活かしやすくしてくれます。
開発チームの好みのスタイルフォーマットに合わせてルールセットをカスタマイズできます。フォーマット規約を確立させ、stylelintの設定に追加していきましょう。

example
.class01 {         /* セレクタと中括弧の間にスペースを入れる */
  opacity: 0.75;   /* 小数にはゼロをつける */
}

.class02, 
.class03,
.class04 {          /* 1行に1セレクタ */
  line-height: 1.6; /* line-heightには単位をつけない */
}

/* インデントはスペース2個 */
.class05 {
  background-color: #FF6F61;
  opacity: 0.75;

  &:hover {        /* ネストする場合は、一行空ける */
    opacity: 1;
  }
}

一つの材料として、こちらの idiomatic-css 一読することをお薦めです。

ベストプラクティスを提供する

好ましくないCSSのコーディングパターンを禁止することができます。
よく知られているベストプラクティスの1つは、max-nesting-depthルールを追加することでしょうか。
プリプロセッサーコードの記述で特定のセレクタのネストが深くなりすぎた場合にエラーを返します。詳細度を合理的な範囲に保ち、手に負えなくなるのを防ぎます。
セレクタも同様で。stylelint を使用すると、

  • セレクタのカテゴリを禁止(例:idセレクタの禁止)
  • 正規表現を使用して残りのセレクタの命名規則を強制
  • !importantの使用を禁止
  • サポートしているブラウザに適用されないブラウザハックを禁止(例:_:-ms-fullscreenの禁止)
  • Autoprefixer を使っている場合、開発者側のCSSでのベンダープレフィックスの使用を禁止

では、実際につかっていきます。

styelint を使ってみる

まず、npm を使って stylelint をインストールし、主なルールセットを有効にするために stylelint-config-standard も一緒にインストールします。

$ npm install --save-dev --save-exact stylelint stylelint-config-standard

stylelint-config-standardは、idiomatic CSS principlesやAirbnbのスタイルガイドなどのCSSスタイルガイドに共通する慣習に沿っており、個人的にはお薦めです。

そして、プロジェクトのルートに設定ファイルを作成します。

$ touch .stylelintrc.json

または

$ touch .stylelintrc

設定ファイルにルールを追加します。

.stylelintrc.json
{
  "extends": "stylelint-config-standard"
}

これでコマンドラインから stylint を実行できるようになりました。
プロジェクト内のCSSファイルのみを対象とする場合は、stylelint "**/*.css" と実行します。
エラーを自動的に修正するには、--fixを追加してください。

Prettier と stylelintを併用して使う

prettier はコードのフォーマットを管理するために使用されています。
prettier があるフォーマットを設定すると、stylelint はエラーとして検知して prettier と衝突することがあります。
stylelint-config-prettierを設定に含めることで、衝突するフォーマットを無効にすることができます。この設定は、ルールが上書きされないように、extends の最後に参照される設定にしましょう。

example
{
  "extends": [
    "stylelint-config-standard",
    "stylelint-config-prettier",
  ]
};

さいごに、stylelintに慣れるために、標準的なルールに目を通しておくとよいでしょう。空白の設定から始めて、必要なルールだけを追加するのもよいです。 別のプラグインをベースにして、プロジェクトが進むにつれて修正していくのも良いでしょう。

最初は自動修正は行わずに、よく発生するエラーを見て理解できるようにするのがいいと思います。 ある程度理解できたら、自動修正を行うようにしてメンテナンス性の高いCSSを書いていきましょう

次は、あまり知られていないプラグインなどの紹介をしていきます。

stylelint のオススメな設定

プロパティを並び替えてくれるプラグイン

stylelint-orderプラグイン はプロパティを自動的に好きな順番に並べ替えることができます。CSS を読みやすく、理解しやすくすることができます。
保存するたびにプロパティをソートしておくと便利です。

ですが、注意点もあります。
Sassでの@mixin@includeを使用している場合、既存の宣言順序を変更すると計算スタイルが変更される可能性があります。

https://github.com/prettier/prettier/issues/1963#issuecomment-307147922

stylelint-config-recess-order もお薦めで、関連するプロパティごとに並び替えてくれます。

example
.wrapper{ 
  /* position */
  position: absolute; 
  top: 20px;
  left: 0;
  
  /* display */
  display: flex; 
  justify-content: center;
  
  /* box-model */
  width: 100%; 
  height: 100%; 
  margin-bottom: 20px;
  margin-left: 20px; 
  margin-left: 2px;
}

小規模なチームでは、関連するプロパティをまとめて記述するのがよいでしょう。 大規模なチームでは、アルファベット順の方がシンプルでメンテナンスがしやすいと考えるかもしれません。どちらにせよ、しっかりと話し合って確立していきましょう

参考文献

https://dev.to/thekashey/happy-potter-and-the-order-of-css-5ec
https://ericwbailey.design/writing/organize-your-css-declarations-alphabetically/

アクセシビリティを高めてくれるプラグイン

アクセシビリティは重要な関心事で、stylelint-a11yプラグイン はアクセシビリティに役に立つルールを追加してくれます。

このプラグインは、以下のようなルールを追加します。

ルール 説明
content-property-no-static-value content が、装飾を目的にしたものではなく、アクセシブルではない擬似要素を許容しない
font-size-is-readable 15pxよりも小さい場合、許容しない
media-prefers-reduced-motion メディア機能でアニメーションやトランジションがある場合、特定のスタイルを要求する
no-display-none display: none プロパティによるコンテンツの非表示を許可しない
no-obsolete-attribute 廃止された属性を使用しない
no-obsolete-element 廃止されたセレクタを使用しない
no-spread-text 快適な範囲で文字幅を確保する
no-outline-none アウトラインクリアの不許可
selector-pseudo-class-focus セレクタに :hover で擬似要素を指定するかしないか

アクセシビリティの観点から、プラグインの導入をするのも興味深いですね。

CSSの誤解を防ぐプラグイン

他のプロパティ、値の組み合わせで反映されないプロパティが存在します。
たとえば、display: inlineを使用した場合、widthなどの sizeプロパティ は無視されます。
CSSに長けたエンジニアには有名な例かもしれませんが、知らない方も多いのではないでしょうか。ですが、プロジェクトの中で忘れてしまったり、見逃してしまったりするものです。

stylelint-declaration-block-no-ignored-propertiesプラグイン を使用すると、これらをエラーとして検出することができます

さいごに

メンテナンスしやすいCSSで快適なUXを実現するために、よければstylelintを使ってみてください。

間違った知識や内容がありましたら、ご指摘ください。
訂正させて頂きます。

GitHubで編集を提案

Discussion

ログインするとコメントできます