---
title: "Stylelintとは？v18の変更点・導入手順・設定とVS Code・CI連携【18.0対応】"
url: "https://www.issoh.co.jp/tech/details/10686/"
published: 2026-01-22
updated: 2026-11-11
categories: ["開発"]
publisher: "株式会社一創"
---

# Stylelintとは？v18の変更点・導入手順・設定とVS Code・CI連携【18.0対応】

Stylelint（スタイルリント）は、CSSのコードをルールに沿って自動で点検するオープンソースのリンターです。存在しないプロパティ、重複したセレクター、ブラウザが読めない値の書き方などを、レビューの前に機械的に見つけます。JavaScriptでいうESLintにあたるツールで、SCSSやLess、Vueの単一ファイルコンポーネント内のCSSも設定次第で検査できます。

2026年11月3日に、メジャー版の18.0.0が公開されました。CLIの引数の読み方が変わり、カスタムプロパティを使った値まで検査するようになった一方で、SCSS向けの共有設定はまだ18に対応していません。この記事では18.0.0と、比較用に17.16.0をNode.js 26.5.0上で動かした出力をもとに、v18の変更点、上げてよいかの判断、導入と設定ファイルの書き方、VS Code・Prettier・CIとの組み合わせ方を説明します。

## まとめ：Stylelint 18の要点と今入れる構成

- StylelintはCSS用のリンター。現行は18.0.0（2026年11月3日）で、Node.js 22.22.2以上・24.15.0以上・26.0.0以上のいずれかが必要（20.xは対象外）
- 新規導入は `stylelint` 18.0.0と `stylelint-config-standard` 41.0.0を入れて `stylelint.config.mjs` を置く。標準設定は82ルールから86ルールに増えた
- CLIは `--mw` などの省略形と `--allowEmptyInput` などのcamelCase表記を受け付けなくなった。`--fix lax` と空白で区切ると `lax` がファイル名として読まれる
- `var(--foo)` を使った値も、宣言されている値に置き換えて検査するようになった。17.16.0では素通りした `top: var(--foo)`（中身は `red`）が18.0.0ではエラーになる
- SCSSを使う、`stylelint-config-recess-order` で並び順を揃えている、GitHubの注釈フォーマッターを使っている場合は、2026年11月11日時点で18と一緒にインストールできない（`ERESOLVE`）。対応版が出るまで17.16.0に留める
- VS Code拡張は3.0.0（VS Code 1.110.0以上）でないとv18を扱えない。CIで警告も止めるなら、設定の `maxWarnings` ではなくCLIの `--max-warnings 0` を使う

## lint（リント）の意味とStylelintが検査する範囲

### lintの語源とリンターの役割

lint（リント）は、ソースコードを実行せずに読み、バグの原因になりそうな書き方や規約違反を指摘する作業を指します。名前の元は、1978年にベル研究所のStephen C. JohnsonがC言語向けに作った検査プログラム「lint」で、英語のlintは衣服から出る糸くずを指す語です。Johnsonの論文「Lint, a C Program Checker」では、型の不整合や移植性など、コンパイラが見逃す問題を検出する用途が説明されています。

この検査を行うツールを「リンター（linter）」と呼びます。JavaScriptならESLint、文章ならtextlint、CSSならStylelintが代表格です。ESLintの設定方法は[ESLintをVSCodeで使う設定手順｜ESLint 10のflat configと保存時の自動修正【10.13対応】](/tech/details/3286/)で扱っています。

### Stylelintが見つける問題と見つけない問題

18.0.0の本体には153のルールが入っています（`stylelint.rules` の件数。17.16.0は150）。どれも既定では無効で、設定ファイルで選んだものだけが動きます。公式の共有設定 `stylelint-config-recommended`（19.0.0）は誤りの検出に絞った46ルール、それを含む `stylelint-config-standard`（41.0.0）は命名や記法の規約まで含めて86ルールを有効にします（どちらも共有設定だけをextendsして `--print-config` で数えた値）。

インデント幅や改行位置といった見た目の整形は、v15で非推奨になり、v16.0.0でまとめて削除されました。整形は[Prettierとは？意味・読み方と使い方・設定、ESLintとの違い【3.9対応】](/tech/details/3354/)のようなフォーマッターに任せ、Stylelintは「動かない・意図と違う・規約に反する」CSSの検出に専念する、というのが現在の役割分担です。v15以前の設定に `indentation` が残っていると、18.0.0では `Unknown rule indentation` のエラーになります。

## Stylelint 18の変更点と影響範囲

公式の移行ガイド（[Migrating to 18.0.0](https://stylelint.io/migration-guide/to-18/)）と[CHANGELOG](https://github.com/stylelint/stylelint/blob/main/CHANGELOG.md)によると、18.0.0には13の破壊的変更と4つの新ルールが入っています。利用者側で対応が要るものを影響範囲ごとに並べました。

| 変更                       | 影響を受ける人                  | 対応                   |
| ------------------------ | ------------------------ | -------------------- |
| Node.js 22.22.2未満などを非対応  | 全員                       | Node.jsを更新           |
| CLIの引数解析をparseArgsに変更    | npm scripts・CIの記述        | フラグの綴りを直す            |
| var()の値も検査               | カスタムプロパティを使う人            | 新しい指摘を確認             |
| 標準設定に5ルール追加              | 共有設定の利用者                 | 新しい指摘を確認             |
| パスの拡張子省略を廃止              | extends・pluginsで相対パスを書く人 | ファイル名まで書く            |
| グローバルのnode\_modulesを探さない | 共有設定をグローバルに入れた人          | プロジェクトに入れる           |
| globbyOptionsを一部だけに縮小    | `gitignore` などを指定していた人   | `--ignore-path` に置換  |
| ルール1つと2つのオプションを削除        | 該当ルール・オプションの利用者          | 設定から外す               |
| `context.fix` を削除        | プラグイン作者                  | `report` に `fix` を渡す |

### CLIフラグの解析変更と受け付ける表記

18.0.0では、CLIの引数をNode.js組み込みの `node:util.parseArgs` で解析するようになり、受け付ける綴りが減りました。17.16.0で通っていた書き方を18.0.0で実行すると、次のように止まります（終了コードはどれも64）。

```
$ npx stylelint a.css --mw 0
Invalid option "--mw". Did you mean "--max-warnings"?

$ npx stylelint "nomatch/*.css" --allowEmptyInput
Invalid option "--allowEmptyInput". Did you mean "--allow-empty-input"?

$ npx stylelint a.css --cache=false
Invalid option "--cache=false". Did you mean "--no-cache"?

$ npx stylelint -c=s.mjs a.css
Invalid option "-c=s.mjs". Did you mean "-c s.mjs"?
```

止まってくれるものは直し方が表示されるので困りません。危ないのは `--fix lax` と空白で区切った書き方です。18.0.0は `lax` をファイル名として読みます。他の対象パターンと並べた `npx stylelint b.css --fix lax` はエラーを出さずに終了コード0で終わり、`lax` 指定は効かないまま既定の `strict` で修正されます。対象パターンを書かずに `--fix lax` だけを渡すと `No files matching the pattern "lax" were found` で止まります。laxを使うなら `--fix=lax` と等号でつなぎます。

17.xで「`--fix=false` を付けても修正される」と問題になった挙動は、18.0.0では直っています。`#ffffff` を含むファイルに `--fix=false` を付けて実行すると、ファイルは書き換わらず、`color-hex-length` の指摘を出して終了コード2で終わりました。

### var()を展開して値を検査する／value-no-invalidの新設

`declaration-property-value-no-unknown` は、`var()` を宣言済みの値に置き換えてから検査するようになりました。次のCSSは17.16.0の標準設定では計算式のエラーが1件、18.0.0の標準設定ではカスタムプロパティの値のエラーも加わって2件になります。

```
:root {
  --foo: red;
}

a {
  top: var(--foo);
  margin: calc(1px + 2);
}
```

```
a.css
  6:8   ✖  Unknown value "red" for property "top", via "var(--foo)"                         declaration-property-value-no-unknown
  7:16  ✖  Invalid value "1px + 2", a number and a dimension or percentage cannot be added  value-no-invalid
```

2行目の `calc(1px + 2)` は、単位のある値に数値を足す無効な計算です。この種の検査は `declaration-property-value-no-unknown` から新ルール `value-no-invalid` に移りました。標準設定を使わず個別にルールを並べている場合、`value-no-invalid` を足さないと、v17まで出ていた指摘が黙って消えます。

デザイントークンなど別ファイルで宣言したカスタムプロパティは、そのままでは展開されません。後の章で扱う `referenceFiles` で読み込ませます。

### 標準設定41.0.0で増えた5ルール

17.xのマイナー版で追加された新ルールは、`stylelint-config-standard` 40.0.0には入っていませんでした。41.0.0（2026年11月3日）では、`stylelint-config-recommended` 19.0.0側に次の5ルールが加わり、標準設定にも引き継がれます。17.16.0＋40.0.0と18.0.0＋41.0.0の `--print-config` を比べた差分と一致します。

| ルール                          | 追加された版  | 検出する内容         |
| ---------------------------- | ------- | -------------- |
| `selector-no-deprecated`     | 17.8.0  | 非推奨のセレクター      |
| `selector-no-invalid`        | 17.10.0 | 構文上無効なセレクター    |
| `selector-no-unmatchable`    | 17.15.0 | 何にも一致しないセレクター  |
| `at-charset-rule-no-invalid` | 18.0.0  | 無効な `@charset` |
| `value-no-invalid`           | 18.0.0  | 解析できない値・無効な計算  |

差分ではもう1つ、`declaration-block-single-line-max-declarations` が標準設定から外れています。本体からも削除されたルールです（次の節）。

既存コードの無効なセレクターを検出するのが `selector-no-invalid` です。18.0.0では `.x::before .y` に対して `Invalid selector ".x::before .y", combinators are invalid after "::before"` と報告しました。擬似要素の後ろに子孫セレクターを書いたこのセレクターは、どの要素にも一致せず無視されるため、気付きにくい不具合です。

### 削除されたルール・オプションと黙って無視されるもの

削除されたものは、設定に残したときの挙動が一様ではありません。18.0.0で試した結果は次のとおりです。

- `declaration-block-single-line-max-declarations`：`Unknown rule` のエラー。整形系として扱いたいなら、コミュニティ製の `@stylistic/stylelint-plugin`（6.0.1、Stylelint 18専用）の `@stylistic/declaration-block-single-line-max-declarations` に移す
- `selector-max-specificity` の `ignoreSelectors`：警告もエラーも出ず、オプションだけが無視される。CSS Modulesの `:global()`・`:local()` は詳細度0として扱われるが、`:global(#x) .y` の中の `#x` は数えられ、`"0,2,0"` の上限を超えたと報告された
- `extends: ["./loc"]` のような拡張子を省いたパス：`Could not find "./loc"` の設定エラー（終了コード78）。`"./loc/index.js"` と書けば通る
- `--globby-options '{"gitignore":true}'`：`unknown option "gitignore"` のエラー。`--ignore-path .gitignore` に置き換える。ただし `.stylelintignore` の自動読み込みも止まるので、使っているなら `--ignore-path` を2回並べて両方を指定する

`ignoreSelectors` は黙って効かなくなるので、移行時に設定ファイルを `ignoreSelectors` で検索しておく必要があります。CommonJSの `require("stylelint")` は18.0.0でも `.cjs` から動きました（require(esm)）。`stylelint.config.ts` は `typescript` パッケージ無しで読み込めるようになった代わりに、`enum` を書くと `SyntaxError` で止まります。型は `import type` で読み込みます。

## 18へ上げてよいか：SCSS・並び順・GitHub注釈の対応状況

v18に上げられるかは、本体より周辺パッケージで決まります。2026年11月11日にnpmレジストリ（例：[stylelint-config-standard-scss](https://www.npmjs.com/package/stylelint-config-standard-scss)）で `peerDependencies` を確認し、`stylelint@18.0.0` と同時に `npm i` した結果です。

| パッケージ（最新版）                                   | 対応するStylelint                      | 18と同時インストール |
| -------------------------------------------- | ---------------------------------- | ----------- |
| `stylelint-config-standard` 41.0.0           | ^18.0.0                            | 可           |
| `stylelint-config-standard-scss` 17.0.0      | ^17.0.0                            | ERESOLVE    |
| `stylelint-config-recommended-scss` 17.0.1   | ^17.0.0                            | 不可（peer範囲外） |
| `stylelint-scss` 7.4.0                       | ^16.8.2 \|\| ^17.0.0               | 不可（peer範囲外） |
| `stylelint-config-recess-order` 7.10.0       | ^16.18.0 \|\| ^17.0.0              | ERESOLVE    |
| `@csstools/stylelint-formatter-github` 2.0.0 | ^17.0.0                            | ERESOLVE    |
| `stylelint-order` 8.1.3                      | ^16.18.0 \|\| ^17.0.0 \|\| ^18.0.0 | 可           |
| `@stylistic/stylelint-plugin` 6.0.1          | ^18.0.0                            | 可           |
| `stylelint-config-recommended-less` 5.0.0    | ^18                                | 可           |

SCSSを書いているプロジェクトは、`stylelint-config-standard-scss` の18対応版が出るまで17.16.0に留めます。`--legacy-peer-deps` で無理に入れることはできますが、SCSS用ルールが18.0.0のAPI変更（`context.fix` の削除など）に追随している保証がありません。17.16.0のリリースノートは「17.xの最後のリリースになる見込み」としているので、17に留まる間は新しいバグ修正は届かないと考えておきます。

素のCSSと `stylelint-order` だけで運用しているなら、Node.js要件と設定・CLIの破壊的変更を確認したうえで18へ移行できます。GitHubの注釈フォーマッターを使っている場合は、注釈を一時的に諦めて18に上げるか、対応版を待つかの選択になります。

## v17で入った変更（v16から上げる場合）

v16から直接18に上げる場合は、2026年1月15日の17.0.0で入った次の変更も一緒に片付けます（[Migrating to 17.0.0](https://stylelint.io/migration-guide/to-17/)）。

- CommonJS版のNode.js APIが削除され、パッケージはESMのみになった。Node.js APIで修正結果を `result.output` から読んでいたら `result.code` に変える
- `--fix` の既定が `strict` になり、構文エラーのあるファイルは直さない。閉じ括弧が足りないCSSに18.0.0で `--fix` をかけると、`Unclosed block CssSyntaxError` だけを報告してファイルは変わらない
- 組み込みの `github` フォーマッターが削除された。指定すると `You must use a valid formatter option` で止まる
- selector-max系の8ルールは、ネストを展開せず `:is()` や `:has()` の中身も数える。`"selector-max-class": 1` で `.foo:has(.bar)` を検査すると `Too many class selectors` になる

### checkContextFunctionalPseudoClassesとresolveNestedSelectorsの削除

`selector-max-id` の `checkContextFunctionalPseudoClasses` は、`:has()` などの中のIDも数えるかを切り替えるオプションでした。v17で中も数えるのが既定になり、オプション自体が消えています。設定に残したまま18.0.0で実行すると `Invalid option name "checkContextFunctionalPseudoClasses" for rule "selector-max-id"` と表示されるので、オプションを外して `"selector-max-id": 2` のように数値だけにします。

`selector-class-pattern` の `resolveNestedSelectors` は、SCSSの `&__title` のような文字列連結のネストを展開してクラス名を検査するオプションでした。標準のCSSネストは文字列を連結しないため削除されました。SCSSでBEMの命名を検査したいなら、`stylelint-config-standard-scss` の `scss/selector-class-pattern` に移します。

## 導入手順：Node.jsの確認と手動セットアップ

### 必要なNode.jsの版

18.0.0の `engines` は `^22.22.2 || ^24.15.0 || >=26.0.0` です。2026年4月にサポートが終わった20.xに加え、22.xでも22.22.2より前、24.xでも24.15.0より前は対象外です。CIのイメージが22系の古いパッチ版のままになっていないか先に確認します。長期サポート版の選び方は[Node.js LTSの最新は24、10月28日に26へ昇格｜v22・v24のEOLと確認・固定・移行の手順](/tech/details/17906/)を参照してください。

### 手動セットアップの3ステップ

公式の手順は、`npm create stylelint@latest` で対話的に入れる方法と、手動で入れる方法の2つです。何が入るかを把握するために、手動の手順を示します。共有設定はグローバルではなくプロジェクトに入れます。18.0.0からはグローバルの `node_modules` を探さなくなりました。

```
npm add -D stylelint stylelint-config-standard
```

プロジェクトのルートに `stylelint.config.mjs` を作ります。

```
/** @type {import('stylelint').Config} */
export default {
  extends: ["stylelint-config-standard"]
};
```

あとは対象ファイルを指定して実行します。パターンは引用符で囲み、シェルではなくStylelintに展開させます。

```
npx stylelint "**/*.css"
```

終了コードは、指摘なしが0、エラーの指摘ありが2、CLIの引数の誤りが64、設定ファイルの誤りが78です。警告（`warning`）だけなら0のまま終わるので、CIでの扱いは後の章で説明します。

## 設定ファイルの書き方：extends・rules・overrides

実務では、共有設定を土台にして、合わないルールだけを上書きします。BEMで命名しているプロジェクトに `stylelint-config-standard` をそのまま当てると、18.0.0でも `.card__title` と `.card--active` が `Expected class selector ".card__title" to be kebab-case` と指摘されます。標準設定のクラス名ルールがケバブケースだけを許すためです。

```
/** @type {import('stylelint').Config} */
export default {
  extends: ["stylelint-config-standard"],
  ignoreFiles: ["dist/**", "**/*.min.css"],
  rules: {
    // BEM（block__element--modifier）を許可する
    "selector-class-pattern": [
      "^[a-z][a-z0-9]*(-[a-z0-9]+)*(__[a-z0-9]+(-[a-z0-9]+)*)?(--[a-z0-9]+(-[a-z0-9]+)*)?$",
      { message: "クラス名はBEM形式（block__element--modifier）で書いてください" }
    ],
    // 当面は警告に留める
    "no-descending-specificity": [true, { severity: "warning" }],
    // 使わないルールは null で無効化
    "selector-id-pattern": null
  },
  overrides: [
    {
      files: ["**/legacy/**/*.css"],
      rules: { "no-descending-specificity": null }
    }
  ]
};
```

上の正規表現に差し替えると、2つのクラス名の指摘は消えました。ルールの値は、主オプション単独（真偽値・文字列・数値など）、`null`（無効）、主オプションと副オプションの配列（2要素目に `severity` や `message`）の3通りです。一部のディレクトリだけ基準を緩めたいときは `overrides` にファイルパターンごとの上書きを書きます。

コード中で一時的に検査を外すには `/* stylelint-disable-next-line selector-max-id */` のようにルール名を付けたコメントを使います。ルール名を省くと全ルールが外れ、後から見て何を許したのか分からなくなります。

## デザイントークンを守らせる：referenceFilesとカスタムプロパティ系ルール

18.0.0では、別ファイルのカスタムプロパティを読み込む `referenceFiles` が正式機能になり、トークンの使い方を縛る2つのルールが加わりました。`declaration-property-custom-property-allowed-list` はプロパティごとに使ってよいカスタムプロパティを決め、実験的ルールの `value-type-custom-property-required-list` は指定した型の値にカスタムプロパティを強制します。

```
// stylelint.config.mjs
export default {
  extends: ["stylelint-config-standard"],
  referenceFiles: "tokens/*.css",
  rules: {
    "declaration-property-custom-property-allowed-list": {
      "/^(margin|padding)/": ["/^--spacing-/"],
      "border-radius": ["/^--radii-/"]
    },
    "value-type-custom-property-required-list": ["length"]
  }
};
```

`tokens/tokens.css` に `--spacing-m: 8px`・`--radii-s: 4px`・`--brand: red` を置き、別ファイルで `border-radius: var(--spacing-m)`、`margin: 1rem`、`top: var(--brand)` と書いて検査した結果が次です。

```
tk.css
  2:22  ✖  Disallowed custom property "--spacing-m" for property "border-radius"  declaration-property-custom-property-allowed-list
  3:11  ✖  Expected "1rem" to be a custom property, as of type "<length>"         value-type-custom-property-required-list
  5:8   ✖  Unknown value "red" for property "top", via "var(--brand)"             declaration-property-value-no-unknown
```

3件目は、`referenceFiles` で読み込んだ値を `var()` の展開に使った結果です。`referenceFiles` を外して標準設定だけで同じファイルを検査すると、指摘はゼロでした。トークンをCSSファイルで管理しているなら、まず `referenceFiles` だけを足すのが得です。設定1行で、トークンの中身と使い方の食い違いが見えるようになります。

## CSSネストとselector-max系ルールの数え方

`no-descending-specificity` と `selector-max-specificity` は、CSS Nestingの仕様に合わせて詳細度を計算します。ネストセレクター `&` の詳細度は、親のセレクターリストのうち最も高いものと同じです。

```
#foo,
.bar {
  & a { color: red; }
}
/* :is(#foo, .bar) a と同じ。詳細度は 1,0,1 */
```

`.bar` の中に書いた `a` でも、隣にIDセレクターが並んでいるだけで詳細度は1,0,1になります。ネスト先で詳細度が跳ね上がり、後から書いたスタイルが効かない原因を、このルールで先に検出できます。

SCSSやLessの非標準ネストを使う場合、v17の移行ガイドは `no-descending-specificity`、`selector-max-specificity`、`no-duplicate-selectors`、`selector-no-qualifying-type` の無効化を案内しています。Lessには、`peerDependencies` を `stylelint: ^18` とした [stylelint-config-recommended-less](https://www.npmjs.com/package/stylelint-config-recommended-less) 5.0.0があります。

## プロパティの並び順を揃える：stylelint-order

宣言の並び順はStylelint本体のルールにはなく、プラグインの `stylelint-order` が受け持ちます。8.1.3でStylelint 18に対応しました。

```
npm add -D stylelint-order
```

```
export default {
  extends: ["stylelint-config-standard"],
  plugins: ["stylelint-order"],
  rules: {
    "order/properties-order": [
      ["position", "top", "display", "margin", "padding", "color"],
      { unspecified: "bottomAlphabetical" }
    ]
  }
};
```

`color`・`display`・`position`・`top` の順に書いたブロックを検査すると、`Expected "display" to come before "color"` など2件が出ます。`--fix` をかけると `position`・`top`・`display`・`color` の順に並べ替えられました。リストに無いプロパティは `unspecified` で末尾にアルファベット順で寄せます。

並び順を自分で決めたくない場合は `stylelint-config-recess-order` がよく使われますが、前の章のとおり7.10.0は18と同時に入りません。v18で使うなら、当面は上のように `stylelint-order` に順序を直接書きます。

## Prettierとの併用：stylelint-config-prettierは不要

古い記事では、Prettierと併用するために `stylelint-config-prettier` を `extends` の最後に入れるよう案内されています。このパッケージの `peerDependencies` は `stylelint >=11.x <15` のままで、v18と一緒には入りません。v16で整形系ルールが削除されたため、Prettierで整形し、Stylelintで検査する、と分けるだけで済みます。整形もStylelintで指摘したい場合は `@stylistic/stylelint-plugin` 6.0.1を使いますが、Prettierと併用するならこのプラグインは入れません。両方が同じ箇所を別の形に直そうとします。

### Rust製のCSSリンターを選ぶ場合

Stylelint本体はNode.js上で動くJavaScript製のツールです。Rust製で速さを求めるなら、CSSのリントと整形を備えた[Biome v2とは？最新2.6の導入・biome.json設定とESLint/Prettier移行](/tech/details/7390/)が候補です。ただし `stylelint-scss` や `stylelint-order` のようなプラグイン群、`referenceFiles` を使ったトークン検査はBiomeにはないため、これらに頼っているならStylelintを残します。

## VS Code拡張の設定：v18は3.0.0以上が必須

公式拡張 `stylelint.vscode-stylelint` は、2026年11月3日の3.0.0でStylelint 18に対応しました（[リリース一覧](https://github.com/stylelint/vscode-stylelint/releases)）。3.0.0はVS Code 1.110.0以上が必要です。v17は2.0.0以上で扱えるので、17.16.0に留めるプロジェクトでは2.2.1のままでも動きます。拡張はワークスペースにインストールされたStylelintを使います。

既定で検査するのは言語IDが `css` と `postcss` のファイルだけです。保存時に自動修正するなら、`settings.json` に次を書きます。

```
{
  "stylelint.validate": ["css", "postcss"],
  "editor.codeActionsOnSave": {
    "source.fixAll.stylelint": "explicit"
  },
  "css.validate": false
}
```

最後の行は、VS Code組み込みのCSS検査を止める任意の設定です。同じ問題が二重に表示される場合に指定します。17.16.0でSCSSを検査するなら、`stylelint.validate` に `"scss"` を足し、`"scss.validate": false` も書きます。

## CIで警告まで止める設定とGitHub Actions

### maxWarnings設定とCLI終了コードの関係

設定ファイルに `maxWarnings: 0` を書いても、CLIの終了コードには効きません。18.0.0で、警告1件のファイルを設定の `maxWarnings: 0` だけで検査すると終了コードは0、同じファイルに `--max-warnings 0` を付けると `Max warnings exceeded: 1 found. 0 allowed` と表示され終了コード2でした。17.16.0と同じ挙動です。CIで警告も失敗扱いにするならフラグで指定します。省略形の `--mw 0` は18.0.0では使えません。

### GitHub Actionsのワークフロー例

以下は、`package.json` と `package-lock.json` をコミット済みの構成です。`.github/workflows/stylelint.yml` に保存します。

```
name: stylelint
on: [pull_request]
jobs:
  lint-css:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-node@v7
        with:
          node-version: lts/*
          cache: npm
      - run: npm ci
      - run: npx stylelint "**/*.css" --max-warnings 0 --color
```

18.0.0は色付けの判定を `node:util.styleText` に切り替えました。パイプ先に出力したときはエスケープシーケンスが0件で、`--color` を付けると色が付きました。ログに色を残したいなら `--color` か環境変数 `FORCE_COLOR` を指定します。PR画面に注釈を出す [@csstools/stylelint-formatter-github](https://www.npmjs.com/package/@csstools/stylelint-formatter-github) は、2.0.0の `peerDependencies` が `stylelint: ^17.0.0` で18と同時に入らないため、17.16.0に留める場合だけ `--custom-formatter` で指定します。`setup-node` の入力は[actions/setup-nodeとは｜v7.1の入力・キャッシュ設定とv4からの移行点](/tech/details/17919/)、ワークフロー全体の組み方は[GitHub Actionsでビルド・自動テストを設定する方法｜build.ymlの書き方と失敗の直し方](/tech/details/2497/)で解説しています。

## 既存プロジェクトへの入れ方とv17からの移行順序

既存のCSSにいきなり `stylelint-config-standard` の86ルールを当てると、命名や記法の指摘が大量に出て、本当に危ない指摘が埋もれます。最初は `stylelint-config-recommended` の46ルールだけでCIに組み込み、誤りの指摘をゼロにしてから `standard` に切り替える、という2段階が現実的です。

v17から上げる場合は、次の順で確認すると手戻りが少なくなります。

1. 使っている共有設定・プラグインの `peerDependencies` が `^18` を含むか確認する（SCSS系なら待つ）
2. 手元・CI・VS Codeが使うNode.jsが22.22.2以上（24系なら24.15.0以上）か確認し、VS Code拡張を3.0.0に上げる
3. `stylelint` 18.0.0と `stylelint-config-standard` 41.0.0をまとめて上げる
4. npm scriptsとCIの `--mw`・`--aei`・camelCaseのフラグ・`--fix lax` を直し、設定の `ignoreSelectors`・拡張子のないパスを検索する
5. `npx stylelint "**/*.css"` を実行し、`var()` 展開と新しい5ルールで増えた指摘を確認する

Stylelintを入れなくてよいのは、CSSをほとんど書かず、Tailwind CSSのユーティリティクラスだけで画面を作っている場合です。検査対象のCSSが少なければ、ルールの調整にかける手間の方が大きくなります。複数人が同じCSSを触り、詳細度やトークンの使い間違いが繰り返されるプロジェクトでは、再発防止に必要なルールから導入します。

## よくある質問

### Stylelintとは何ですか？読み方は？

CSSを点検するオープンソースのリンターで、読み方は「スタイルリント」です。存在しないプロパティや無効なセレクター、命名規約違反などを検出し、一部は `--fix` で自動修正できます。lint（リント）は、プログラムを実行せずにソースコードを読んで誤りを指摘することを指します。

### stylelint –fixで直らないのはなぜですか？

自動修正の既定は `strict` で、構文エラーのあるファイルは修正されません。出力に `CssSyntaxError` があれば、先にその箇所を手で直してから再実行します。18.0.0で `--fix lax` と空白で区切った場合も、laxは効かず `strict` のまま動きます。自動修正に対応していないルールの指摘も残ります。

### Stylelint 18はNode.js 20で動きますか？

動きません。18.0.0の要件は `^22.22.2 || ^24.15.0 || >=26.0.0` です。Node.js 20を使い続けるなら、20.19.0以上で動く17.16.0に留めます。

### SCSSでStylelint 18は使えますか？

2026年11月11日時点では、`stylelint-config-standard-scss` 17.0.0と `stylelint-scss` 7.4.0がStylelint 17までしか対応していません。18と一緒に入れると `ERESOLVE` で止まるため、対応版が出るまで17.16.0を使います。

### stylelint-config-standardとstylelint-config-recommendedの違いは何ですか？

`recommended` は誤りの検出に絞った46ルール、`standard` はそれに命名・記法の規約を加えた86ルールです（18.0.0で `--print-config` により数えた値）。既存プロジェクトでは `recommended` から始めると指摘が少なく導入しやすくなります。

## 関連記事

- [ESLintをVSCodeで使う設定手順｜ESLint 10のflat configと保存時の自動修正【10.13対応】](/tech/details/3286/)
- [Prettierとは？意味・読み方と使い方・設定、ESLintとの違い【3.9対応】](/tech/details/3354/)
- [Biome v2とは？最新2.6の導入・biome.json設定とESLint/Prettier移行](/tech/details/7390/)
- [textlint（テキストリント）とは？日本語の文章校正をVS Code・CI・コミット前に回す設定手順【v15.8対応】](/tech/details/9573/)

---

出典: [Stylelintとは？v18の変更点・導入手順・設定とVS Code・CI連携【18.0対応】](<https://www.issoh.co.jp/tech/details/10686/>)（株式会社一創）
