Shadow DOM

If you’re using HTML5, you may well have come across templates, which are a way to create reusable code clocks. They can be used in conjunction with the Shadow DOM to create more semantic markup while still adding all the additional goodies in terms of additional CSS and HTML that you would like.

For example, lets say we want to put an email address in a fancy box into a website. The old horrible way of doing it is something like this:

<style>
    #email {
        background: url('images/at.png')
        center left no-repeat;
    }
    #email .label {
        font-size: small;
        text-transform: uppercase;
    }
</style>

<div id="email">
    <div class="outer">
        <div class="label">Email address</div>
        <div>
            john@example.com
        </div>
    </div>
</div>

Look at all that stuff we do not need. Semantically we do not need all those divs. Crawlers don’t need to seem them. Neither do accessibility tools. It would be way nicer if we could mark the page up like this:

<div id="email">john@example.com</div>

Turns out we can! All we need is a little help from templates and the shadow DOM. Lets work from that markup, and put the additional markup into a template tag.

<template id="emailTemplate">
    <style>
        #email {
            padding: 0.5em;
            background: url('images/at.png')
            center left no-repeat;
        }
        #email .label {
            font-size: small;
            text-transform: uppercase;
        }
    </style>
    
    <div id="email">
        <div class="outer">
            <div class="label">Email address</div>
            <div>
                <content></content>
            </div>
        </div>
    </div>
</template>

You will notice that this is basically the same code as we started out with, except now it is in a template tag, and instead of having the email address in there, there is a >content> tag. This acts as a placeholder that the contents of the div will be put into when we combine it all together.

Finally, we use some JavaScript to activate the shadow DOM.

<script>
    var shadow   = document.querySelector('#email').createShadowRoot();
    var template = document.querySelector('#emailTemplate');
    var clone    = document.importNode(template.content, true);
    shadow.appendChild(clone);
</script>

This allows us to add all the additional styling that we had initially, but thanks to the shadow DOM we are able to eliminate a lot of the additional markup in the page itself that made very little sense semantically.

Timeline

Newsletter

Don't have time to check my blog? Get a weekly email with all the new posts. This is my personal blog, so obviously it is 100% spam free.

Metadata

Tags: , , ,

This entry was posted on Tuesday, March 17th, 2015 at 11:12 am and is filed under Programming. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.