1. このページの目的
カスタム要素 v1: 再利用可能なウェブ コンポーネント | Web | Google Developers に載っているコードを試してみる。
2. デモその1
<button>タグ (HTMLButtonElementクラス) を拡張する。
コード
HTML
<!-- カスタムタグではなく <button>タグを使う -->
<button is="fancy-button">Fancy button!</button>
<button is="fancy-button" disabled>Fancy button!</button>
<!-- 以下の使い方はNG -->
<fancy-button disabled>Hello!</fancy-button>
      - 実際はそれぞれのタグを <p> タグで囲んでいる。
 
JavaScript
class FancyButton extends HTMLButtonElement {
  ...
}
customElements.define('fancy-button', FancyButton, {extends: 'button'});
      define()の第三引数で元のタグ名を指定する。クラス名とタグ名は1対1対応ではないため、ここで指定しなければいけない。
実行結果
メモ
<fancy-button><fancy-button>と書いてもボタンにならない。- もともと存在している 
HTMLButtonElementのようなクラスを拡張した場合は、もとのタグを使いis属性を指定する必要があるようだ。 
3. デモその2
connectedCallback() を使って、コンテンツを上書きする。
※ 要素定義済みのコンテンツを追加するには、、Shadow DOM を使ったほうが良い。
コード
HTML
<x-foo-with-markup>
 <b>I'm an x-foo-with-markup!</b>
</x-foo-with-markup>
      JavaScript
customElements.define('x-foo-with-markup', class extends HTMLElement {
  connectedCallback() {
    this.innerHTML = "<i>I'm an x-foo-with-markup!</i>";
  }
});
      実行結果
4. デモその3
「未登録要素の事前スタイル設定(:not(:defined))」を試す。
コード
HTML
<style>
app-drawer:not(:defined),
app-div:not(:defined) {
  background-color: #c7d7ff; /* 薄い青 */
  color: orange;
}
app-drawer:defined,
app-div:defined {
  background-color: #ffc7e0; /* pink */
  color: blue;
}
</style>
<app-drawer></app-drawer>
<p>---------------</p>
<app-div>app-div</app-div>
      - Shadow DOM の外でスタイルを指定している。
 
JavaScript
window.customElements.define('app-drawer', class extends HTMLElement {
  constructor() {
    super();
    // Attach a shadow root to the element.
    let shadowRoot = this.attachShadow({mode: 'open'});
    shadowRoot.innerHTML = `
      <style>
      :host {
        color: red;
        background-color: #ffc7e0; /* pink */
      }
      /* 以下は効かない
      app-drawer {
        background-color: #ffc7e0;
      }*/
      </style>
      <span>Hi!</span>
      <p>Hello, <span>World!</span></p>
    `;
  }
});
      :hostはカスタムタグ自体を表す。
実行結果
---------------
メモ
- カスタムタグ内のスタイルは、Shadow DOM の外側の定義が優先される。
 - Shadow DOM 内のCSSのセレクタでは、カスタムタグ名は使えない。
 - 定義がないカスタムタグには、
:not(:defined)がマッチする。 
3. 結論
- 既存の要素を拡張する場合は、
define()の第三引数に注意する。