【PR】を含みます。

フロントエンド

StylelintでCSSプロパティの順番を統一する方法

StylelintでCSSプロパティの順番を統一する方法

CSSのプロパティ順序は、チームや案件ごとにルールが分かれやすいポイントです。

自分で意識して並び順をそろえることもできますが、毎回手作業で合わせるのは大変です。

結論からいうと、CSSプロパティの順番は Stylelint と stylelint-order を使って管理するのがおすすめです。

これにより、プロパティ順序のルールを設定ファイルとして残せるだけでなく、違反の検出や自動修正もしやすくなります。

この記事では、StylelintでCSSプロパティ順序を管理する考え方、stylelint-orderの導入方法、設定例、VS Codeでの使い方までわかりやすく解説します。

そもそもCSSプロパティをどのような順番で並べるか迷っている場合は、先に以下の記事を読むと整理しやすいです。

あわせて読む
CSS プロパティの記述順序の決め方|おすすめの並び順を解説

【CSS】プロパティの記述順序の決め方|おすすめの並び順を解説

CSSを書いていて、「なんとなく書いたけど、あとから見返したら読みにくい…」と感じたことはありませんか? CSSは自由度が高いぶん、同じ見た目でも書き方が人によって変わりやすく、プロパティの並び方がバ ...

CSSプロパティの順番をStylelintで管理するメリット

CSSプロパティの順番は、絶対的な正解があるわけではありません。

ただし、案件やチームの中で並び順がばらつくと、コードレビューや保守のたびに読みづらさが出やすくなります。

CSSプロパティの順番をStylelintで管理すると、次のようなメリットがあります。

  • 並び順のルールをファイルとして残せる
  • 人による書き方のぶれを減らせる
  • レビュー時に順序の指摘を減らしやすい
  • 自動修正まで設定しておけば、手作業を減らしやすい

「ルールを決める」だけでなく、自動修正までできる状態にしておくと、運用がかなり安定しやすくなります。

PrettierではなくStylelintで管理する理由

コード整形というとPrettierを使う場面も多いですが、CSSプロパティの順番管理はStylelint系の方が向いています。

Prettierは主に改行やインデント、クォートなどの見た目を整える役割が中心です。

一方でStylelintは、CSSのルール違反やコーディング規約をチェックするLinterなので、プロパティ順序のような「チーム独自ルール」と相性が良いです。

見た目の整形はPrettier、プロパティ順序のようなコーディング規約の管理はStylelint、というように役割を分けて考えると整理しやすいです。

コードの見た目を整える自動整形については、以下の記事でまとめています。

あわせて読む
VS Code 拡張機能で自動整形する方法|保存時フォーマットの設定も解説

【VS Code】拡張機能で自動整形する方法|保存時フォーマットの設定も解説

VS Codeでコードを書いていると、インデントや改行位置がばらついて見づらくなることがあります。 特にフリーランスや複数案件を行き来する働き方だと、現場が変わるたびにVS Codeの設定を見直す場面 ...

Stylelintとstylelint-orderとは?

Stylelintは、CSSのエラー検出やコーディング規約の統一に使えるLinterです。

stylelint-orderは、その中でも順序に関するルールを追加するためのプラグインです。

ツール役割
StylelintCSS全体のLintを行う本体
stylelint-orderプロパティ順序などの order 系ルールを追加するプラグイン

CSSプロパティの順序を管理したい場合は、Stylelint本体だけでなく、stylelint-orderもあわせて導入する必要があります。

Stylelintを導入する手順

まずは、Stylelintを使いたいプロジェクトのフォルダで、Stylelint本体とプロパティ順序を管理するための stylelint-order をインストールします。

Copyをクリックするとコピーできます。

Command
Copy
  1. npm install -D stylelint stylelint-config-standard stylelint-order

-Dは開発用のパッケージとしてインストールするための指定です。

Stylelintは開発中に使うツールなので、この形で問題ありません。

続いて、package.json があるフォルダに stylelint.config.mjs を作成します。

export defaultを使う場合は、拡張子を.mjsにしておくとモジュール形式が明確になり、環境差分で詰まりにくくなります。

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

まずは最小構成で試すのがおすすめ

最初から細かいグループ分けを作り込まなくても、まずはStylelint本体とstylelint-orderを導入し、基本的な順序ルールだけ試す形でも十分です。

この段階では、まずStylelintが正しく動くことを確認するのがおすすめです。

最小構成で動作確認してから、案件やチームのルールに合わせてグループ分けを調整していくと、導入時につまずきにくくなります。

CSSプロパティ順序の設定例

StylelintでCSSプロパティの順番を管理するには、stylelint.config.mjsrules に設定を追加します。

すでに stylelint.config.mjs を作成している場合は、そのファイルに追記してください。

今回は、CSSプロパティをグループごとに並べる例として、次のような設定を紹介します。

以下の設定では、指定したプロパティはグループごとの順番で並び、設定に含まれていないプロパティは末尾にアルファベット順で並びます。

そのため、最初からすべてのCSSプロパティを定義しなくても運用を始めやすいです。

/** @type {import('stylelint').Config} */
export default {
  extends: ['stylelint-config-standard'],
  plugins: ['stylelint-order'],
  rules: {
    'media-feature-range-notation': 'prefix',
    'order/properties-order': [
      [
        {
          groupName: 'レイアウト・表示モード',
          emptyLineBefore: 'never',
          properties: [
            'display',
            'visibility',
            'position',
            'z-index',
            'inset',
            'top',
            'right',
            'bottom',
            'left',
            'float',
            'clear'
          ]
        },
        {
          groupName: 'Flex / Grid',
          emptyLineBefore: 'never',
          properties: [
            'flex',
            'flex-grow',
            'flex-shrink',
            'flex-basis',
            'flex-flow',
            'flex-direction',
            'flex-wrap',
            'justify-content',
            'align-items',
            'align-content',
            'align-self',
            'justify-self',
            'order',
            'grid',
            'grid-template',
            'grid-template-areas',
            'grid-template-columns',
            'grid-template-rows',
            'grid-auto-flow',
            'grid-auto-columns',
            'grid-auto-rows',
            'grid-area',
            'place-items',
            'place-content',
            'gap',
            'row-gap',
            'column-gap'
          ]
        },
        {
          groupName: 'ボックスサイズ',
          emptyLineBefore: 'never',
          properties: [
            'box-sizing',
            'aspect-ratio',
            'width',
            'min-width',
            'max-width',
            'height',
            'min-height',
            'max-height',
            'inline-size',
            'block-size'
          ]
        },
        {
          groupName: '余白',
          emptyLineBefore: 'never',
          properties: [
            'margin',
            'margin-top',
            'margin-right',
            'margin-bottom',
            'margin-left',
            'margin-block',
            'margin-inline',
            'padding',
            'padding-top',
            'padding-right',
            'padding-bottom',
            'padding-left',
            'padding-block',
            'padding-inline'
          ]
        },
        {
          groupName: 'スクロール・オーバーフロー',
          emptyLineBefore: 'never',
          properties: [
            'overflow',
            'overflow-x',
            'overflow-y',
            'overflow-anchor',
            'clip',
            'resize'
          ]
        },
        {
          groupName: 'リスト・テーブル・置換要素',
          emptyLineBefore: 'never',
          properties: [
            'list-style',
            'table-layout',
            'border-collapse',
            'object-fit',
            'object-position',
            'vertical-align'
          ]
        },
        {
          groupName: '文字',
          emptyLineBefore: 'never',
          properties: [
            'font',
            'font-family',
            'font-size',
            'font-weight',
            'font-style',
            'font-variant',
            'font-feature-settings',
            'line-height',
            'letter-spacing',
            'text-align',
            'text-indent',
            'text-decoration',
            'text-decoration-color',
            'text-decoration-thickness',
            'text-underline-offset',
            'white-space',
            'text-overflow',
            'word-break',
            'overflow-wrap',
            'color'
          ]
        },
        {
          groupName: '背景・境界線・装飾',
          emptyLineBefore: 'never',
          properties: [
            'background',
            'background-color',
            'background-image',
            'background-position',
            'background-size',
            'background-repeat',
            'border',
            'border-top',
            'border-right',
            'border-bottom',
            'border-left',
            'border-width',
            'border-style',
            'border-color',
            'border-top-width',
            'border-right-width',
            'border-bottom-width',
            'border-left-width',
            'border-top-style',
            'border-right-style',
            'border-bottom-style',
            'border-left-style',
            'border-top-color',
            'border-right-color',
            'border-bottom-color',
            'border-left-color',
            'border-radius',
            'outline',
            'opacity',
            'box-shadow',
            'filter'
          ]
        },
        {
          groupName: 'アニメーション・変化',
          emptyLineBefore: 'never',
          properties: [
            'cursor',
            'pointer-events',
            'user-select',
            'transform',
            'transform-box',
            'transform-style',
            'backface-visibility',
            'transition',
            'animation'
          ]
        },
        {
          groupName: '擬似要素・補助的なプロパティ',
          emptyLineBefore: 'never',
          properties: [
            'content'
          ]
        }
      ],
      {
        unspecified: 'bottomAlphabetical',
        emptyLineBeforeUnspecified: 'always'
      }
    ]
  }
};

contentプロパティの扱いについて

contentは、::before::afterなどの擬似要素で使う特殊なプロパティです。

そのため、backgroundborderなどと同じ「装飾」グループに入れても大きな問題はありませんが、気になる場合は最後の補助的なグループに分けて管理しても構いません。

実務では、ルールの厳密さよりも「チーム内で違和感なく統一できるか」の方が大切なので、運用しやすい場所に置くのがおすすめです。

Lintを実行する方法

Stylelintを実行しやすくするために、まずはpackage.jsonscriptsにコマンドを追加します。

以下の設定は、package.jsonscriptsに追加してください。

lint:cssはチェックのみを行うコマンドで、lint:css:fixはチェックに加えて自動修正も行うコマンドです。

自動修正とは、Stylelintが修正可能なルール違反を自動で書き換えることです。

たとえば、プロパティの順番の並び替えや、書式の一部調整などが該当します。

ただし、すべての問題を自動で直せるわけではなく、ルールによっては検出のみで終わるものもあります。

Copyをクリックするとコピーできます。

package.json
Copy
  1. {
  2.   "scripts": {
  3.     "lint:css": "stylelint \"**/*.css\"",
  4.     "lint:css:fix": "stylelint \"**/*.css\" --fix"
  5.   }
  6. }

package.jsonがあるフォルダで作業している場合は、追加したコマンドをnpm runで呼び出せるようになります。

npm runは、package.jsonscriptsに登録したコマンドを実行する方法です。

設定後は、ターミナルで次のコマンドを実行するとLintを実行できます。

Copyをクリックするとコピーできます。

Command
Copy
  1. npm run lint:css

自動修正まで行いたい場合は、次のコマンドを使います。

Copyをクリックするとコピーできます。

Command
Copy
  1. npm run lint:css:fix

なお、package.jsonscriptsを追加しない場合でも、npxで直接実行することは可能です。

npxは、Stylelintのコマンドを直接指定して実行する方法です。

まずは試したいときや、scriptsをまだ用意していないときに向いています。

Copyをクリックするとコピーできます。

Command
Copy
  1. npx stylelint "**/*.css"

自動修正したい場合は、次のように--fixを付けます。

Copyをクリックするとコピーできます。

Command
Copy
  1. npx stylelint "**/*.css" --fix

VS Codeで保存時にStylelintを動かす方法

VS Codeで保存時にStylelintを動かすには、拡張機能「Stylelint」(stylelint.vscode-stylelint)を入れておく必要があります。

Stylelint

保存時に自動修正したい場合は、VS Code側のsettings.jsonに以下コードアクションを設定します。

{
  "editor.codeActionsOnSave": {
    "source.fixAll.stylelint": "explicit"
  }
}

CSSでエラー表示が重複する場合は、VS Code標準のCSS検証をオフにする方法もあります。

{
  "css.validate": false
}

settings.jsonの開き方がわからない場合は、以下の記事を先に確認しておくとスムーズです。

あわせて読む

【VS Code】settings.json の開き方|ユーザー設定とワークスペース設定の違いも解説

VS Codeの設定を調整しようとしたとき、「settings.jsonはどこから開けばいいの?」と迷うことがあります。 自動整形やPrettierの設定を追加したいときも、設定画面ではなくJSONを ...

導入時の考え方と注意点

プロパティ順序のルールは、必ずしもゼロから自作する必要はありません。

チームや案件によっては、既存の共有設定をベースにして運用した方が導入しやすいこともあります。

まずは既存ルールをベースに運用を始め、必要に応じて独自ルールへ寄せていく流れでも問題ありません。

また、すでにCSSファイルが多い案件に対して、いきなり --fix を広範囲にかけると、差分が大きくなってレビューしづらくなることがあります。

そのため、最初は新規ファイルだけに適用したり、対象ディレクトリを絞って段階的に導入したりする方が実務では安全です。

特に複数人で保守している案件では、導入タイミングや適用範囲をあらかじめ決めておくと混乱を減らしやすくなります。

SCSSまで管理したい場合

SCSSまで対象にしたい場合は、CSS向けの基本設定だけでは足りないことがあります。

その場合は、SCSS向けの共有設定や構文対応もあわせて検討すると整理しやすいです。

たとえば、stylelint-config-standard-scsspostcss-scssなどが必要になることがあります。

まずはCSSだけで運用を始めて、必要に応じて対象を広げていくのがおすすめです。

Stylelint導入時によくあるトラブル

Stylelint本体だけ入れていて順序チェックが動かない

プロパティ順序の管理にはstylelint-orderが必要です。

Stylelint本体だけでは、独自のプロパティ順序ルールまでは設定できません。

VS Codeで自動修正が動かない

CLIの--fixでは直るのに、VS Code保存時では直らないことがあります。

その場合は、Stylelint拡張機能の設定やeditor.codeActionsOnSaveの内容を確認してみてください。

設定ファイルの形式と書き方が合っていない

stylelint.config.jsexport defaultを書く場合は、Node.js側のモジュール設定の影響を受けることがあります。

export defaultを使うなら、stylelint.config.mjsにしておくのがおすすめです。

まとめ

CSSプロパティの順番を統一したいなら、Stylelintとstylelint-orderを使ってLintで管理するのがおすすめです。

  • プロパティ順序は手作業ではなくLintで統一した方が運用しやすい
  • StylelintはCSSの規約チェック、stylelint-orderは順序ルール追加に向いている
  • order/properties-orderを使えば独自の順番を設定できる
  • npm run lint:css:fixnpx stylelint "**/*.css" --fixで自動修正も行いやすい
  • VS Code拡張と組み合わせると日常運用しやすい

プロパティ順序に正解はありませんが、ルールを決めたなら、Lintで仕組み化しておくとかなり楽になります。

この記事を書いた人
もみじのアイコン画像

もみじ

現役フリーランスWebエンジニア。フロントエンド開発を中心に、Web制作、WordPress、業務効率化ツール開発、PHPを用いた機能改修に携わってきました。社内SEとして業務ツール開発や運用保守を担当した経験もあります。

実務や学習を通じて得た知見をもとに、初心者がつまずきやすいポイントや、現場で役立つ考え方をわかりやすく発信しています。

詳しいプロフィールはこちら

-フロントエンド
-,