Posted over 2 years ago. Visible to the public. Repeats.

Defining new elements for your HTML document

Browsers come with a set of built-in elements like <p> or <input>. When we need a new component not covered by that, we often build it from <div> and <span> tags. An alternative is to introduce a new element, like <my-element>.

When a browser encounters an unknown element like <my-element>, the browser will proceed to render <my-element>'s children. The visual rendering of your page will not be affected.

If you care about their HTML being valid, your new element should contain a dash character (-) to mark it as a custom element. Custom elements will be ignored for the purposes HTML validation, but their children will still be validated.

Styling new elements

Browsers will give unknown elements a default style of display: inline. This way the element will not affect the layout flow Archive .

You may style new elements with CSS:

my-element { display: block; font-weight: bold; }

If you have been in web development for a long time, you might remember browsers not applying styles to unknown elements. This was fixed in Internet Explorer 9, and hasn't been an issue for a decade.

If your new element isolates its children in a shadow DOM Archive , they do not inherit styles from the document. See Styling a Web Component Archive for this case.

Applying JavaScript behavior to new elements

All client-side JavaScript frameworks comes with mechanisms to activate JavaScript behavior on certain DOM elements. E.g. in Unpoly Archive uses compilers Archive for that purpose. Instead of using a framework mechanism you may use customElements.define() Archive to register your custom element's JavaScript behavior with the browser directly.

A big advantage of using the browser's customElements.define() is that your new element does not not need to be compiled or activated after insertion. Attaching a <my-element> to the document will automatically activate the registered behavior. This decouples your custom element from a particular JavaScript framework.

Here is an example:

class MyElement extends HTMLElement { connectedCallback() { // the element was added to the DOM } disconnectedCallback() { // the element was removed from the DOM } attributeChangedCallback(attribute, oldValue, newValue) { // the given attribute was changed } foo() { // a custom method } } customElements.define('my-element', MyElement)

Note that this class automatically describes the JavaScript API for your new element. The DOM node objects are their own JavaScript representation:

let newElement = new MyElement() document.body.appendChild(newElement) let queriedElement = document.querySelector('my-element') console.log(newElement === queriedElement) // true

Transpiling custom elements

Note that custom element classes must not be transpiled down to ES5 prototypes. You must send native ES6 classes to the browser. All browsers except IE11 have been supporting ES6 classes natively your years, so you might want to stop dumbing down your ES6 classes anyway.

Growing Rails Applications in Practice
Check out our new e-book:
Learn to structure large Ruby on Rails codebases with the tools you already know and love.

Owner of this card:

Henning Koch
Last edit:
over 2 years ago
by Besprechungs-PC
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Henning Koch to makandra dev
This website uses short-lived cookies to improve usability.
Accept or learn more