ゼファーネットのロゴ

Webコンポーネントの疑似クラスと疑似要素は思ったより簡単です

日付:

これでCSSを使用する内部について多くのことを議論しました Webコンポーネントに関する継続的なシリーズ、しかし、いくつかの特別な疑似要素と疑似クラスがあります。これらは、良い友達のように、潜在的な愛の興味に話しかける前に、恐らくは嫌な息を喜んで嗅ぎます。 あなたが知っている、彼らはあなたがそれを最も必要とするときにあなたを助けます。 そして、良い友達があなたに息をのむようなミントを渡すように、これらの疑似要素と疑似クラスは、両方からのいくつかの解決策をあなたに提供します 以内 Webコンポーネントと 外側 Webコンポーネント—Webコンポーネントが存在するWebサイト。

私は具体的に言及しています ::part & ::slotted 疑似要素、および :defined, :host, :host-context 疑似クラス。 それらは、Webコンポーネントと対話するための追加の方法を提供します。 それらを詳しく調べてみましょう。

記事シリーズ

  ::part 疑似要素

::part要するに、影の木を突き刺すことができます。これは、指輪物語のように、要素をスタイリングできると言う方法です。 内部 からのシャドウDOM 外側 シャドウDOM。 理論的には、Shadow DOMのすべてのスタイルをShadowDOM内にカプセル化する必要があります。 <style> あなたの要素 <template> 要素。

だから、このようなものを非常に与えられた このシリーズの最初の部分、あなたが持っているところ <h2> 自分で <template>、そのためのあなたのスタイル <h2> すべてが <style> 要素。

<template id="zprofiletemplate"> <style> h2 { font-size: 3em; margin: 0 0 0.25em 0; line-height: 0.8; } /* other styles */ </style> <div class="profile-wrapper"> <div class="info"> <h2> <slot name="zombie-name">Zombie Bob</slot> </h2> <!-- other zombie profile info --> </div>
</template>

ただし、ページに存在する情報に基づいて、ShadowDOMの要素のスタイルを設定する必要がある場合があります。 たとえば、不朽の愛のシステムにマッチのあるゾンビごとにページがあるとします。 プロファイルがどれだけ一致しているかに基づいて、プロファイルにクラスを追加できます。 たとえば、一致が適切な場合は、一致の名前を強調表示できます。 一致の近さは、一致する可能性のあるリストが表示されているかどうかによって異なり、そのページに移動するまでその情報がわからないため、機能をWebコンポーネントに組み込むことはできません。 以来 <h2> はシャドウDOM内にありますが、シャドウDOMの外部からアクセスしたり、スタイルを設定したりすることはできません。 zombie-profile h2 試合ページでは機能しません。

しかし、少し調整すると <template> 追加することによるマークアップ part 属性を <h2>:

<template id="zprofiletemplate"> <style> h2 { font-size: 3em; margin: 0 0 0.25em 0; line-height: 0.8; } /* other styles */ </style> <div class="profile-wrapper"> <div class="info"> <h2 part="zname"> <slot name="zombie-name">Zombie Bob</slot> </h2> <!-- other zombie profile info --> </div>
</template>

口の中のビアンカのスプレーのように、私たちは今、シャドウDOMバリアを突破し、それらの要素をスタイリングする超大国を持っています 外側 <template>:

/* External stylesheet */
.high-match::part(zname) { color: blue;
}
.medium-match::part(zname) { color: navy;
}
.low-match::part(zname) { color: slategray;
}

CSSの使用に関しては、考慮すべきことがたくさんあります。 ::part。 たとえば、パーツ内の要素のスタイリングは不要です。

/* frowny-face emoji */
.high-match::part(zname) span { ... }

ただし、追加できます part その要素に属性を付け、独自のパーツ名でスタイルを設定します。

ただし、別のWebコンポーネント内にWebコンポーネントがある場合はどうなりますか? 意思 ::part まだ動作しますか? Webコンポーネントがページのマークアップに表示されている場合、つまりスロットインしている場合は、 ::part メインページのCSSから問題なく動作します。

<zombie-profile class="high-match"> <img slot="profile-image" src="https://assets.codepen.io/1804713/leroy.png" /> <span slot="zombie-name">Leroy</span> <zombie-details slot="zdetails"> <!-- Leroy's details --> </zombie-details>
</zombie-profile>

ただし、Webコンポーネントがテンプレート/シャドウDOMにある場合は、 ::part 両方のシャドウツリーを突き刺すことはできません。最初のXNUMXつだけです。 持参する必要があります ::part 光の中に…いわば。 私たちはそれを行うことができます exportparts 属性。

これを示すために、Webコンポーネントを使用してプロファイルの後ろに「透かし」を追加します。 (なぜですか?信じられないかもしれませんが、これは私が思いついた最も不自然な例でした。)テンプレートは次のとおりです。(1)のテンプレート <zombie-watermark>、および(2)の同じテンプレート <zombie-profile> しかし、追加された <zombie-watermark> 最後の要素。

<template id="zwatermarktemplate"> <style> div { text-transform: uppercase; font-size: 2.1em; color: rgb(0 0 0 / 0.1); line-height: 0.75; letter-spacing: -5px; } span { color: rgb( 255 0 0 / 0.15); } </style> <div part="watermark"> U n d y i n g L o v e U n d y i n g L o v e U n d y i n g L o v e <span part="copyright">©2 0 2 7 U n d y i n g L o v e U n L t d .</span> <!-- Repeat this a bunch of times so we can cover the background of the profile --> </div> </template>
<template id="zprofiletemplate"> <style> ::part(watermark) { color: rgb( 0 0 255 / 0.1); } /* More styles */ </style> <!-- zombie-profile markup --> <zombie-watermark exportparts="copyright"></zombie-watermark>
</template>
<style> /* External styles */ ::part(copyright) { color: rgb( 0 100 0 / 0.125); }
</style>

Since ::part(watermark) 上のシャドウDOMはXNUMXつだけです <zombie-watermark>、それは内部から正常に動作します <zombie-profile>のテンプレートスタイル。 また、使用したので exportparts="copyright" <zombie-watermark>、著作権部分はに押し上げられました <zombie-profile>のシャドウDOMと ::part(copyright) 現在は外部スタイルでも機能しますが ::part(watermark) 外では動作しません <zombie-profile>のテンプレート。

転送して パーツの名前を変更 その属性で:

<zombie-watermark exportparts="copyright: cpyear"></zombie-watermark>
/* Within zombie-profile's shadow DOM */ /* happy-face emoji */
::part(cpyear) { ... } /* frowny-face emoji */
::part(copyright) { ... }

構造的疑似クラス(:nth-child、など)パーツでも機能しませんが、次のような疑似クラスを使用できます。 :hover。 一致度の高い名前を少しアニメートして、いくつかのlovinを探しているときに揺らしてみましょう。 さて、私はそれを聞いて、それが厄介であることに同意します。 …ええと…少し動かして、もっと目立つようにしましょう。

.high::part(name):hover { animation: highmatch 1s ease-in-out;
}

  ::slotted 疑似要素

  ::slotted CSS疑似要素が実際に登場したのは インタラクティブなWebコンポーネントについて説明しました。 基本的な考え方は ::slotted のコンテンツを表します slot Webコンポーネント、つまり、 slot その属性。 しかしここで ::part Shadow DOMを貫通して、Webコンポーネントの要素を外部のスタイルにアクセスできるようにします。 ::slotted にカプセル化されたまま <style> コンポーネントの要素 <template> 技術的にシャドウDOMの外側にある要素にアクセスします。

<zombie-profile> コンポーネント、たとえば、各プロファイル画像は、 slot="profile-image".

<zombie-profile> <img slot="profile-image" src="photo.jpg" /> <!-- rest of the content -->
</zombie-profile>

つまり、次のように、その画像(および他のスロットの画像)にアクセスできます。

::slotted(img) { width: 100%; max-width: 300px; height: auto; margin: 0 1em 0 0;
}

同様に、 スロット ::slotted(*) それがどんな要素であるかに関係なく。 ただ注意してください ::slotted 要素を選択する必要があります—テキストノードは影響を受けません ::slotted ゾンビスタイル。 また、スロット内の要素の子にはアクセスできません。

  :defined 疑似クラス

:defined 組み込みとカスタムの両方で、定義されたすべての要素に一致します(私は知っています、驚くべきことですよね?)。 カスタム要素がゾンビのようにシャッフルして、ガールフレンドのお父さんの「生きている」状況についての質問を避けている場合は、コンテンツの死体が生き返るのを待っている間、コンテンツの死体を表示したくない場合があります。

あなたが使用することができます :defined 次のように、Webコンポーネントが使用可能になる前、つまり「定義」される前に非表示にする疑似クラス。

:not(:defined) { display: none;
}

あなたは方法を見ることができます :defined コンポーネントスタイルの口の中で一種のミントとして機能し、ページの読み込み中に壊れたコンテンツが表示されないようにします(または口臭が漏れるのを防ぎます)。 要素が定義されると、それは自動的に表示されます。これは、定義されたものであり、定義されていないためです。 定義された。

追加しました setTimeout 次のデモでは、WebコンポーネントにXNUMX秒かかります。 そうすれば、あなたはそれを見ることができます <zombie-profile> 未定義の要素は表示されません。 The <h1><div> それは <zombie-profile> コンポーネントはまだそこにあります。 それはただ <zombie-profile> 取得するWebコンポーネント display: none それらはまだ定義されていないので。

  :host 疑似クラス

カスタム要素自体にスタイル変更を加えたいとしましょう。 あなたはからこれを行うことができますが 外側 カスタム要素(そのN95を締めるなど)では、結果はカプセル化されず、このカスタム要素が配置されている場所に追加のCSSを転送する必要があります。

その場合、到達できる疑似クラスがあると非常に便利です。 外側 シャドウDOMを選択し、シャドウルートを選択します。 そのCSS疑似クラスは :host.

このシリーズ全体の前の例では、 <zombie-profile> 次のように、メインページのCSSからの幅:

zombie-profile { width: calc(50% - 1em);
}

:host、しかし、私はからその幅を設定することができます 内部 次のようなWebコンポーネント:

:host { width: calc(50% - 1em);
}

実際、次のクラスのdivがありました .profile-wrapper 私の例では、シャドウルートをラッパーとして使用できるため、削除できます。 :host。 これは、マークアップをスリム化するための優れた方法です。

あなたはから子孫セレクターを行うことができます :host、ただし、アクセスできるのはシャドウDOM内の子孫のみです。Webコンポーネントにスロットされているものは何もありません(使用せずに) ::slotted).

:host疑似要素に関連するHTMLの部分を表示します。

いえ、 :host ワントリックゾンビではありません。 また、クラスセレクタなどのパラメータを受け取ることもでき、クラスが存在する場合にのみスタイルを適用します。

:host(.high) { border: 2px solid blue;
}

これにより、特定のクラスがカスタム要素に追加された場合に変更を加えることができます。

そこに疑似クラスを渡すこともできます。 :host(:last-child) & :host(:hover).

  :host-context 疑似クラス

それでは話しましょう :host-context。 それは私たちの友人のようなものです :host()、しかしステロイドについて。 その間 :host シャドウルートを取得します。カスタム要素が存在するコンテキストや、その親要素と祖先要素については何も教えてくれません。

:host-context一方、風に抑制を投げかけることで、レオタードを着たレプラコーンまで、虹の上のDOMツリーをたどることができます。 私がこれを書いている時点で、 :host-context FirefoxまたはSafariではサポートされていません。 したがって、プログレッシブエンハンスメントに使用します。

仕組みは次のとおりです。 ゾンビプロファイルのリストをXNUMXつのdivに分割します。 最初のdivには、ハイゾンビの試合がすべて含まれます。 .bestmatch クラス。 XNUMX番目のdivは、すべての中低の愛の試合を保持します .worstmatch とに提供されます。

<div class="profiles bestmatch"> <zombie-profile class="high"> <!-- etc. --> </zombie-profile> <!-- more profiles -->
</div> <div class="profiles worstmatch"> <zombie-profile class="medium"> <!-- etc. --> </zombie-profile> <zombie-profile class="low"> <!-- etc. --> </zombie-profile> <!-- more profiles -->
</div>

異なる背景色をに適用したいとします .bestmatch & .worstmatch クラス。 ただでこれを行うことはできません :host:

:host(.bestmatch) { background-color: #eef;
}
:host(.worstmatch) { background-color: #ddd;
}

これは、ベストマッチクラスとワーストマッチクラスがカスタム要素にないためです。 必要なのは、ShadowDOM内からプロファイルの親要素を選択できるようにすることです。 :host-context カスタム要素を超えて突く match スタイリングしたいクラスに一致します。

:host-context(.bestmatch) { background-color: #eef;
}
:host-context(.worstmatch) { background-color: #ddd;
}

さて、口臭にもかかわらずぶらぶらしてくれてありがとう。 (私はあなたが言うことができなかったことを知っています、しかし私が話していたとき上記 息、こっそり話していた my 呼吸。)

どう使う? ::part, ::slotted, :defined, :host, :host-context あなたのウェブコンポーネントで? コメントで教えてください。 (または、慢性口臭の治療法がある場合、私の妻は 非常に もっと聞きたいです。)

スポット画像

最新のインテリジェンス

スポット画像