The next big thing on the web – custom HTML elements
If you are either a HTML component
vendor or ever wanted to use someone else's HTML module, you already
faces the same issue: components may not work together and even if
they do, they put a lot of noise in your pure HTML structure. This is
going to change very soon.
Large component vendors like Kendo or
Telerik are creating amazing HTML components that are, in theory,
just plug and play: whatever framework you are working with it should
be really easy to use those enhanced modules. However, even if they
work as they are intended to, they change and litter the HTML DOM so
any kind of debugging can be a bit of a pain.
Noisy HTML
The problem is that even if we start
with a nice and clean HTML code that looks like this:
<select id="size">
<option>S - 6
3/4"</option>
<option>M - 7
1/4"</option>
<option>L - 7
1/8"</option>
<option>XL - 7
5/8"</option>
</select>
the frameworks will turn this into a
lot of different divs and spans to be able to apply the nice visuals
on it. However, this will create unexpected nodes and structures in
your HTML code which may or may not display correctly after applying
it. The above will be replaced to this during runtime (some
attributes are removed for readability):
<span class="k-widget
k-dropdown k-header" unselectable="on" …>
<span unselectable="on"
class="k-dropdown-wrap k-state-default">
<span unselectable="on"
class="k-input">S - 6 3/4"</span>
<span unselectable="on"
class="k-select">
<span unselectable="on"
class="k-icon k-i-arrow-s">select</span>
</span>
</span>
<select id="size"
data-role="dropdownlist" style="display: none;">
<option value="S - 6 3/4""
selected="selected">S - 6 3/4"</option>
<option value="M - 7
1/4"">M - 7 1/4"</option>
<option value="L - 7
1/8"">L - 7 1/8"</option>
<option value="XL - 7
5/8"">XL - 7 5/8"</option>
</select>
</span>
Custom elements
Even though the custom HTML elementdefinition is still just a W3C draft and basically none of the browsers are natively supporting it (ChromeCanary and Firefox has a partial support), it's still by far the most
interesting upcoming HTML feature I've seen in a while.
With custom elements, you can define a
custom tag and add any HTML or Javascript rendering within it – the
browser will interpret that locally but won't be visible from the
outside. The only requirement is that the tag must contain a dash so
the name will never interfere with upcoming standard HTML tags (eg:
<hello> is not a valid custom tag but <adams-hello> is).
Defining custom elements
To define a custom tag, it has to be
declared in the following format:
<element name="adams-hello">
...
</element>
The rendering is a bit tricky though:
just because we have some internal content it will not be visible
from the outside. In the above case “...” will not be rendered
when someone uses the <adams-hello></adams-hello> tag. In
some cases it can be a bit confusing but it's for the greater good:
any internal structure can be pre-stored and used when necessary, no
need to fiddle with what and what's not visible: anything that we
have not explicitly rendered with Javascript is not visible.
Displaying time
To continue with our simple extension
above, let's add some simple rendering to it to display the current
time:
<element name="adams-hello"> <section> Hey, the time is: <time id='currentTime' /> </section> <footer>It will not be visible</footer> <script> var el; function tick(){ el.innerHTML = (new Date()).toString(); } if (this !== window) { var section = this.querySelector('section'); this.register({ prototype: { readyCallback: function() { var root = this.createShadowRoot(); root.innerHTML = section.innerHTML; el = root.querySelector("#currentTime"); setInterval(tick, 1000); } } }); } </script> </element>
The code is pretty straightforward,
however, there are couple of things that are good to know about:
- We need to register for the
readyCallback to do any kind of rendering. Without that the element
won't display anything.
- If we want to hide the internal
content of the DOM from debuggers we can create a shadow root. This
is not really supported yet so the root element can be simply this.
In that case the internal structure will appear in the DOM (note:
even if we use shadow root the browser knows about it and can display
it to the developer is we enable that option – it's not for
security, more for easier debugging).
Without shadow root - Chrome will display internal structure |
With shadow root - nice and clean markup |
You can grab the full source code fromhere.
Remember to run the samples on a local web server (like python -m
SimpleHTTPServer 8080) otherwise the HTML import won't work.
How can I use it today?
As basically none of the browsers
support is yet so the only solution is to use some kind of polyfill
framework to “bring the browser up to speed”. The only reasonable
implementation I've seen is Google's Polymer Project.
The framework is pretty well written so even Internet Explorer will
be able to work with most of the features mentioned above (note: for
me shadow root did not work). Give it a go and be prepared: this is
really an exciting feature in HTML!
Comments
Post a Comment