Menu

Advanced Features

These features below is not required to build a fully functioning components, but it allows you to work around some web platform limitations.

Polymorphic Elements

By default custom element will be replaced by a div with a data-template attribute. If you want to change the wrapper element to be other than div, you can use is attribute in HTML element.

<section is="hello-world"></section>

Unfortunately, the spec limits the number of elements that are allowed to be a shadow root.

For example, you can't use is attribute in a li element, even though creating a reusable list-item element makes sense.

To work around this, you can add data-element in your template definition. Note that this only applies to production build due to limitation described above. In dev, it only influences CSS property, so the Custom Elements have the same display value as data-element.

<template id="hello-world" data-element="li"> ... </template>

This is also useful if you want to always use the specified element rather than using is attribute manually.

Host Styles

If you want to style the root wrapper of your custom element, there are two methods that you can choose: scoped style or global style.

First alternative is to use scoped style that targets :host selector.

<style>
  :host {
    height: 100vh;
  }
</style>

<template id="x-element"> ... </template>

In build time all :host selectors will be replaced by [data-template="x-element"] selector.

<style>
  [data-template="x-element"] {
    height: 100vh;
  }
</style>

<div data-template="x-element">...</div>

Alternatively, you can also add the class name directly in the template tag

<template id="x-element" class="h-screen"> ... </template>

Or in the Custom Elements itself

<x-element class="h-screen"></x-element>

HTML Includes

HTML doesn't really have the concept of includes here so we're going to deviate a little bit here, similar to external templates.

In static site generation context, sometimes it's useful to have this capability. For example you want to write your documentation in markdown, and the rest in HTML. You can compile the markdown to HTML and include it in your main HTML file.

Remember the old days where we abuse script tag with an unknown type attribute to store a template? Here we're going to do the same thing.

Add a script tag with text/html type and an src attribute.

<body>
  <aside></aside>
  <main>
    <div id="content">
      <script type="text/html" src="/markdown/docs.html"></script>
    </div>
  </main>
</body>

It will replace the #content children with the content from public/markdown/docs.html.

<body>
  <aside></aside>
  <main>
    <div id="content">...</div>
  </main>
</body>

Similar to external templates, we need HTML includes files to be placed inside public directory. The main difference is HTML includes must always be referenced in the src attribute using absolute path.