Question: Trying to extend an custom element :

```js
class ABC extends HTMLDivElement {
  connectedCallback() { console.log('ABC here') }
}

customElements.define("x-abc", ABC, {
  extends: 'div'
})

class XYZ extends ABC {
  connectedCallback() { console.log('XYZ here') }
}

customElements.define("x-xyz", XYZ, {
  extends: 'x-abc'
})
```

```html
<div is="x-abc"></div>
<div is="x-xyz"></div>
```

but getting this error :

```
 Uncaught DOMException: Failed to execute 'define' on 'CustomElementRegistry': "x-abc" is a valid custom element name

```

The err is confusing because it say 'is valid', not 'is not valid' !!

On the other hand FF says :

```
  Uncaught DOMException: CustomElementRegistry.define: 'x-xyz' cannot extend a custom element

```

I want to build hierarchy of custom elements.

Answer: 
The error may sound confusing at first, but actually it is very clear. The spec clearly defines that you can only extend built-ins using the `is` syntax. As it is currently designed, using `ABC` as a base class is definitely not the brightest idea (until you drop extending `HTMLDivElement` in favour of `HTMLElement`).

You have not explained why you need to extend `div` elements, which is definitely not what you typically build a component hierarchy on. It is not even (and probably never will be) supported in Safari.

Instead, extend `HTMLElement`, and omit the `is`-syntax.

```js
class ABC extends HTMLElement {
  connectedCallback() {
    console.log('ABC here')
  }
}

customElements.define('x-abc', ABC)

class XYZ extends ABC {
  connectedCallback() {
    super.connectedCallback();
    console.log('XYZ here')
  }
}

customElements.define('x-xyz', XYZ)
```

```html
<x-abc></x-abc>
<x-xyz></x-xyz>
```

If for whatever strange reason you need to keep extending `HTMLDivElement` (instead of `HTMLElement` which would be the proper way), here you go:

Just replace the `{extends: 'x-abc'}` part with `{extends: 'div'}`.

Both your components extend `div` (their defining tag name).

```js
class ABC extends HTMLDivElement {
  connectedCallback() {
    console.log('ABC here')
  }
}

customElements.define('x-abc', ABC, {
  extends: 'div'
})

class XYZ extends ABC {
  connectedCallback() {
    super.connectedCallback();
    console.log('XYZ here')
  }
}

customElements.define('x-xyz', XYZ, {
  extends: 'div'
})
```

```html
<div is="x-abc"></div>
<div is="x-xyz"></div>
```
Actually, the option-name extends:"xxx" is confusing.
As the extended built-in element must be html-marked with the tag of that built-in (accompanied with the is attribute), this option does not determine the direct ancestor ("extending" it) (this is defined by the class-constructor-chain), rather it defines the tag-name, for which the given constructor (together with the whole chain) is used when parsing html/upgrading the element. Strictly speaking, it does extend that tag's class indeed, however not directly. The meaning "extends", is more related to the html is="xxxx" syntax. Think about it as it would have some name like basetag, builtintag, markuptag, builtinbase etc.