spiracss/keyframes-naming
@keyframes の配置と命名を検証します。
目的
- アニメーションの責務と配置を明確にする
- 命名衝突を避け、探索性を上げる
検証内容
@keyframesはルート直下のみ(@media/@layer内は不可)@keyframesはファイル末尾に集約- 命名は
{block}-{action}または{block}-{element}-{action} - block / element のケースは
stylelint.base.namingに従う - {block} の後ろがファイル内の element 名に一致する場合は {element} として扱い、そうでなければ suffix 全体を {action} として扱う
- action は
blockCaseのケースで 1〜3語(actionMaxWordsで変更可)
✅ 適切
.sample-block { opacity: 0;}
@keyframes sample-block-fade-in { from { opacity: 0; } to { opacity: 1; }}❌ 不適切
@media (min-width: 768px) { @keyframes sample-block-fade-in { // ❌: ルート直下以外 from { opacity: 0; } to { opacity: 1; } }}@keyframes sample-block-fade-in-out-fast { // ❌: action の語数が上限(デフォルト: 3)を超える from { opacity: 0; } to { opacity: 1; }}理由
- ルート直下・末尾に集約すると、探索と管理がしやすい
- 命名を Block / Element に紐づけることで衝突を避ける
例外 / 注意
- 共有アニメーションは
kf-などの prefix を使い、keyframes.scssに集約する - ルート Block が取得できない場合は警告して命名のみスキップされる(
blockSource/blockWarnMissingで変更可)
エラー一覧
needRoot(@keyframes はルート直下)
例:
// ❌@media (min-width: 768px) { @keyframes sample-block-fade-in { from { opacity: 0; } to { opacity: 1; } }}
// ✅@keyframes sample-block-fade-in { from { opacity: 0; } to { opacity: 1; }}理由: アニメーション定義を集約して探索しやすくする
needTail(ファイル末尾に配置)
例:
// ❌@keyframes sample-block-fade-in { from { opacity: 0; } to { opacity: 1; }}
.sample-block { opacity: 0;}
// ✅.sample-block { opacity: 0;}
@keyframes sample-block-fade-in { from { opacity: 0; } to { opacity: 1; }}理由: アニメーション定義を見つけやすくする
invalidName(命名規則違反)
例:
// ❌@keyframes fade-in { from { opacity: 0; } to { opacity: 1; }}
// ✅@keyframes sample-block-fade-in { from { opacity: 0; } to { opacity: 1; }}理由: Block / Element に紐づけて衝突を避ける
invalidSharedName(共有アニメーションの命名違反)
例:
// ❌@keyframes fade-in { from { opacity: 0; } to { opacity: 1; }}
// ✅@keyframes kf-fade-in { from { opacity: 0; } to { opacity: 1; }}理由: 共有アニメーションを明示する
sharedFileOnly(共有アニメーションの配置違反)
例:
// ❌// in card-list.scss@keyframes kf-fade-in { from { opacity: 0; } to { opacity: 1; }}
// ✅// in keyframes.scss@keyframes kf-fade-in { from { opacity: 0; } to { opacity: 1; }}理由: 共有定義の場所を固定する
missingBlock(ルート Block が判定できない)
例:
// ❌@keyframes fade-in { from { opacity: 0; } to { opacity: 1; }}
// ✅.sample-block { opacity: 0;}@keyframes sample-block-fade-in { from { opacity: 0; } to { opacity: 1; }}理由: Block 名に紐づく命名ができない
selectorParseFailed(セレクタ解析失敗)
例:
// ❌.sample-block { > : { color: #111; }}
// ✅.sample-block { > .title { color: #111; }}理由: 解析できないセレクタは検証できない