ここ最近の CSS を取り巻く状況の変化は目覚ましいものがあり、これまでにはない速度でブラウザのサポートも進んでいます。その反面、使用できるプロパティが大幅に増えたことで、CSS プロパティ(宣言)の記述順の一貫性を保つことが難しくなりました。
そのような状況を踏まえ、この記事では、CSS を書くときのプロパティ(宣言)の記述順の再考と、Stylelint を導入して自動的に修正を適用する方法を検討していきます。
紹介する CSS プロパティの記述順はあくまでも個人の主観にとどまります。
CSS プロパティの分類
見出し「CSS プロパティの分類」膨大な CSS プロパティを 1 つずつ検討して並べていくのは現実的ではないので、まずはいくつかのグループに分けます。
いくつかの分類方法が考えられますが、CSS の仕様はモジュールごとに開発が進んでいるので、このモジュール単位で分類すれば、プロパティが増えたときにも対応しやすく合理的だと感じました。
そこで、W3C が提供する、CSS の仕様の進捗状況をまとめた CSS Snapshot 2023 の References に掲載されているモジュールをベースに考えていきます。
ここに必要なプロパティを追加した計 492 のプロパティを、仕様の各モジュールごとに以下の 43 のグループごとに並べていきます。
- Cascading and Inheritance
all - Generated Content
content、quotes - Positioned Layout
position、insetなど - Anchor Positioning
anchor-name、position-anchorなど - Containment Module
conatiner、containなど - Display
display、order、visibility - Grid Layout
grid、grid-comumnなど - Flexible Box
flex、flex-flowなど - Box Alignment Module
gap、align-content、jusitify-contentなど - Float
float、clear - Multi-column Layout
conatiner、containなど - Overflow
overlfow、text-overflowなど - Overscroll Behavior
overscroll-behaviorなど - Masking
clip、maskなど - Box Sizing
box-sizing、inline-size、block-sizeなど - Box Model
margin、paddingなど - Backgrounds and Borders (border)
border、border-radiusなど - Shapes
shape-outsideなど - Images
object-fit、image-renderingなど - Lists and Counters
list-style、counter-resetなど - Tables
table-layout、border-collapseなど - Color Adjustment
color-schemeなど - Backgrounds and Borders (background)
background、background-colorなど - Color
color、opacityなど - Compositing and Blending
mix-blend-mode、background-blend-modeなど - Fragmentation
box-decoration-breakなど - Writing Modes
writing-mode、directionなど - Fonts
font-family、font-sizeなど - Inline Layouts
line-height、vertical-alignなど - Text Module
text-align、white-spaceなど - Text Decoration
text-decoration、text-shadowなど - Ruby Annotation Layout
ruby-positionなど - Filter Effects
filterなど - SVG's Presentation
fill、strokeなど - Scroll Snap
scroll-snap-type、scroll-snap-alignなど - Scrollbars Styling
scrollbar-color、scrollbar-width - Basic User Interface
outline、resize、pointer-eventsなど - Motion Path
offset-pathなど - Viewport
zoom - Transforms
transform、translateなど - Will Change
will-change - Transitions
transitionなど - Animations
animationなど - Scroll-driven Animations
animation-range、scroll-timelineなど - View Transitions Module
view-transition-name
2024/06/20 追記 Anchor Positioning グループを追加しました。
2024/07/29 追記 Viewport グループを追加しました。
グループの順番はスタイルを適用したときの影響範囲の外側から内側へとなるように並べていますが、そこまで厳密ではなく、いくつか例外もあります。
例えば、影響範囲が全体に及ぶ可能性のある Writing Modes を関連性の強い Fonts の直前に配置していたり、UI や変形、アニメーションに関連するプロパティは最後に配置したりと、個人的な使い勝手を考慮したアレンジを加えています。
Stylelint の導入
見出し「Stylelint の導入」プロパティの順番が決まったので、スタイルに反映していきますが、当然ながらこの順番を正確に記憶するのは不可能ですし、すでに存在する CSS の記述順を手作業で変更するのも論外です。
そこで、CSS の Linter(静的解析ツール)である Stylelint と、そのプラグインである stylelint-order を使用します。
まずは、Stylelint と stylelint-order をインストールします。
npm install --save-dev stylelint stylelint-order 本サイトのフレームワークは Astro を使用しており、.astro ファイル内の <style> にも反映する必要があるため、postcss-html と stylelint-config-html をインストールします。
npm install --save-dev postcss-html stylelint-config-html 続いて、Stylelint の設定ファイル .stylelintrc.yml をルートディレクトリに作成します。この設定ファイルは JSON 形式や JS 形式にも対応していますが、コメントが使えて簡潔に記述できるため YAML 形式を選択しました。
extends: stylelint-config-html/astro
plugins:
- stylelint-order
rules:
order/properties-order:
-
# Cascading and Inheritance
- all
# Generated Content
- content
- quotes
# Positioned Layout
- position
- top
- right
- bottom
- left
# ... まず、extends で .astro ファイルにも対応するようにし、plugins には stylelint-order を指定し、rules でプロパティの並び順を指定しています。
前述した 43 のグループの並び順以外でのルールとしては以下のとおりです。
- ショートハンドプロパティを優先
-webkit-などのベンダープレフィックスは除く(stylelint-order 上で補完してくれるため)- モジュールには含まれないが関連性が強いものは含めてもよい(例:
z-indexを Positioned Layout に追加) - SVG のプレゼンテーション属性(
fillやstroke)については、必要最小限なプロパティのみを抜粋 - 使用する可能性が極めて低いプロパティは、処理の負担を抑えるためにコメントアウトで無効化
コードの全体は、以下の GitHub Gist から確認できます。
https://gist.github.com/griponminds/e5a17150ea8ce69e33d20972eafcaa79
ちなみに、この rules の order/properties-order では、groupName を付与してプロパティのグループを明示的に階層化することもできますが、コメントでも十分なのと、ループ処理の負担を低くするために使用は見送りました。
また、unspecified オプションでは含まれていないプロパティの処理を指定できますが、デフォルトから変更していないので単純に並び順のチェックから無視されます。
すべてのオプションについては、stylelint-order の GitHub リポジトリを参照してください。
これで、Stylelint が実行できるようになったので、npm-scripts に追加します。
{
// ...
"scripts": {
"lint": "stylelint \"src/**/*.{css,astro}\"",
"lint:fix": "stylelint --fix \"src/**/*.{css,astro}\""
},
// ...
} ここでは、解析のみを実行する lint と、解析結果のエラーを修正する lint:fix の 2 つのスクリプトを追加しました。試しに npm run lint を実行すると、以下のように解析結果がコンソールに表示されるようになります。

CLI の詳細については、Stylelint の公式ドキュメントを参照してください。
ここまでの設定で、CSS のプロパティの記述順を統一することができました。次のセクションでは、Stylelint を自動的に適用する方法を紹介します。
Lefthook の導入
見出し「Lefthook の導入」CSS プロパティ(宣言)の記述順のルールを徹底するために、Git フックを使用して、コミットするタイミングで Stylelint の解析と修正を適用するようにします。
Git フックマネージャとしては、husky が有名ですが、ここでは軽量で使い勝手の良さそうな Lefthook を選択しました。
まずは、Lefthook をインストールします。
npm install --save-dev lefthook 次に、Lefthook の設定ファイル lefthook.yml をルートディレクトリに用意します。
pre-commit:
commands:
stylelint:
root: 'src/'
glob: '**/*.{css,astro}'
run: npx stylelint --fix {staged_files}
stage_fixed: true ここでは、コミットのタイミングで npx stylelint --fix コマンドが、src/**/*.{css,astro} に一致するファイルで、なおかつステージングされたファイルに対して実行するように指示しています。
最後の行の stage_fixed: true によって、コマンドでステージングされたファイルが修正されたときに、その変更をコミットに含めることができます。
設定ファイルを用意したら、Git フックを設定するためのコマンドを実行します。
npx lefthook install この状態で Git にコミットすると、設定した Stylelint が実行されます。

Stylelint を Git フックに設定すべきか
見出し「Stylelint を Git フックに設定すべきか」ここまでで、Lefthook 経由で Git フックが設定され、コミットするたびに Stylelint が実行されるようになり、CSS プロパティ(宣言)の記述順の一貫性を保つことができるようになりました。
宣言ブロックの順番とは異なり、プロパティ(宣言)の順番が変わることでのスタイルへの影響のリスクは、同一のプロパティや、競合するプロパティ(margin-top と margin-block-start など)が含まれていない限り考えられません。
しかし、最近ではネスト記法や多くの at-rules が登場し、CSS の書き方が変わってきており、プロパティ(宣言)の順番を変更することによるスタイルへの影響が発生しないとも言い切れません。自動化した場合にはこの影響に気づかずにデプロイしてしまう可能性があります。
また、コミットするたびにスクリプトが実行されるので、わずかながら待ち時間が追加されてしまうのも少しだけ気になる点です。
このような懸念は残りますが、ひとまず Git フックによる自動化は有効にしたまま様子見とし、問題があるようであれば手法を見直したいと考えています。
おわりに
見出し「おわりに」この記事では、CSS の仕様のモジュールごとに CSS プロパティを分類する方法で記述順のルールを作成しました。Stylelint を使うことで、この CSS プロパティの記述順のルールの解析と修正を委ねることができました。
さらに、Git フックマネージャ(Lefthook)を導入することでコミット時に自動的に Stylelint が実行されることで一貫性を持たせることができました。
今回作成したルールについては、実際に運用しながら気になった点があれば調整していきます。