Help us understand the problem. What is going on with this article?

stylelintの導入方法と各ルール解説

フロントエンドエンジニアの松田です。
先日、副業で開発に参加しているFindyでstylelintの導入を行ったので、導入方法と各ルールについてまとめてみました。

stylelintとは

eslint, tslint等と同じようなCSSのlinterです。導入することによって、詳細度や!importantの使用制限など、CSSがカオスになってしまうのを防いでくれる効果があります。

導入方法(技術面)

User Guideに書かれているように、stylelintを利用する方法は幾つかあります。チーム開発する場合はCLIツールとして導入し、npm scriptsで実行できるようにするのが良いでしょう。各種CIツールで実行する際にも便利です。

インストール

他のCLIツールと同様にnpmもしくはyarnでパッケージを追加し、package.jsonのscriptsで実行できるようにしましょう。

npm install stylelint --save-dev
// or
yarn add -D stylelint
package.json
"scripts": {
  "lint:css": "stylelint **/*.scss",
}

導入方法(運用面)

stylelintはデフォルトではルールが設定されていないので、とりあえず導入だけしてルールを広げていくという方法がとれます。prettierなどの場合はデフォルトでもある程度ルールが決まっているので、導入の際にはルールを無効化しておいて徐々に有効化していくことが必要になりますが、stylelintではその必要はありません。

まずは導入してCIツールなどの設定をしておき、徐々にルールを拡張してきましょう。

Findyのstylelint設定

Findyではこの記事の執筆時点(2019/2/26)で、以下のルール設定になっています。まだ導入はしたばかりで、導入の際にチェックしたかった簡単なルールしか設定していませんが、徐々に拡張していきたいと考えています。

FindyではSCSSを使っているため、プラグインを追加してSCSSのルールも設定できるようにしています。

stylelintrc.json
{
  "plugins": [
    "stylelint-scss"
  ],
  "rules": {
    "color-no-invalid-hex": [true],
    "color-named": "never",
    "color-hex-case": ["lower"]
  }
}

各ルールについて

ルールごとの導入敷居

Possible errosは、そもそもCSSが機能していない部分を指摘するルールなので比較的導入が容易です。しかしPossible errosで指摘されている箇所が発生している場合は、修正の際に影響箇所の調査を必要とする場合があるので、導入ハードルはかなり上がります。ここでエラーが出ているルールは後回しにしておきましょう。

Limit language featureとStylistic issuesについては、表記の変更だけ(color-hex-lengthなど)のルールが多く、スタイル崩れが発生しづらいので導入が容易です。導入してもwarningが発生しない箇所から導入していき、warningが出る箇所については影響範囲を調査しつつ地道に導入していくのが良いでしょう。

ここからは各ルールの内容解説になります。

Possible erros

Color

color-no-invalid-hex
16進数表記が正しいかチェックしてくれます。

/* NG */
.ng { color: #00; }
/* OK */
.ok { color: #000; }

Font family

font-family-no-duplicate-names
指定が重複していないかチェックしてくれます。

/* NG */
.ng { font-family: sans-serif, sans-serif; }
/* OK */
.ok { font-family: sans-serif; }

font-family-no-missing-generic-family-keyword
sans-serifなどの一般的な使えるようなフォントを1つ以上指定しないとエラーになります。もちろんフォントがない場合は使えるフォントで自動的に表示されるため、文字自体が消えることはないですが、明示的に書きましょうというルールです。

/* NG */
.ng { font-family: Times; }
/* OK */
.ok { font-family: Times, sans-serif; }

Function

function-calc-no-invalid
calc()の表記が間違っていないかをチェックしてくれます。

/* NG */
.ng { width: calc(100% -20px); }
/* OK */
.ok { width: calc(100% - 20px); }

function-calc-no-unspaced-operator
calc()の演算子の左右にスペースが入っているかをチェックしてくれます。
NGパターンでも一見すると動作するように見えますが、スペースが入っていないとダメです。

/* NG */
.ng { width: calc(100%+20px); }
/* OK */
.ok { width: calc(100% + 20px); }

function-linear-gradient-no-nonstandard-direction
linear-gradientの表記が間違っていないかチェックしてくれます。
toが入っていない、同じ位置が指定されている、などがエラーの対象です。

/* NG */
.ng1 { background: linear-gradient(top, #fff, #000); }
.ng2 { background: linear-gradient(to top top, #fff, #000); }
/* OK */
.ok { background: linear-gradient(to bottom right, #fff, #000); }

String

string-no-newline
文字列の途中で改行が入っていないかをチェックしてくれます。CSSには文字列連結がないため、改行はできません。

/* NG */
.ng {
  content: "first
    second";     
}  
/* OK */
.ok { content: "first\\nsecond";  }

Unit

正しい単位が使われているかをチェックしてくれます。

/* NG */
.ng { width: 200pixels; }
/* OK */
.ok { width: 200px; }

Property

property-no-unknown
存在しないプロパティが使われていないかをチェックしてくれます。

/* NG */
.ng { widt: 200px; }
/* OK */
.ok { width: 200px; }

Keyframe declaration

keyframe-declaration-no-important
keyframeで!importantが使われていないかをチェックしてくれます。
ブラウザによって、keyframe内の!important指定が無視される場合があります。

/* NG */
@keyframes important1 {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(100px) !important;
  }
}
/* OK */
@keyframes important1 {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(100px);
  }
}

Declaration block

declaration-block-no-duplicate-properties
同一セレクタ内で同じプロパティが使われていないかをチェックしてくれます。displayやfont-sizeなどのコピー&ペーストでヒューマンエラーが出やすく、エラーになる場合もあるかもしれません。

/* NG */
.ng {
  display: block;
  display: inline-block;
}
/* OK */
.ok { display: block; }

declaration-block-no-shorthand-property-overrides

/* NG */
.ng {
  padding-left: 10px;
  padding: 20px;
}
/* OK */
.ok {
 padding: 20px;
 padding-left: 10px;
}

Block

block-no-empty
セレクタ指定内にプロパティがない場合にエラーになります。

/* NG */
.ng { }
/* OK */
.ok { width: 200px; }

Selector

selector-pseudo-class-no-unknown
擬似クラスの名前があっているかをチェックしてくれます。

/* NG */
.ng:hoverr { }
/* OK */
.ok:hover { }

selector-pseudo-element-no-unknown
擬似要素の名前があっているかをチェックしてくれます。

/* NG */
.ng::beforee { }
/* OK */
.ok::before { }

selector-type-no-unknown
存在しないHTML要素を指定していないかをチェックしてくれます。

/* NG */
aa { }
/* OK */
a { }

Media feature

media-feature-name-no-unknown
メディアクエリの指定が正しいかチェックしてくれます。

/* NG */
@media screen and (unknown) {}
/* OK */
@media screen and (min-width: 700px) {}

At-rule

at-rule-no-unknown
@で始まる指定が正しいかどうかチェックしてくれます。

/* NG */
@unknown {}
/* OK */
@charset "UTF-8";

Comment

comment-no-empty
空のコメントがないかチェックしてくれます。

/* NG */
/* */
/* OK */
/* Comment */

General / Sheet

no-descending-specificity
以下のような指定がないかチェックしてくれます。NGの.ng aは次の行の指定で無効化されてしまうため、意味のない指定になってしまいます。

/* NG */
.ng a { }
a { }
/* OK */
a { }
.ok a { }

no-duplicate-at-import-rules
同一ファイルをimportしていないかチェックしてくれます。

/* NG */
@import 'a.css';
@import 'a.css';
/* OK */
@import 'a.css';
@import 'b.css';

no-duplicate-selectors
重複セレクタがないかをチェックしてくれます。

/* NG */
.ng .ng1 { }
.ng .ng1 { }
/* OK */
.ok .ok1 { }
.ok1 .ok { }

no-empty-source
CSSファイルが空でないかをチェックしてくれます。

no-extra-semicolons(Autofixable)
セミコロンが重複していないかをチェックしてくれます。

no-invalid-double-slash-comments
//で始まるコメントがないかをチェックしてくれます。

Limit language features

Color

color-named
"always-where-possible"では色名をつける、"never"では色名をつけないことを強制します。必ずしも色名がついているカラーコードだけが使われているわけではなく、表記が混在してしまうので、neverがオススメです。

/* NG */
.ng { color: black; }
/* OK */
.ok { color: #000; }

Function

function-blacklist
function-whitelist
オプションによってscaleなどの関数の利用を制限できます。

function-url-no-scheme-relative
//example.comのような//で始まるURL指定がないかをチェックしてくれます。

function-url-scheme-blacklist
function-url-scheme-whitelist
オプションによってURLのscheme制限ができます。

Keyframes

keyframes-name-pattern
正規表現によってkeyframeの名前を制限できます。

Number

number-max-precision
小数点以下の桁数を制限できます。

Time

time-min-milliseconds
時間を指定する場合の最小ミリ秒を制限できます。早すぎるアニメーションが実装されてしまうことを防ぐことができます。

Unit

unit-blacklist
unit-whitelist
em, remなどの特定の単位のしようを制限できます。

Shorthand property

shorthand-property-no-redundant-values (Autofixable)

/* NG */
.ng { margin: 1px 1px 1px 1px; }
/* OK */
.ok { margin: 1px; }

Value

value-no-vendor-prefix
ベンダープレフィックスが書かれていないかをチェックしてくれます。バージョン管理するソースにはベンダープレフィックスを含めずに書いて、autoprefixerを使って自動追加するようにしましょう。

Custom property

custom-property-pattern
正規表現でカスタムプロパティの名前を制限できます。

Property

property-blacklist
property-whitelist
プロパティの使用を制限できます。

property-no-vendor-prefix
ベンダープレフィックスが書かれていないかをチェックしてくれます。バージョン管理するソースにはベンダープレフィックスを含めずに書いて、autoprefixerを使って自動追加するようにしましょう。

Declaration

declaration-block-no-redundant-longhand-properties

/* NG */
.ng {
  padding-top: 1px;    
  padding-right: 2px;    
  padding-bottom: 3px;    
  padding-left: 4px;    
}
/* OK */
.ok { padding: 1px 2px 3px 4px; }

declaration-no-important
!importantが使われていないかをチェックできます。ユーティリティクラスを集めたファイルなど、特定の箇所でのみ無効化すると良いでしょう。既存のプロジェクトに導入するのは現実的にかなり難しいので、新規プロジェクトの初期段階で設定しておきましょう。

declaration-property-unit-blacklist
declaration-property-unit-whitelist
declaration-property-value-blacklist
declaration-property-value-whitelist
特定のピクセル指定や、プロパティと値の設定を制限できます。

Declaration block

declaration-block-single-line-max-declarations
1行に設定できるプロパティの数を制限できます。設定する場合は1にしましょう。

Selector

selector-attribute-operator-blacklist
selector-attribute-operator-whitelist
selector-class-pattern
selector-combinator-blacklist
selector-combinator-whitelist
selector-id-pattern
特定のセレクタ指定を制限できます。combinatorは+などの演算子のことです。

selector-max-attribute
selector-max-class
selector-max-combinators
selector-max-compound-selectors
selector-max-empty-lines
selector-max-id
selector-max-pseudo-class
selector-max-specificity
selector-max-type
selector-max-universal
1つのセレクタ指定で使える最大値を指定できます。
compound-selectorsは.a .bなどクラスの連結の回数、specificityは詳細度の制限、typeはaなどのタグ指定の回数制限を、universalは*の回数を制限できます。

selector-max-typeはスタイル崩れを防ぐためにかなり有効です。spanタグなどの指定を使っていると、HTMLの構成を変更してspanタグではなくなってしまった場合にスタイルが崩れてしまいますが、selector-max-typeをチェックしておくと事前に防げます。

selector-max-specificityで詳細度の上限を決めておけば、複雑なCSSになることを防げます。

selector-nested-pattern
ネストのパターンを指定できます。通常のCSSではネストを使った場合はエラーになります。

selector-no-qualifying-type
aタグなどタグ指定を一切できないようにします。特定のファイル内でのみ無効化しておくと良いでしょう。

selector-no-vendor-prefix
ベンダープレフィックスが書かれていないかをチェックしてくれます。バージョン管理するソースにはベンダープレフィックスを含めずに書いて、autoprefixerを使って自動追加するようにしましょう。

selector-pseudo-class-blacklist
selector-pseudo-class-whitelist
selector-pseudo-element-blacklist
selector-pseudo-element-whitelist
擬似クラス、擬似要素の制限ができます。

Media feature

media-feature-name-blacklist
media-feature-name-whitelist
media-feature-name-value-whitelist
メディアクエリの指定を制限できます。

media-feature-name-no-vendor-prefix
ベンダープレフィックスが書かれていないかをチェックしてくれます。バージョン管理するソースにはベンダープレフィックスを含めずに書いて、autoprefixerを使って自動追加するようにしましょう。

Custom media

custom-media-pattern
正規表現でカスタムメディアクエリのパターンを指定できます。

At-rule

at-rule-blacklist
at-rule-whitelist
@ルールの制限ができます。

at-rule-no-vendor-prefix
ベンダープレフィックスが書かれていないかをチェックしてくれます。バージョン管理するソースにはベンダープレフィックスを含めずに書いて、autoprefixerを使って自動追加するようにしましょう。

Comment

comment-word-blacklist
正規表現でコメントの文言を制限できます。TODOを残さないようにする、などが可能です。

General / Sheet

max-nesting-depth
ネストの最大深さを設定できます。

no-unknown-animations
keyframeで定義されていないアニメーション名を使用していないかチェックしてくれます。

Stylistic issues

Color

color-hex-case((Autofixable))
color-hex-length((Autofixable))
16進数の大文字小文字(lower or upper)、長さ(short or long)の指定ができます。

Font family

font-family-name-quotes
スペースが含まれるフォントをクォートで囲むかどうかを指定できます。

Font weight

font-weight-notation
"numeric"にすると700などの数値指定を、"named-where-possible"にするとboldなどの名前での指定を強制できます。フォントによってはboldの数値が700でない場合もあるので、設定するなら"named-where-possible"が良いでしょう。

Function

function-comma-newline-after (Autofixable)
function-comma-newline-before (Autofixable)
function-comma-space-after (Autofixable)
function-comma-space-before (Autofixable)
function-max-empty-lines(Autofixable)
function-name-case(Autofixable).
function-parentheses-newline-inside(Autofixable)
function-parentheses-space-inside (Autofixable)
function-url-quotes
function-whitespace-after(Autofixable)
概ね名前の通りですが、表記のスタイルをチェックしてくれます。

Number

number-leading-zero (Autofixable)
1未満の数の表記を制御できます。"always"なら0.5, "never"なら.5を強制できます。これはどちらでも良いでしょう。

number-no-trailing-zeros(Autofixable)
1.0など数字が0で終わっていないかをチェックしてくれます。

String

string-quotes(Autofixable)
シングルクォートかダブルクォートかを指定できます。

Length

length-zero-no-unit(Autofixable)
0px0にするかどうかを指定できます。

以下については、カンマや空白・改行のスタイルについてのチェックなので割愛します。
Unit
Value
Value list
Custom property
Property
Declaration
Declaration block
Block
Selector
Selector list
Rule
Media feature
Media query list
At-rule
Comment
General / Sheet

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away