π₯§ TL;DR;
-
UnknownHTMLElement
elements can be used as Web Component building blocks - The
<pie-chart>
and<progress-circle>
Web Components, used in this post are available on https://pie-meister.github.io
<slice>
is an UnknownHTMLElement
In my previous post
I explained how to build a vanilla JavaScript <pie-chart>
Web Component.
With semantic HTML creating a Pie Chart:
<pie-chart>
<slice size="90" stroke="green">HTML</slice>
<slice size="1" stroke="red">JavaScript</slice>
<slice size="9" stroke="blue">CSS</slice>
</pie-chart>
Experienced Web Developers commented <slice>
is not a valid HTML Element.
document.querySelector("slice").constructor.name === "HTMLUnknownElement"
Neither is it a valid Custom Element, because those always require at least one hyphen in the tagname.
That hyphen restriction is to prevent conflicts with any HTML tags the WHATWG might add in the future.
Custom Element tag names:
- have to start with a lowercase ASCII character
- can't have uppercase characters anywhere
- must contain at least one hyphen - character
- UTF-8 characters, emojis are allowed:
<a-π₯§-chart>
- cannot be self closing:
<pie-chart/>
What is the value of using <slice>
?
<pie-chart>
must be a unique Custom Element (extended from HTMLElement)
Scoped registries have been on the agenda for 4 years now.
For now all Custom Elements go into the same global customElementsRegistryThat means
customElements.define("pie-chart")
can only be called once.If an element with the same tag name was already created,
my<pie-chart>
element will throw an error:
- For a good UX (User eXperience) and DX (Developer eXperience)
my
<pie-chart>
Web Component should test if it can be defined:
if (customElements.get("pie-chart")) {
// warn the user "my" Web Component doesn't work; another definition exists
// warn the developer another Web Component with the same name exists
} else {
customElements.define("pie-chart", ... )
}
To <slice>
or to <pie-slice>
, that is the question
<slice>
has less restrictions
A duplicate
<slice>
can only be created by the WHATWG adding<slice>
as standard HTML tag.Till then. I know with 100% certainty there will not be a naming conflict.
Because no 3rd party Developer can create a valid
<slice>
element:
Had I used a
<pie-slice>
Custom Element,
it would have been an additional point of failure.
I would have to add extra code to check if<pie-slice>
was defined by another developer; like required for<pie-chart>
<pie-slice>
versus <slice>
<pie-slice>
can have all the Web Components goodies:observedAttributes
,attributeChangedCallback
etc.<slice>
will always be an UnknownHTMLElement.
observedAttributes
-like behaviour can only be created by adding a MutationObserver (yes, works on Unknown Elements)
You then get an extra bonus; because a MutationObserver can observe text Node changes.
A Custom Element can not monitor theinnerHTML
label.
(ab)using existing HTML tags
We can test the "WHATWG created a new HTML tag" scenario.
<progress>
is an existing HTML tag
And for those who don't know.
Many standard HTML elements,<input>
,<video>
, are Web Components
Browsers have different implementations;
check out the<progress>
documentation page in Chrome, Firefox or Safari
Similar to <pie-chart>
(and using the same Base Class, available on https://pie-meister.github.io)
This chart (modelled after a Google Analytics chart):
is created by the <progress-circle>
Web Component, from semantic HTML:
<progress-circle>
<progress value="75%" stroke="green">SEO</progress>
<progress value="60%" stroke="orange">Social</progress>
<progress value="65%" stroke="teal" edge="black">Maps</progress>
<progress value="50%" stroke="orangered">Traffic</progress>
</progress-circle>
This Web Component uses shadowDOM to display the chart, the semantic HTML remains invisible in lightDOM
Thus you do not see the
<progress>
default behaviourIf you really, really want a "NO JavaScript!" version, you have to change the HTML, CSS (and Web Component code) a bit to work with something like this:
<progress max="100" value="75" stroke="green" label="SEO"></progress>
<progress max="100" value="60" stroke="orange" label="Social"></progress>
<progress max="100" value="65" stroke="teal" label="Maps"></progress>
<progress max="100" value="50" stroke="orangered" label="Traffic">Traffic</progress>
again, the
<progress>
elements remains invisible in lightDOMthe resulting chart is displayed in shadowDOM
I only have to safeguard a duplicate naming conflict for the
<progress-circle>
Web Component.As long as you can keep the output in invisible lightDOM,
you can (ab)use any existing HTML tag for other purposes.
Pie-Meister.github.io
The <pie-chart>
and <progress-circle>
Web Components are available, as unlicensed source code, on https://pie-meister.github.io
The code is an enhanced version of my previous <pie-chart>
post
instead of a SVG
<circle>
Element, a<path>
Element is used to draw slices. The<progress-circle>
can not be created with<circle>
elements.Uses shadowDOM
uses ::part shadowParts for optional global styling
all in vanilla JavaScript, (way) under 2 kB GZipped
a starting point for you own Web Components
Top comments (0)