Get to know MDN better
このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docs コミュニティーについてもっと知り、仲間になるにはこちらから。
ウェブコンポーネントの主な特徴のひとつは、カスタム要素を作成できることです。つまり、ウェブ開発者によって動作が定義され、ブラウザーで利用可能な要素セットを拡張する HTML 要素です。
この記事では、カスタム要素について紹介し、いくつかの例を説明します。
カスタム要素には 2 つの種類があります。
自律型カスタム要素 (Autonomous custom element) は HTML 要素の基底クラスである HTMLElement を継承します。 1 から動作を実装する必要があります。
カスタム組み込み要素 (Customized built-in element) は、標準 HTML 要素、例えば HTMLImageElement や HTMLParagraphElement を継承します。これらの実装により、標準要素の特定のインスタンスの動作が拡張されます。
メモ: Safari はカスタム組み込み要素に対応する計画がありません。詳しくは is 属性のリファレンスを参照してください。
どちらの種類のカスタム要素についても、作成して使用するための基本的な段階は同じです。
カスタム要素は、HTMLElement を拡張するクラス(自律型要素の場合)またはカスタマイズするインターフェイス(カスタム組み込み要素の場合)として実装されます。このクラスは自分で呼び出すのではなく、ブラウザーによって呼び出されます。クラスを定義した後、カスタム要素を登録する必要があります。これにより、 HTML マークアップで要素を記述したり、 document.createElement() を呼び出したりするなど、標準的な DOM 手法を用いてそのインスタンスを作成できるようになります。
以下は、最小限のカスタム要素で、<p> 要素をカスタマイズする実装例です。
最小限の自律型カスタム要素の実装は次のとおりです。
クラスのコンストラクターでは、初期状態や既定値の設定、イベントリスナーの登録、シャドウルートを作成することなどが可能です。この時点では、要素の属性や子要素を検査したり、新しい属性や子要素を追加したりしないでください。要件のすべてについては、Requirements for custom element constructors and reactions を参照してください。
カスタム要素が登録されると、ページのコードがカスタム要素と特定の方法でやり取りを行う際に、ブラウザーがそのクラスの特定のメソッドを呼び出します。 仕様書ではこれらのメソッドの実装を「ライフサイクルコールバック」と呼んでいますが、これらのメソッドを提供することで、これらのイベントに応答してコードを実行することができます。
カスタム要素のライフサイクルコールバックには、以下のものが含まれます。
これらのライフサイクルイベントを記録する最小限のカスタム要素は次のとおりです。
カスタム要素の DOM 内の位置は、通常の HTML 要素と同様にできるが、ライフサイクルに伴う副作用を考慮しなければなりません。
カスタム要素が移動されるたびに(Element.moveBefore() や Node.insertBefore() などのメソッドを介して)、disconnectedCallback() および connectedCallback() ライフサイクルコールバックがそれぞれの時点で発行されます。これは、要素が DOM から切断され、再接続されるためです。
これは意図通りの動作かもしれません。ただし、これらのコールバックは通常、要素のライフサイクルの始まりや終わりに実行される必要な初期化やクリーンアップコードを実装するために使用されます。そのため、要素が移動された時(除去されたり挿入されたりした時ではなく)にこれらを実行すると、その状態に問題が生じる可能性があります。例えば、要素がまだ必要としている保存データを誤って削除してしまう可能性があります。
要素の状態を維持したい場合は、要素クラス内で connectedMoveCallback() ライフサイクルコールバックを定義するのが最適であり、それから Element.moveBefore() メソッドを使用して要素を移動します(Node.insertBefore() などの類似メソッドの代わりに)。このことは、 connectedMoveCallback() を connectedCallback() および disconnectedCallback() の代わりに実行させることになります。
空の connectedMoveCallback() を追加して、他の 2 種類 のコールバックが実行されるのを停止するか、独自のロジックを記載して移動を処理することができます。
カスタム要素をページで利用できるようにするには、Window.customElements の define() メソッドを呼び出します。
define() メソッドは、以下の引数を取ります。
name要素の名前。これは小文字で始まり、ハイフンを含み、仕様書の definition of a valid name に記載されているその他の特定のルールを満たす必要があります。
constructorカスタム要素のコンストラクター関数。
optionsカスタム組み込み要素のみに含まれ、これは単一のプロパティ extends を含むオブジェクトです。これは、拡張する組み込み要素の名前を指定する文字列です。
例えば、このコードはカスタム組み込み要素である WordCount を登録します。
このコードは、PopupInfo という自律型カスタム要素を登録します。
カスタム要素を定義し登録すると、コードで使用できるようになります。
カスタム組み込み要素を使用するには、組み込み要素を使用しますが、カスタム名を is 属性の値として使用します。
自律型カスタム要素を独自に作成して使用するには、組み込みの HTML 要素と同様にカスタム名を使用します。
組み込み要素と同様に、カスタム要素も HTML 属性を使用して要素の動作を設定することができます。属性を効果的に使用するには、要素が属性値の変更に対応できなければなりません。これを実現するには、カスタム要素を実装するクラスに以下のメンバーを追加する必要があります。
attributeChangedCallback() コールバックは、要素の observedAttributes プロパティにリストされた名前の属性が追加、修正、削除、置換されるたびに呼び出されます。
コールバックには 3 つの引数が渡されます。
例えば、この自律的な要素は size 属性を監視し、値が変更された際に新旧の値を記録します。
要素の HTML 宣言に監視される属性が含まれている場合、その属性が初期化された後に、要素の宣言が最初に解釈された時点で attributeChangedCallback() が呼び出されることに 注意してください。 したがって、以下の例では、たとえ属性がその後変更されることがなかったとしても、DOM が解釈された時点で attributeChangedCallback() が呼び出されます。
attributeChangedCallback() の使用を示す完全な例については、このページのライフサイクルコールバックを参照してください。
HTML 要素に組み込まれた要素は、「ホバー」、「無効」、「読み取り専用」など、様々な状態を取ります。 これらの状態の一部は、HTML または JavaScript を使用して属性として設定できますが、内部的なものもあり、設定できないものもあります。 外部または内部に関わらず、これらの状態には通常、特定の状態にある要素を選択し、スタイルを適用するために使用できる対応する CSS 擬似クラスが存在します。
また、自律型カスタム要素(組み込み要素をベースにした要素を除く)では、擬似クラス関数 :state() を使用して状態を定義し、それに対して選択を行うこともできます。 以下のコードでは、内部状態 "collapsed" を持つ自律型カスタム要素の例を使用して、その動作を示しています。
collapsed の状態は、要素の外からは見えない論理値プロパティ(セッターとゲッターメソッド付き)として表現されます。 この状態を CSS で選択できるようにするために、カスタム要素は最初のコンストラクターで HTMLElement.attachInternals() を呼び出し、ElementInternals オブジェクトを装着します。これにより、ElementInternals.states プロパティを通じて CustomStateSet にアクセスできるようになります。 (内部で)折りたたまれた状態のセッターは、状態が true であれば CustomStateSet に識別子 hidden を追加し、状態が false であれば除去します。 識別子は単なる文字列です。この場合、hidden と呼びましたが、collapsed と読んでも同じように機能します。
カスタム要素の CustomStateSet (this._internals.states) に追加された識別子を使用して、要素のカスタム状態と照合することができます。 これは、:state() 擬似クラスに識別子を渡すと照合されます。 例えば、下記では、hidden セレクターを使用して、hidden 状態が true(したがって、要素がcollapsed 状態)であることを選択し、境界線を削除します。
:state() 擬似クラスを :host() 擬似クラス関数内で使用すると、カスタム要素のシャドウ DOM 内のカスタム状態と照合することもできます。 さらに、:state() 擬似クラスを ::part() 擬似要素の後で使用することで、特定の状態にあるカスタム要素のシャドウパーツと照合することもできます。
CustomStateSet には、これがどのように動作するのかを示すいくつかのライブサンプルがあります。
このガイドの残りの部分では、いくつかのカスタム要素の例を見ていきます。 これらの例のすべて、およびその他のソースは、web-components-examples リポジトリーで参照できます。また、すべてをライブで確認するには、https://mdn.github.io/web-components-examples/ にアクセスしてください。
まず、自律カスタム要素の例を見てみましょう。<popup-info> カスタム要素は、画像アイコンとテキスト文字列を属性として取り、アイコンにフォーカスすると、テキストをポップアップ情報ボックスに表示し、さらにコンテキスト内の情報を提供します。
最初に HTMLElement クラスを継承して PopupInfo というクラスを定義する JavaScript ファイルです。
前述のコードスニペットはクラスのコンストラクター (constructor()) の定義を含んでいます。ここでは常に super() を最初に呼び出し、正しいプロトタイプチェーンが確立されるようにします。
connectedCallback() メソッド内で、要素が DOM に接続された際にその要素が持つすべての機能を定義します。この例では、シャドウルートをカスタム要素に割り当て、DOM 操作を使用して要素の内部シャドウルート構造を作成します(そしてシャドウルートに割り当てます)。最後に、シャドウルートにいくつかの CSS を割り当ててスタイル設定します。要素の属性は DOM に接続されるまで利用できないため、コンストラクターでは処理はうまくいきません。
最後に、カスタム要素を CustomElementRegistry に登録します。前述の define() を使用して、引数で要素名とその機能を定義するクラス名を指定します。
これによって要素がページで使えるようになりました。 HTML 内で下記のように使用することができます。
上記の例では、<style> 要素を用いてシャドウ DOM にスタイルを適用しましたが、代わりに <link> 要素から外部スタイルシートを参照することが可能です。この例では、外部スタイルシートを使用するように <popup-info> カスタム要素を変更します。
こちらがクラス定義です。
これは、元の <popup-info> の例とほぼ同じですが、外部スタイルシートにリンクするために、シャドウ DOM に追加する <link> 要素を使用している点が異なります。
なお、 <link> 要素はシャドウルートの描画をブロックしないので、スタイルシートのロード中にスタイル付けされていないコンテンツ (FOUC) が一瞬表示されるかもしれないことに注意してください。
最近のブラウザーの多くは、共通のノードからクローンされた、あるいは同一のテキストを持つ <style> タグに対して、単一のバッキングスタイルシートを共有できるようにする最適化を実装しています。この最適化によって、外部スタイルでも内部スタイルでも性能は同程度になるはずです。
ここで、もう 1 つの組み込み要素の例を見てみましょう。この例は、組み込みの <ul> 要素を拡張して、リストアイテムが展開・収納するするようにします。
メモ: カスタム組み込み要素の実装に関する注意事項については、is 属性のリファレンスを参照してください。
まず始めに、これまでと同様の方法でクラス要素を定義します。
なお、今回は HTMLElement ではなく、HTMLUListElement を拡張しています。 つまり、リストの既定の動作が得られ、独自のカスタマイズのみを実装すればよいということです。
前回と同様に、コードのほとんどは connectedCallback() ライフサイクルコールバック内にあります。
次に、前回と同様に define() メソッドを使用して要素を登録しますが、今回は、カスタム要素が継承する要素の詳細を記載した options オブジェクトも含めます。
ウェブ文書内で組み込み要素を使用すると、また少し違った見え方になります。
通常のように <ul> を使用していますが、カスタム要素の名前が is 属性で指定されています。
この場合、DOM が完全に解釈された後にカスタム要素を定義するスクリプトが実行されるように保証する必要があります。connectedCallback() は展開されたリストが DOM に追加されると同時に呼び出されますが、その時点では子要素はまだ追加されていないため、querySelectorAll() の呼び出しでは何も見つかりません。これを保証する一つの方法は、スクリプトを記載する行に defer 属性を追加することです。
これまでは、connectedCallback() というライフサイクルコールバックが 1 つだけ動作しているのを見てきました。最後の例である <custom-square> では、他にもいくつか見ていきます。この例では、自律型のカスタム要素 <custom-square> を紹介します。これは、名前付きの 2 つの属性 "size" および "color" によってサイズと色が決定される四角形を描画します。
クラスのコンストラクターでは、要素にシャドウ DOM を割り当て、空の <div> および <style> 要素をシャドウルートに追加します。
この例の主要な機能は updateStyle() です。これは要素を取得し、シャドウルートを取得し、その <style> 要素を見つけて、width, height, background-color をそのスタイルに追加します。
実際の更新はすべて、メソッドとしてクラス定義内に配置されているライフサイクルコールバックによって処理されます。 connectedCallback() は、要素が DOM に追加されるたびに実行されます。ここでは、 updateStyle() 関数を実行して、正方形がその属性で定義されたスタイルになっていることを確認します。
disconnectedCallback() および adoptedCallback() コールバックは、要素が DOM から削除されるか、別のページに移動されたときに通知する単純なメッセージをコンソールに記録します。
attributeChangedCallback() コールバックは、要素の属性の 1 つが何らかの方法で変更されるたびに実行されます。その引数からわかるように、属性、属性の名前、および古い属性値と新しい属性値を個別に操作することができます。ただし、この場合は、updateStyle() 関数を再度実行して、新しい値に従って正方形のスタイルが更新されるようにします。
ある属性が変更されたときに起動する attributeChangedCallback() コールバックを取得するには、その属性を監視する必要があることに注意してください。これは、カスタム要素クラス内で static get observedAttributes() メソッドを定義することによって行われます。これは、監視したい属性の名前を含む配列を返すようにしてください。
This page was last modified on 2025年11月9日 by MDN contributors.
Your blueprint for a better internet.
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998–2026 by individual mozilla.org contributors. Content available under a Creative Commons license.