なぜWordPressの「追加CSS」は崩れるのか?保守性を高めるCSS設計「NpCSS」の提案

WordPress(特にSWELLやCocoonなどの高機能テーマ)を使っていると、「追加CSS」は魔法のツールです。管理画面からプレビューを見ながら、サクサクとデザインを調整できる。本当に便利ですよね。
しかし、サイト運営を半年、1年と続けていくうちに、多くの人が「CSSの保守地獄」に落ちます。
- トップページの見出しを変えたら、なぜかフッターのデザインまで崩れた。
- スタイルが効かないので
!importantをつけて無理やりねじ伏せた。 - コードが長くなりすぎて、「どのコードがどこに使われているか分からないから、怖くて消せない」ゴミ屋敷状態になった。
なぜ、WordPressテーマのCSSカスタマイズは破綻しやすいのでしょうか? そして、どうすれば「1年後の自分」でもメンテナンス可能なサイトを作れるのでしょうか。
その答えが、WordPressテーマの仕様に特化したCSS設計手法 「NpCSS(エヌピーシーエスエス)」 です。
WordPressテーマのCSSカスタマイズが破綻する原因

CSSは、基本的に「グローバル(全てのページに有効)」な言語です。 あなたが「.title を赤くする」と書けば、サイト内のありとあらゆる .title が赤くなります。
これが諸悪の根源です。
- あなたがトップページのために
.titleを書く。 - 半年後、別のスタッフ(あるいはすっかり忘れてしまった未来のあなた自身)が記事ページのために
.titleを書く。 - 結果: 後から書いた方の詳細度が優先されたり、予期せぬ継承が起きたりして、過去に作ったデザインが崩れる。
これを防ぐには、「場所(place)」を特定してスコープを閉じ込め、影響範囲をコントロールする必要があります。
NpCSSの基本:場所(place)でスコープを定義する

NpCSSの「p」はplace(場所) です。 まず、WordPressのブロックエディタ(Gutenberg)側で、セクション(フルワイドブロックなど)に対して「ここが何の場所か」を示すクラス名を付けます。
命名ルール:ユニーク(一意)な住所を決める

クラス名は、以下例のようにの3つの要素をハイフンで繋げて作ります。
- プレフィックス:
p-(placeのp。場所を示す合図) - ページ名:
top(トップ)、company(会社概要)など - セクション名:
hero(メイン)、contact(お問い合わせ)など
これらを繋げて p-top-hero とします。 これをセクションの一番外側のブロック(フルワイドセクション)に付与します。
効果:コードが「文章」になり、メンテナンス性が向上する

このルールを守ると、CSSファイルの中に 「一つのセクションにつき、一つのネストの塊」 が出来上がります。
/* ■■■ トップページ:ヒーローセクション ■■■ */
/* p-top-hero という「塊」(スコープ) */
.p-top-hero {
/* この中には、トップページのヒーローセクションのスタイルしか書かれていない */
.__heroTitle { ... }
.__heroText { ... }
}
/* ■■■ 会社概要ページ:代表挨拶セクション ■■■ */
/* p-company-message という「塊」(スコープ) */
.p-company-message {
/* この中には、会社概要ページの代表挨拶セクションのスタイルしか書かれていない */
.__contactForm { ... }
}
こうすることで、1年後に追加CSSを開いたときも、「あ、ここからここまではヒーローセクションの話だな」 と、まるで文章を読むようにコードの構造を理解できるようになります。
コードの迷子になることがなくなり、修正したい場所へ一瞬でたどり着ける高いメンテナンス性を実現します。
NpCSSの基本構造:3つのルート(p・C・u)

具体的なルールの前に、NpCSSシステム全体の構造を整理しましょう。 このシステムは、CSSコードを 「3つのルート」 に分類することから始まります。
ルート1:place(場所・セクション)

- 役割:
p-top-heroのように、特定のページやセクションを定義します。 - 構造: この中に Element(要素)や Modifier(変化)をネストして、一つのセットとして完結させます。
ルート2:Component(共通部品)

- 役割:
c-Cardのように、サイト内で使い回す独立した部品です。 - 構造: placeとは独立して存在します。これ自体も内部に Element や Modifier を持ちます。
ルート3:utility(ユーティリティ)

- 役割:
u-serifのように、単一の機能(フォント変更、PCのみ表示など)を提供するヘルパークラスです。 - 構造: ネストせず、単体で使用します。
NpCSS 命名規則チートシート

【親となる3つのルート(p・C・u)】
| 分類 | プレフィックス | 役割 | 命名ルール | 例 |
|---|---|---|---|---|
| place | p- | 場所 | p-ページ名-セクション名 | p-top-hero |
| Component | c- | 再利用パーツ | c-機能名 (頭大文字) | c-Card, c-Btn |
| utility | u- | 便利ツール | u-プロパティ(頭小文字) | u-serif, u-pcOnly |
【pやCの中で使う中身(E・M)】
| 分類 | プレフィックス | 役割 | 命名ルール | 例 |
|---|---|---|---|---|
| Element | __ | 中の要素 | __ + 役割 | __heroTitle |
| Modifier | -- | 状態変化 | -- + 変化 | --active |
※キャメルケース・パスカルケースは親(place / Component)のルールに準拠
どこに、どう書くのか?

- 書く場所: WordPressの「カスタマイズ > 追加CSS」
- 書き方: 親(placeやComponent)の中に、子(Element)を入れる 「CSS Nesting(入れ子)記法」 を使います。
NpCSSの「N」は Nesting(ネスト) のNです。
/* ルート(place) */
.p-top-hero {
/* 中身(Element) */
.__heroTitle {...}
}
/* ルート(Component) */
.c-Card {
/* 中身(Element) */
.__CardTitle {...}
}
【重要】ネストしていいのは「親」だけ!

NpCSSではネストを推奨しますが、「要素(Element)の中に要素(Element)を入れること」は禁止です。HTML構造が入れ子になっていても、CSSはフラットに書いてください。
× 悪い書き方(多重ネスト)
.p-top-hero {
.__card {
/* 要素の中に要素をネストするのはダメ! */
.__cardTitle { ... }
}
}
⚪︎ 正しい書き方(フラット)
.p-top-hero {
/* すべて親の直下に並列で書く */
.__card { ... }
.__cardTitle { ... }
}
この構造がNpCSSの土台です。
しかし、これだけでは防げない事故があります。それが次章の「場所(p)と部品(C)の衝突」です。
NpCSSの真骨頂:「小文字」と「大文字」のによるカプセル化

サイト内で使い回す「カード型デザイン(c-Card)」のような部品は、色々な「場所」に置かれます。 もし、場所(place)のルールが強すぎて、中にある部品(Component)のデザインまで上書き(汚染)してしまったら?
ここで登場するのが、NpCSS最大の特徴である「キャメルケース(小文字)とパスカルケース(大文字)による識別」です。
ルールはたった2つ

- その場限りの調整(place) は、「キャメルケース(camelCase:一文字目は小文字)」 で書く。
- 大事な使い回し部品(Component) は、「パスカルケース(PascalCase:一文字目は大文字)」 で書く。
なぜこれで解決するのか?

クラス名が「物理的に異なる」ため、絶対に干渉しなくなるからです。 CSSのクラス名は、大文字と小文字を区別します(例:__card と __Card は別物)。これにより疑似的なカプセル化を実現します。
まず、ルールがない(区別がつかない)場合に起こる悲劇を見てみましょう。
【失敗例】区別がないと、うっかり壊してしまう
/* ------ 上の方に書いたコード ------ */
.p-top-service {
/* place側:「キャメルケース:一文字目が小文字」で「カードのタイトル」にクラス付与 */
/* うっかり、中にある汎用部品「カードのタイトル」に影響を与えてしまう */
.__cardTitle {
font-size: 50px;
}
}
/* ~~~ 間に何百行ものコード ~~~ */
/* ------ 本来のコンポーネントの定義 ------ */
.c-ctaCard {
/* Component側:ここもキャメルケースで定義していた場合 */
/* 上のセクション内に置いた瞬間、前述のコードが効いてしまい
50pxに爆発してデザインが壊れる */
.__cardTitle {
font-size: 24px;
}
}
これだと、place側の影響をComponentがまともに受けてしまいます。
CSS上では明確に区切られているように見えても、HTML側ではp-top-serviceの中にplaceの__cardTitleとComponentの__cardTitleが存在してしまっているからです。
そこで NpCSS の出番です。
【成功例】NpCSSなら、物理的に干渉しない
.p-top-hero {
/* placeのルール(キャメルケース)で書く */
/* もしここで、うっかり「カードのタイトル」をいじろうとしても… */
.__cardTitle {
font-size: 50px;
}
}
/* ~~~ 間に何百行ものコード ~~~ */
.c-CtaCard {
/* コンポーネントは「パスカルケース:一文字目が大文字」で定義されています。
.__CardTitle {
font-size: 24px;
}
}
/* .__cardTitle と .__CardTitle は別の名前として区別されるので、
コンポーネントのデザインは絶対に壊れません。無傷です。 */
}
- 小文字(placeの世界):
p-top-heroや__heroTitle。この名前を使う限り、パスカルケースの世界には触れられません。
- 大文字(Componentの世界):
c-Cardや__CardTitle。この名前を使う限り、キャメルケースの世界(place)からの干渉を完全にブロックできます。
グローバル汚染を防ぐ本質は「名前空間(世界)の分離」にあります。
技術仕様:BEM/FLOCSSとの違いと詳細度管理

ここまで解説してきたNpCSSは、日本で有名なCSS設計手法「FLOCSS(フロックス)」や「BEM」をベースに、WordPress向けに特化改造したものです。
FLOCSS と NpCSS の違い

FLOCSSを知っている方は、「NpCSSはFLOCSSのWordPress版(実戦型バリアント)」だと考えると分かりやすいでしょう。
| 項目 | FLOCSS (Standard) | NpCSS (WordPress Optimized) |
|---|---|---|
| 構成要素 | Foundation, Layout, Object (Project, Component, Utility) | place, Component, utility(Element, Other) |
| ネスト(入れ子) | 避ける(詳細度を低く保つため) | ネストする(WPテーマの詳細度に対抗するため) |
| 命名規則(Case) | 一般的にスネークケース等 | 大文字・小文字を厳格に使い分ける |
| 主な用途 | 一般的なWeb開発 | 「追加CSS」やエディタ上での運用 |
FLOCSSは素晴らしい設計ですが、NpCSSは以下の2点で独自の進化を遂げています。
- 詳細度の意図的な強化(Nesting):
- WordPressの「テーマのCSS」に負けないよう、あえてネストして詳細度を上げます。これが「NpCSS」の「N」の由来です。
- 物理的な名前空間(Namespace)の構築:
- Case(大文字・小文字)を使い分ける目的は、目視確認のためだけではありません。
- ツール(Linter等)が使えない環境でも、「物理的に名前が一致しない」状態を強制することで、プログラムレベルでの干渉を不可能にするためです。
!important を撲滅するメカニズム

NpCSSを導入すると、WordPressテーマカスタマイズにつきものの !important(強制適用)が基本不要になります。理由は2つあります。
- CSS Nesting による詳細度アップ NpCSSでは
.p-top-hero { .__title { ... } }のようにネスト(入れ子)して記述します。これにより、「クラス2つ分」の詳細度が自然と付与されるため、WordPress標準のスタイル(クラス1つ分)に「自然に打ち勝つ」ことができます。
- 編集画面での設定を避ける
- ブロックエディタ側で色やサイズをポチポチ設定すると、後でCSSで上書きするのにもかかわらず、優先度高くCSSプロパティが設定されたり、インラインスタイル(最強の詳細度)が書き込またりしてしまいます。
- NpCSSでは「クラス名」だけで管理するため、CSS側でコントロール権を握り続けることができます。
記載例

これがNpCSSに準拠してCSSを記載した例(抜粋)です。コメントで解説します。
/* ====== place(プレフィックス:「p-」) ========================= */
/* トップページのコミットメントセクションに付与。 */
.p-top-commitment {
/* placeなので、キャメルケース(一文字目は小文字)で記載。 */
.__secTitle {
text-transform: uppercase;
text-align: left;
}
/* 単語のつなぎ目はハイフンを使用せず、一文字目を大文字にして繋ぎます。 */
.__secCopy {
color: var(--text-stone-400);
font-size: .75em;
}
}
/* ====== Component(プレフィックス:「c-」)========================= */
/* コンポーネントはパスカルケース(一文字目大文字)で記載します */
.c-LimitedGuidance {
text-align: center;
/* エレメントも同様にパスカルケースで記載します */
.__UnlockedText {
border: 1px solid;
background-color: #f7f7f7;
}
~~~略~~~
}
/* ====== utility(プレフィックス:「u-」)================= */
.u-uppercase { /* 「クラス名 = プロパティ」という使い方ができます。 */
text-transform: uppercase;
}
結論:NpCSSシステムの全貌

最後に、NpCSSの名前の由来と、システム全体の構成を整理しましょう。
Nested place & Component CSS
(ネストされた”場所”と”部品”のCSS)
これが NpCSS(エヌピーシーエスエス) の正式名称です。
- place (.p-top-hero)
- キャメルケース(.p-top-probrem { .__cardTitle { } })で書く、その「場所」に限る調整。
- Component (c-Card)
- パスカルケース(.c-Card { .__CardTitle { } } )で書く、鉄壁の再利用パーツ。
- Nesting: これらをネストで記述し、
!importではなく詳細度でテーマCSSに自然に打ち勝つ。
名前そのものがルールを表しています。 「pは小文字、Cは大文字」。
このシンプルなルールを守るだけで、CSSの保守に関する恐怖から解放され、安心してサイト運営を続けられるようになります。
