
こんにちは!静岡県浜松市でWEBデザイナーをしています小瀧です。
Webコンポーネント(Custom Elements)を使う機会が増えてきた今日この頃。
その便利さに惹かれる一方で、「CSSでスタイルを当てられない…」と悩んだこと、ありませんか?
これはシャドーDOMという“外から触れないカプセル”のせい。
でも大丈夫。
CSSには ::part と ::slotted という、“カプセル越しにスタイルを伝える窓口”が用意されているんです!
この記事では、その使い方と使い分け、実用例を丁寧に解説していきます。
シャドーDOMのスタイルの壁とは?
Webコンポーネントでは、HTML要素の中にshadowRoot(シャドーDOM)を定義することで、
外部CSSの影響を完全に遮断する独立空間が生まれます。
たとえば以下のようなカスタム要素
<my-button>Click me!</my-button>
この中のボタンをシャドーDOMに閉じ込めてしまうと、下記のような外部CSSは効きません。
button {
color: red;
}
そんなときのために導入されたのが次の2つ
- ::part:シャドーDOM内の公開したいパーツにだけCSSを渡す
- ::slotted:ユーザーが <slot> を使って挿入した外部要素にCSSを渡す
::part:コンポーネント内のパーツを公開
使い方の基本
シャドーDOM内の要素に part 属性を付けておくと、
外部からその部分だけにスタイルを当てることができます。
コンポーネントの中(JavaScript側)
<button part="base">Click me</button>
外部CSS
my-button::part(base) {
background-color: royalblue;
color: white;
}
これで、my-buttonの内部ボタンにだけCSSが届くようになります。
まるで scoped なCSSの穴をあけるようなイメージですね。
複数パーツの指定も可能
<div part="header content footer"> ... </div>
外部ではそれぞれの ::part(header) などにスタイルを当てられます。
::slotted:ユーザーが挿入した要素にスタイル
一方で、slot に差し込まれた 外部ユーザーからの要素にスタイルを適用したい場合は ::slotted を使います。
スロット例
シャドーDOM内のHTML
<slot name="text"></slot>
使用者側
<my-card> <p slot="text">差し込まれたテキスト</p> </my-card>
スタイル
::slotted(p[slot="text"]) { font-weight: bold; color: crimson; }
このように、スロットに差し込まれた要素にだけピンポイントでスタイルが届くというわけです。
::part と ::slotted の違いまとめ
| ::part | ターゲット:シャドーDOM内の要素 宣言場所:コンポーネント内で part="" を付ける 外部CSSからの指定:::part(名前) 詳細指定:可能(擬似要素、classなど併用OK) |
::slotted | ターゲット:シャドーDOMに差し込まれた外部要素 宣言場所: 外部CSSからの指定:::slotted(セレクタ) 詳細指定:セレクタは第一階層まで(直接の子のみ) |
|---|
まとめ
CSS の ::part と ::slotted は、Webコンポーネントの“密閉性”を壊さずにスタイルの柔軟性を保つためのキー技術です。
- カプセル化しながらも拡張可能なデザインができる
- コンポーネントの再利用性とテーマ対応を両立できる
- 構造の意図を保ったままCSSカスタマイズが可能になる
コンポーネント化が進む今後のWeb制作においては、必修スキルになること間違いなし!
実務でも、UIライブラリ制作でも、今から使っておいて損はありませんよ。













