Ссылка на стандарт: www.w3.org/TR/2013/WD-shadow-dom-20130514/
Итак, что же такое shadow DOM:
Shadow DOM (или теневая модель документа) — часть документа, реализующая инкапсуляцию в DOM дереве. Она (теневая модель) является частью документа и встраивается непосредственно внутрь страницы.
Для упрощения отладки shadow DOM, в хроме можно включить отображение в веб-инспекторе (Settings — General — Show shadow DOM).
Надо заметить, что в стандарте реализуемая инкапсуляция называется функциональной, поскольку shadow DOM встраивается в документ и является одной из многих его частей, работающих «независимо» (более-менее независимо) друг от друга. Соответственно, при проектировании реализации, нужно было установить функциональные границы в дереве документа, чтобы как-то оперировать с множеством таких «независимых» фрагментов. Для решения проблемы инкапсуляции, и была введена новая абстракция — shadow DOM, позволяющая создавать несколько DOM деревьев в пределах одного родительского дерева и был разработан документ, описывающий ее.
Дочернее дерево размещается внутри некоторого элемента на странице. Функциональные границы между главным деревом документа и теневым называются shadow boundaries (теневые границы). Элемент, который размещает в себе теневое дерево, называется shadow host, а корень теневого дерево, соответственно, называется shadow root.
Во время рендеринга shadow tree занимает место содержимого shadow host (элемента).
Пример реализации в chromium:
<div id="shadow-host"></div>
var shadowHost = document.querySelector("#shadow-host"),
    shadowRoot = shadowHost.webkitCreateShadowRoot();
Insertion points
Для композиции потомков shadow host и shadow tree используются insertion points. Insertion points определяют местонахождение потомков shadow host в shadow tree. При рендеринге shadow tree потомки проецируются в это место. Механизм, определяющий какие потомки shadow host будут спроецированы в insertion point называется distribution.
Реализация:
<div id="shadow-host">
    <span>Hi shadow DOM!</span>
</div>
var shadowHost = document.querySelector("#shadow-host"),
    shadowRoot = shadowHost.webkitCreateShadowRoot(),
    content = document.createElement("content");
content.select = "span"; // выбираем все спаны из shadow host
shadowRoot.appendChild(content);
Псевдо-элемент ::distributed()
::distributed(selector) — функциональный псевдо-элемент принимающий относительный селектор в качестве аргумента. Он представляет отношение между insertion point в shadow tree и элементом, перенесенным в insertion point.
Реализация (chrome canary only):
<html>
    <head>
        <script>
            function onLoad() {
                var shadowHost = document.querySelector("#shadow-host"),
                    shadowRoot = shadowHost.webkitCreateShadowRoot();
                shadowRoot.innerHTML = document.querySelector("template").innerHTML;
            }
        </script>
    </head>
    <body onload="onLoad()">
        <div id="shadow-host">
            <span>Hi shadow DOM!</span>
        </div>
        <template>
              <style>
                content::-webkit-distributed(span) {
                  color: red !important;
                }
            </style>
            <content></content>
        </template>
    </body>
</html>
Один shadow host может вмещать в себя несколько shadow tree — они будут отображены в порядке их добавления. Такой набор деревьев называется shadow stack. Более «старый» shadow tree так же можно переносить в другой shadow tree посредством shadow insertion point.
<html>
    <head>
        <script>
            function onLoad() {
                var shadowHost = document.querySelector("#shadow-host"),
                    firstShadowRoot = shadowHost.webkitCreateShadowRoot(),
                    secondShadowRoot = shadowHost.webkitCreateShadowRoot();
                firstShadowRoot.innerHTML = document.querySelector("#template-1").innerHTML;
                secondShadowRoot.innerHTML = document.querySelector("#template-2").innerHTML;
            }
        </script>
    </head>
    <body onload="onLoad()">
        <div id="shadow-host">
            <span>Hi shadow DOM!</span>
        </div>
        <template id="template-1">
            <div>root 1</div>
        </template>
        <template id="template-2">
            <div>root 2</div>
            <shadow></shadow>
        </template>
    </body>
</html>
Reprojection (перепроецирование)
Перепроецирование это ситуация, при которой первое shadow tree уже имеет insertion point, а второй shadow tree имеет shadow insetion point, при этом контент, взятый из shadow host сначала проецируется в первом shadow tree, а затем во втором.
<html>
    <head>
        <script>
            function onLoad() {
                var shadowHost = document.querySelector("#shadow-host"),
                    firstShadowRoot = shadowHost.webkitCreateShadowRoot(),
                    secondShadowRoot = shadowHost.webkitCreateShadowRoot();
                firstShadowRoot.innerHTML = document.querySelector("#template-1").innerHTML;
                secondShadowRoot.innerHTML = document.querySelector("#template-2").innerHTML;
            }
        </script>
    </head>
    <body onload="onLoad()">
        <div id="shadow-host">
            <span>Hi shadow DOM!</span>
        </div>
        <template id="template-1">
            <div>root 1</div>
            <content select="span"></content>
        </template>
        <template id="template-2">
            <div>root 2</div>
            <shadow></shadow>
        </template>
    </body>
</html>
Псевдо-элементы (в контексте shadow DOM)
Автор стандарта пишет:
In certain situations, the author of a shadow tree may wish to designate one or more elements from that tree as a structural abstraction that provides additional information about the contents of the shadow tree.
В определенных ситуациях, автору shadow tree захочется назначить один или несколько элементов из shadow tree как стукртурную абстракцию, дающую дополнительную информацию о контенте shadow tree.
Что я понимаю как возможность использовать css селекторы вне shadow tree для доступа к элементам внутри него:
<html>
    <head>
        <script>
            function onLoad() {
                var shadowHost = document.querySelector("#shadow-host"),
                    shadowRoot = shadowHost.webkitCreateShadowRoot();
                shadowRoot.innerHTML = document.querySelector("template").innerHTML;
            }
        </script>
        <style>
            div::x-thumb {
                width: 10px;
                height: 10px;
                background: black;
            }
        </style>
    </head>
    <body onload="onLoad()">
        <div id="shadow-host"></div>
        <template>
            <div pseudo="x-thumb"></div>
        </template>
    </body>
</html>
События
Некоторые события пропускаются через shadow boundary, некоторые нет. Исключение составляют mutation events — они вообще не должны возникать в shadow tree и, соответственно, переходить через shadow boundary. При прохождении события через shadow boundary у него меняется event.target для поддержания инкапсуляции.
Вот интересный пример:
<html>
    <head>
        <script>
            function onLoad() {
                var shadowHost = document.querySelector("#shadow-host"),
                    shadowRoot = shadowHost.webkitCreateShadowRoot();
                shadowRoot.innerHTML = document.querySelector("template").innerHTML;
                shadowHost.addEventListener("mouseout", function(e) {
                    console.log("mouse out", e.target);
                });
            }
        </script>
        <style>
            #shadow-host {
                width: 100px;
                height: 100px;
                background: blue;
            }
            #outer-element {
                width: 100%;
                height: 20px;
                background: red;
            }
        </style>
    </head>
    <body onload="onLoad()">
        <div id="shadow-host">
            <div id="outer-element"></div>
        </div>
        <template>
            <div id="first-inner-element"></div>
            <div id="second-inner-element"></div>
            <content></content>
            <style>
                #first-inner-element {
                    width: 100px;
                    height: 20px;
                    background: green;
                    position: absolute;
                    top: 140px;
                }
                #second-inner-element {
                    width: 100px;
                    height: 20px;
                    background: black;
                    margin-bottom: 40px;
                }
            </style>
        </template>
    </body>
</html>
События спроецированного элемента всплывают в shadow host, как-будто он все еще находится непосредственно внутри shadow host. События first-inner-element не всплывают в shadow host, в отличие от second-inner-element, который абсолютно спозиционирован и вынесен за пределы shadow host (при этом event.target сменился).
Стили
Есть два метода, позволяющие манипулировать стилями shadow tree:
shadowRoot.resetStyleInheritance (false by default)
Сбрасывает наследование стилей для shadow tree (стили снаружи не применяются на shadow tree).
shadowRoot.applyAuthorStyles (false by default)
Применяет стили авторского (главного) документа.
<html>
    <head>
        <script>
            function onLoad() {
                var shadowHost = document.querySelector("#shadow-host"),
                    firstShadowRoot = shadowHost.webkitCreateShadowRoot();
                var secondShadowRoot = shadowHost.webkitCreateShadowRoot();
                secondShadowRoot.resetStyleInheritance = true;
                secondShadowRoot.applyAuthorStyles = true;
                firstShadowRoot.innerHTML = document.querySelector("#template-1").innerHTML;
                secondShadowRoot.innerHTML = document.querySelector("#template-2").innerHTML;
            }
        </script>
        <style>
            * {
                font-style: italic;
            }
        </style>
    </head>
    <body onload="onLoad()">
        <div id="shadow-host"></div>
        <template id="template-1">
            <style>
                * {
                    color: red;
                    font-weight: bold;
                }
            </style>
            <div>root 1</div>
        </template>
        <template id="template-2">
            <div>root 2</div>
            <shadow></shadow>
        </template>
    </body>
</html>
Итог
Можно сказать, что некоторой «инкапсуляции» для html не хватало. Это открывает большие возможности по созданию и шаблонизации различных, заранее подготовленных, виджетов на странице. Удивляет только отсутствие инкапсуляции JavaScript кода внутри виджетов, хотя мне казалось бы это довольно логичным.
На html5rocks есть демка shadow dom visualizer.

