クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【CSS】CSS Declaration Sorterでプロパティ順をソートする

フロントエンド開発環境の続きです。前回はAutoprefixerでベンダープレフィックスを自動で付けました。今回はもう一つCSSでやりたいテーマ、プロパティ順のソートです。CSS Declaration Sorterを使ってみます。それではいきましょう!

【目次】

前回の記事
※参考:【CSS】そうだ Autoprefixerで 自動ベンプレ付けよう(Gulpで動かす) - クモのようにコツコツと

※参考:Web開発環境まとめ
qiita.com

プロパティ順のルール

人間にとってはプロパティ順のルールは必要

CSSのレンダリングをする上ではプロパティの書き順は基本的には自由でいい。同一セレクタに同じプロパティを書かない限り干渉はない。

しかし後から修正をする際には人間にとってわかりやすい順番の方が作業はスムーズになる。例えばwidthのすぐ後はheightとかborder関係のプロパティはまとめる、とか、positionのすぐ後にtopとかがあった方がわかりやすいよね、という感じ。

mozilla.org Base Styles

自分がいつも意識して書いていた順番と近かったのはこちらの記事の「mozilla.org Base Styles」。要素の大枠の設定からだんだんコンテンツの詳細に入っていく考え方。

f:id:idr_zz:20200225054555g:plain

この図解はイメージがしやすくて、色々な記事でも引用されている。素晴らしい。

  • 要素の表示設定(display)
  • 要素をどこに配置するか(positionやfloatなど)
  • 要素のボックスモデル(width、height、margin、padding、borderなど)
  • 背景の設定(backgroundなど)
  • テキストなどコンテンツ(color、font-size、line-heightなど)
  • 動きを付けるか(CSSアニメーション)※追加

※参考:【CSS】CSSプロパティの記述順について考えてみた | unitopi - ユニトピ -

ただ、残念ながら「mozilla.org Base Styles」の大元のページは今はなくなっている。

※参考:https://www.mozilla.org/css/base/content.css

多分予想だけど、CSSのプロパティが増え続けるのでメンテしきれなくて無くなったのではなかろうか。

Google HTML/CSS Style Guide

一方、Googleの「Google HTML/CSS Style Guide」はアルファベット順を推奨しているようだ。

※参考:Google HTML/CSS Style Guide

確かにこれなら誰が書いても同じ順番になる。しかし後から見るときに直感的ではない気はしている。知っているプロパティ名なら探しやすいと思うけど。あと気になるのはベンダープレフィックスとの絡みをどうするか。

Ignore vendor-specific prefixes for sorting purposes. However, multiple vendor-specific prefixes for a certain CSS property should be kept sorted (e.g. -moz prefix comes before -webkit).

翻訳すると

ソートの目的でベンダー固有のプレフィックスを無視します。 ただし、特定のCSSプロパティのベンダー固有の複数のプレフィックスはソートされたままにする必要があります(例:-mozプレフィックスは-webkitの前にあります)。

うーん?ちょっとよくわからない。なぜ-moz-webkitの前の方がいいのかな。

プロパティ順をソートするツール

プロパティを変更(ソート)するツールを調べるといくつかあるようだ。

CSS comb

長く使われてきたのは「CSS comb」というツールで、jsonファイルでソート順を設定するようだ。

※参考:CSScombについてのおさらい - Qiita

デフォルトでも3種類のプリセットが用意されている。

csscomb
※参考:csscomb.js/csscomb.json at master · csscomb/csscomb.js · GitHub

yandex
※参考:csscomb.js/yandex.json at master · csscomb/csscomb.js · GitHub

zen
※参考:csscomb.js/zen.json at master · csscomb/csscomb.js · GitHub

またsort-order-fallback設定をabcにすることでgoogleのようなアルファベット順にもできる。

自分で独自設定のjsonファイルを作ることもできる。しかし、この設定を自分でやるのはなかなか大変な部分もありそうな気がした。

css-declaration-sorter(PostCSS)

前回のAutoprefixerのようにPostCSSが用意しているプラグインで「css-declaration-sorter」というのがあった。こちらも良さそう。

※参考:css-declaration-sorter - npm

使い方の参考になりそうな記事。

※参考:Sassから完璧なCSSファイルを出力するために通したいGulpのタスク【WordPress編】 | HPcode

※参考:PostCSSでSassをさらに便利にする | Web制作者のためのSassの教科書 改訂2版 - 公式サポートサイト

※参考:【gulp】css-declaration-sorter が効かない時【アルファベット順に並べ替えたい】|naolife.online

stylelint-config-recess-order(StyleLint)

以前の記事で扱ったCSSのlintツールStylelint。

※参考:【CSS】StyleLintで構文チェックを事始める - クモのようにコツコツと

こちらの追加モジュールで「stylelint-config-recess-order」というのがあり、これもよく使われているようだ。

※参考:GitHub - stormwarning/stylelint-config-recess-order: 🗂️ Recess-based property sort order for Stylelint.

使い方の参考になりそうなページ。

※参考:gulpでSassの並び順を整頓する「stylelint-config-recess-order」|エンジニアの日々効率化

StyleLintには他にもソート系のモジュールがあるようだ。こちらの比較記事がわかりやすい。

※参考:stylelintのorderモジュール選定 - Qiita

比較検討:css-declaration-sorterにしてみる

先程も3つを比較した結果、まずはcss-declaration-sorterを使ってみることにした。

  • CSS combのjsonファイルの手作業メンテより、大元でメンテされているものを利用してみる
  • stylelint-config-recess-orderよりcss-declaration-sorterの方がnpmやGithubで利用数が多そう

css-declaration-sorterをGulpで使ってみる

利用するにはいくつかの方法があるが、まずはGulpで使ってみる。

インストールの準備

インストール準備。Autoprefixerと同じくPostCSSのプラグインなので手順が似ていそう。

まず、Node.jsとnpmは既に入っている前提(ターミナルで下記を叩くとバージョン番号が出る)

node -v
npm -v

Autoprefixerを入れるフォルダを作る。今回は「css_sort_test」とした。

cdコマンドでcss_sort_testフォルダに移動。

cd (フォルダのパス)/css_sort_test

package.jsonの作成

npm init -y

ここまでいつもの流れ。

css-declaration-sorterのインストール

Autoprefixerと同じように、下記の3つをインストールする。

  • gulp
  • gulp-postcss
  • css-declaration-sorter

ローカルフォルダにインストール!

npm i -D gulp gulp-postcss css-declaration-sorter

package.jsonに追記される

  "devDependencies": {
    "css-declaration-sorter": "^5.1.2",
    "gulp": "^4.0.2",
    "gulp-postcss": "^8.0.0"
  }

sorttest.cssを作る

「css_sort_test」フォルダに「sorttest.css」というファイルを作る。

h1 {
    font-size: 20px;
    padding: 10px;
    color: #666;
    position: retative;
    border-radius: 5px;
    transition: all 500ms 0s ease;
    margin: 0 0 20px;
    opacity: 1;
    width: 100%;
    border-bottom: 1px solid #333;
    background: #eee;
    display: flex;
    height: auto;
    max-width: 600px;
    text-align: center;
    line-height: 1.25;
    -ms-border-radius: 5px;   
}

わざとデタラメな順番で書いてみる。ひどいねぇw
ベンダープレフィックス(-ms-)もつけてみた。あえて本体とは離れた位置に。

gulpfile.jsにcss-declaration-sorterの設定を書く

公式サイトを参考に。

※参考:css-declaration-sorter - npm

const gulp = require('gulp');
const gulpPostcss = require('gulp-postcss');
const cssDeclarationSorter = require('css-declaration-sorter');
 
gulp.task('default', () => {
  return gulp.src('sorttest.css')
    .pipe(gulpPostcss([cssDeclarationSorter({order: 'smacss'})]))
    .pipe(gulp.dest('./'));
});
  • 変数gulprequire()gulpを読み込む
  • 変数gulpPostcssrequire()gulp-postcssを読み込む
  • 変数cssDeclarationSorterrequire()css-declaration-sorterを読み込む
  • gulp.task()メソッドを実行。第一引数はdefault、第二引数は無名関数)
  • 無名関数の中、returnで処理を返す。メソッドチェーンになっている
  • メソッドチェーンの一つ目、gulp.src()メソッドでsorttest.cssをソートの対象ファイルとして指定。
  • 続いてpipe()メソッドの引数gulpPostcsscssDeclarationSorterを実行。ordersmacssを設定。
  • 次のpipe()メソッドの引数gulp.dest()で書き出す場所を指定する。今回は同じ場所に上書き。

公式サイトのgulp.task()cssだが前回と同じdefaultにしたので、gulpコマンドで実行できるはず!

SMACSSルールでソート実行

公式サイトではルールがsmacssになっていた。

   .pipe(gulpPostcss([cssDeclarationSorter({order: 'smacss'})]))

とりあえずこままでいいか。

早速実行してみる。

npx gulp

結果は…やた!実行でけた!

h1 {
    display: flex;
    position: retative;
    width: 100%;
    max-width: 600px;
    height: auto;
    margin: 0 0 20px;
    padding: 10px;
    border-bottom: 1px solid #333;
    border-radius: 5px;
    -ms-border-radius: 5px;
    background: #eee;
    color: #666;
    font-size: 20px;
    line-height: 1.25;
    text-align: center;
    opacity: 1;
    transition: all 500ms 0s ease;
}

「SMACSS」というルール、公式サイトによると

SMACSS
smacss
Order from most important, flow affecting properties, to least important properties.

  • Box
  • Border
  • Background
  • Text
  • Other

翻訳すると

smaccs
最も重要なフローに影響を与えるプロパティから、最も重要でないプロパティへの順序付け。

* ボックス
* 境界
* バックグラウンド
* テキスト
* その他

最初の「mozilla.org Base Styles」と似た考え方でわかりやすく感じた!

「SMACSS」の参考になりそうな記事

※参考:初心者による初心者向けのSMACSSまとめ - Qiita

※参考:SMACSSによるCSSの設計 - ベースとレイアウト | CodeGrid

※参考:SMACSS を使ってみた話 - CHROMA

concentric-cssルールでソート実行

ルールを変えてみる。「concentric-css」に。

   .pipe(gulpPostcss([cssDeclarationSorter({order: 'concentric-css'})]))

実行!

npx gulp

結果

h1 {
    display: flex;
    position: retative;
    opacity: 1;
    transition: all 500ms 0s ease;
    margin: 0 0 20px;
    border-bottom: 1px solid #333;
    border-radius: 5px;
    -ms-border-radius: 5px;
    background: #eee;
    padding: 10px;
    width: 100%;
    max-width: 600px;
    height: auto;
    color: #666;
    font-size: 20px;
    line-height: 1.25;
    text-align: center;
}

さっきとちょっと変わったな。 アニメーションが上の方に行ったり。

公式サイトによると。

Concentric CSS
concentric-css
Order properties applying outside the box model, moving inward to intrinsic changes.

  • Positioning
  • Visibility
  • Box model
  • Dimensions
  • Text

翻訳すると

同心円CSS
ボックスモデルの外側に適用されるプロパティを順序付け、本質的な変更に向かって移動します。

ポジショニング
可視性
ボックスモデル
寸法
テキスト

同心円CSSてw

こちらも外側から本質的な内容に向かっていくようなので、好みで決めるといいかと。

SMACSSに比べると情報は少ないが、下記は公式サイトかな?図解がある。

f:id:idr_zz:20200225072723p:plain

※参考:Concentric CSS

アルファベット順でソート実行

最後に、アルファベット順でソートしてみる。

   .pipe(gulpPostcss([cssDeclarationSorter({order: 'alphabetical'})]))

アルファべティカルてカッコ良い。

実行!

npx gulp

結果

h1 {
    background: #eee;
    border-bottom: 1px solid #333;
    border-radius: 5px;
    -ms-border-radius: 5px;
    color: #666;
    display: flex;
    font-size: 20px;
    height: auto;
    line-height: 1.25;
    margin: 0 0 20px;
    max-width: 600px;
    opacity: 1;
    padding: 10px;
    position: retative;
    text-align: center;
    transition: all 500ms 0s ease;
    width: 100%;
}

確かになった。決め打ちでプロパティを探す分には辞書や索引のようでわかりやすいんだが。。

公式サイト

Alphabetical
alphabetical
Default, order in a simple alphabetical manner from a - z.

翻訳

アルファベット順
デフォルトは、aからzまでの単純なアルファベット順です。

最後に

ということでプロパティ順のソートができました!個人的にはSMACSSルールが一番わかりやすい気がしました。どのタイプもベンダープレフィックスはちゃんと本体のすぐ下にきてくれてるのは安心しました。これでプロパティ順に悩むことが減りそうです。

PostCSSのプロパティはAutoprefixerもCSS Declaration Sorterも似たつかい方に感じました。他にも色々ありそうなので試したく思います。(メディアクエリの統合とか画像パス、サイズの変更など、いいですねー)

※参考:PostCSSでSassをさらに便利にする | Web制作者のためのSassの教科書 改訂2版 - 公式サポートサイト

それではまた!


※参考:Web開発環境まとめ
qiita.com