設計思想
「CSS アーキテクチャを覚えて守る」から「崩れにくさをデザインする」へ。
SpiraCSS は 「親が子のレイアウトを決め、子は内部だけを書く」 という原則に基づき、構造判断を Stylelint で検証可能にします。
CSS 設計が抱える構造的な課題
CSS は見た目を再現するだけなら設計は不要です。しかしプロフェッショナルの現場では保守・運用を見据えたコードの品質管理が求められます。
個人開発であれば独自のやり方でも成立しますが、実際のプロジェクトではスキルレベルの異なるメンバーが混在し、外部の開発者が途中から参加することも珍しくありません。そうした環境で、規約を全員が同じ水準で守り続けることは容易ではありません。
数多くの設計手法が「CSS をどう構造化し、保守可能にするか」という課題に取り組んできました。しかし、その多くは規約ベースのアプローチであり、共通する構造的な課題を抱えています:
「ガイドラインを覚え、人が判断し、守り続ける」という運用モデルそのものが安定しない
たとえば、次のような判断が常に求められます:
- どこまでを 1 つのコンポーネントとするか?
- この要素は親の一部か、独立したコンポーネントか?
- 親と子のレイアウト責務をどちらが持つか?
- どんな命名規則に従うべきか?
ガイドラインはあっても、覚える負担があり、判断は実装者の経験や感覚に依存し、守り続けられるかはチームの運用力次第です。その結果:
- プロジェクトごとに分割の粒度や命名がバラつく
- チームが大きくなるほど、規約の浸透が追いつかず一貫性が崩れる
- コードレビューでコンポーネント境界の議論に時間を費やす
- AI に指示しても一貫性が保てないことがある
また RSCSS は One component per file を明記しており、BEM も ブロック実装を技術ごとの別ファイルに分ける方針です。しかしファイル分割に伴う行き来の煩雑さを補う運用支援が十分でなく、命名規則だけが取り入れられ実務では定着しにくい状態が続いていました。
SpiraCSS のアプローチ
従来の CSS 設計手法はすべて「より良い規約」の改善でした。SpiraCSS は問題の捉え方を変えます——規約を改善するのではなく、崩れにくさそのものをデザインする。人間でも判断がブレるルールは、AI に指示しても安定しません。そこで機械的に検証できるルールだけを採用し、Stylelint で検証することで、人間も AI も、ジュニアでもシニアでも、同じ基準で設計を保てる仕組みを作ります。
チームがスケールしても規約の浸透に依存せず、一定の設計品質が保たれます。
構造判断を「不変条件」に落とし込む
クラス名で構造を表現し、Block 単位でファイルを分割した上で、構造判断を「解釈」ではなく「不変条件」に落とし込みます。Block ごとにファイルを分け、各 Block が自分の責務だけを持ち、子は内部を自己完結させ、親が子に対して行うのはレイアウトのみです。この考え方は、プログラミングにおけるオブジェクト指向(責務の分離やカプセル化)に通じるものがあるかもしれません。
コンポーネント境界の曖昧さを解消する
規約ベースの CSS 設計ではコンポーネントの境界判断に人の解釈が入り、その判断次第で命名や配置も変わります。SpiraCSS は「Block > 子(Block または Element)」の繰り返しだけで構造を表現し、Stylelint でその構造を強制するため破綻しません。
クラス名の衝突を物理的に防ぐ
コンポーネントごとに SCSS フォルダを作り、1 Block = 1 ファイル、かつファイル名 = Block 名というルールを適用します。同じフォルダ内に同名のファイルは作れないため、同一コンポーネントフォルダ内では Block 名の衝突は物理的にありえません。ルールで禁止するのではなく、構造として不可能にしています。
Modifier を Variant と State に分離する
従来の BEM Modifier は「見た目のバリエーション」と「インタラクション状態」を同じ仕組みで扱っていたため、両者の区別が曖昧でした。SpiraCSS では静的な差分(Variant)と動的な状態(State)を分離し、デフォルトでは data-variant / data-state 属性で明示します。HTML レベルで両者の区別が明確になり、SCSS 内の書く場所も Stylelint が検証するため、コード全体で統一されます。
レイアウトとプロパティの責務を明確にする
CSS のレイアウトは本質的に「親が子を並べる」仕組みです(親に display: flex、子に align-self)。子の margin も親のレイアウトに影響するため、子自身ではなく親から指定します。この性質に基づき、SpiraCSS はどのプロパティを誰が持つべきか明確に規定します。
ファイル内の構造も明確にする
従来の CSS 設計手法は「どのファイルに何を書くか」は規定しても、「1 つのファイル内でどう構成するか」は言及していませんでした。SpiraCSS では —interaction・—shared などのセクション構成を規定し、ファイル内の構造も明確にしています。
新しい CSS 機能に依存しない
SpiraCSS は @scope や @layer がなくても成立します。SCSS のネスト・ファイル分割・Stylelint の検証だけで構造化するため、新しい CSS 機能を学ぶ必要がありません。チームに様々なスキルレベルのメンバーがいても、馴染みのある SCSS だけで運用できます。
エラーメッセージで自律修正させる
AI に複雑なルールを指示書で理解させるのは非現実的です。TypeScript の型エラーのように「何が間違っているか」「どう直すべきか」をエラーメッセージに含めれば、AI は自律的に修正できます。人間も同じメッセージで学べるため、新人教育にも有効です。
ツールで作業を効率化する
1 Block = 1 ファイルの運用では関連ファイルへの移動が頻繁になります。@rel コメントでリンクを張り、VS Code 拡張(SpiraCSS Comment Links)でクリック遷移することで親子 Block 間を高速に行き来します。
HTML から SCSS を生成する VS Code 拡張(HTML to SCSS) / CLI も用意しています。CLI は AI エージェントや自動化スクリプトからも利用でき、人間は VS Code、AI は CLI という形で同じ生成ロジックを共有します。
SPIRA の意味
SpiraCSS = Simplified Practical Integrated Relational Architecture
| 原則 | 意味 |
|---|---|
| Simplified | 「親が子のレイアウトを決め、子は内部だけを書く」を原則 |
| Practical | 実務で曖昧になりがちなプロパティの責務やセクション構成を規定 |
| Integrated | HTML 構造・SCSS・ツールが同じルールで連動、Stylelint で検証 |
| Relational | @rel コメントでファイル間の依存関係を明示 |
| Architecture | CSS レイヤー 3 層と 1 Block = 1 ファイルで全体を設計 |