Web Components
The old new era
Why?
- HTML is not verbose/"semantic" enough.
- There is no standard template system.
- There is no native encapsulation in browsers.
- There is no way to reuse existing HTML.
- Everything is a component, right?
- WE LOVE DECLARATIVE WEB!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!111111111one
Need for verbosity
- HTML is semantic only for end user.
- Developers want to be able to read their code.
- The era of "developer semantics".
Need for verbosity
Slider
Slide
vs
Slide
The beautifully beautiful slide!
Custom elements!
- Emerging standard for creating our own tags with semantics defined by us.
- Easy way to extend existing tags.
- Element's lifecycles.
- Live detection and enhancement of custom elements.
- Forced to use special name convention –
prefix-name
.
New custom element
class XSlider extends HTMLElement {}
window.customElements.define( 'x-slider', XSlider );
Extending existing element
class XButton extends HTMLButtonElement {}
window.customElements.define( 'x-button', XButton, { extends: 'button' } );
Native template system
- All existing template systems are string-based…
- …but DOM is a tree.
- How to utilize tree strenghts in templates?
- How to "switch off" some DOM subtrees (e.g. force them not to fetch images)?
template
template
contains inactive DOM subtree.
- Only inserting its content into some "live" site's element activates this subtree.
- What's more,
template
just reuses good old DocumentFragment
!
Working with template
const template = document.getElementById('image').content;
const img = template.querySelector( 'img' );
img.src = '/whatever.png';
img.alt = 'Just a placeholder.';
const parsed = document.importNode( template, true );
document.getElementById( 'image-container' ).appendChild( parsed );
Need for encapsulation
- HTML & CSS are leaky by default.
- Everything exists in a global scope.
- Everything is interacting with everything.
- There is no way to hide implementation details (
video
tag case).
- BEM is helping, but it's merely a convention.
The shadow boundary
It hides all implementation details.
All styles inside it are scoped.
Nothing is exposed to the Light DOM…
…so we are forced to create sane API.
Slots
- Slots are just placeholders.
- They wait for our content.
- It has a fancy name: "Nodes Distribution Algorithm".
HTML as a module
- We can reuse JS by modularizing it and using
script
tag.
- We can reuse CSS by putting it into the separate file.
- For the very long time the only way to do this with HTML was using an
iframe
.
HTML Imports
Just put your component into separate file:
And import it from your application's main file:
HTML Imports and ES Modules
- They are able to coexist…
- …but they are two very similar mechanisms, yet totally separate.
- Will HTML Imports become a subtype of ES Modules?
Standarization
- The main goal is to upstream every WC part into DOM and/or HTML standard…
- …which is already partly done.
Current browser support
- Can I Use lies!
- Only Chrome supports custom elements – but in their former version.
- Only Chrome supports Shadow DOM – in its former and current versions.
- Only Chrome is even willing to support HTML Imports…
- Still in flux – after 3 years.
- Better go React then!
- Polymer? Nope!
Common pitfalls
- Not everything is a component…
- …at least not a declarative one!
- Non-UI related logic inside custom tags? Bah!
2 pillars of architecture
- Totally independent UI, created with the use of web components.
- Business/application/non-UI logic, created with… PURE JS™.
- Events as the way to communicate between these two separate worlds.
- Just like in Zakas's idea.