カスタム要素における template 要素内の style 要素で指定した ::slotted セレクタのスタイルが外部の全称セレクタ(*)に負ける
Q&A
Closed
解決したいこと
カスタム要素を定義して、内部でスタイルを指定しようとしています。しかし思った通りに適用されず困っています。
template
要素内で用意した slot
に差し込まれる li
要素へスタイルを当てたいです(コードは後述)。しかし、別の箇所で指定されている、いわゆる「リセットCSS」である
* { margin: 0; padding: 0; }
というスタイルに邪魔され、margin
/ padding
が設定できなくて困っています。
一般に、全称セレクタは詳細度が 0-0-0
であり、要素セレクタは 0-0-1
であると理解しているのですが、何故か全称セレクタの指定が要素セレクタの指定を打ち消してしまいます。
- なぜ全称セレクタの指定が優先されてしまうのか
- どのように解決するのが一般的な手法なのか
を知りたいです。
発生している問題・エラー
全称セレクタで指定された指定が優先されています。
- 期待している結果:
li
要素の文字が青になりmargin
が30px
取られる - 実際の結果:
li
要素の文字は赤く、margin
は0
のままである
開発者ツールでも全称セレクタの指定がより優先度の高いものとして表示されます(が、詳細度だけ見ると勝っているはずなので理由がよくわかりません。::slotted()
であることが関係している?)。
Windows 10 の Chrome, Firefox で再現しています。バージョンはあまり関係なさそうなので割愛します。
該当するソースコード
https://codepen.io/chocolamint/pen/poMbYJd で再現可能です。
<my-custom>
<li slot="items">テスト</li>
<li slot="items">テスト2</li>
</my-custom>
<template id="tm">
<ul>
<slot name="items"></slot>
</ul>
<style>
::slotted(li) {
margin: 30px;
color: blue;
/* 全称セレクタで指定のないスタイルはきちんと適用されるのでセレクタ自体は間違っていない? */
background: #F0F0FF;
}
</style>
</template>
* {
margin: 0;
padding: 0;
color: red;
}
customElements.define(
"my-custom",
class MyCustomElement extends HTMLElement {
connectedCallback() {
const template = document.querySelector("#tm").content;
const shadowRoot = this.attachShadow({ mode: "open" });
shadowRoot.appendChild(template.cloneNode(true));
}
}
);
自分で試したこと
- ::slotted() - CSS: カスケーディングスタイルシート | MDN を読んでみたがスタイルの優先順位についてはよくわからず
- ChatGPT に相談すると
li
要素にclass
属性を振ってクラスセレクタを追加する方法など提案されるが結果は変わらず