Posts Tagged ‘semantic web’

Shadow DOM

Tuesday, March 17th, 2015 | Programming

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.