昨日の「スタイルガイドジェネレータ「Hologram」とShadow DOM」の続きです。課題として挙げていたbody要素に設定したスタイルがShadow DOMに継承される点などや、カスタム要素名の改善を検討してみました。
ちなみに、markup_example_template.html.erbのコードは、hologram init
で生成したものです。class名などはいずれ変えると思います。
body要素に設定したスタイルにまつわる課題の解決
まず、一点目の「スタイルガイドのテンプレートのCSSでbody要素に設定したスタイルはShadow DOMにも継承されること」について。おそらく問題になるのはfont-size
やline-height
あたりではないかと思います。ひとまずモジュール表示サンプル部分のフォントサイズがブラウザのデフォルトに戻っていれば良い気がするので、div.exampleOutput
にfont-size: 1rem;
を指定することで解決を図りました。(rem
に関しては、CSS Values and Units Module Level 3を参照。)
また、二点目の「スタイルガイドでドキュメント化しようとしているCSSのbody要素に設定したスタイルは反映されないこと」については、昨日も書いた:host
セレクタを使用することで解決を図りました。元々スタイルガイド生成時に、Gruntでドキュメントルートからのパスを相対パスに置換していたので、body
を:host
に置換する処理を追加しました。
カスタム要素名の改善
昨日のサンプルを見ていただくと、モジュールの表示サンプル部分がx-sg-output-example-[連番]
になっているのが分かると思います。これは連番にしないと次のように要素名が既に登録済みのエラーが出るためでした。
Uncaught NotSupportedError: Failed to execute 'registerElement' on 'Document': Registration failed for type 'x-sg-output-example'. A type with that name is already registered.
JavaScriptで処理の流れを変更したところ、カスタム要素名x-sg-output-example
でどのモジュールのサンプルも表示できるようになりました。
改善したJavaScript
先にdocument.registerElement("x-sg-output-example");
をして、forEach
内でvar customElement = document.createElement("x-sg-output-example");
をし、template要素内のコードを挿入するようにしました。
(function () {
"use strict";
var examples = document.querySelectorAll(".codeExample");
document.registerElement("x-sg-output-example");
Array.prototype.forEach.call(examples, function (example, index) {
var appendTarget = example.querySelector(".exampleOutput");
var customElement = document.createElement("x-sg-output-example");
var shadowRoot;
var template = example.querySelector(".renderedExampleTmpl");
var clone;
shadowRoot = customElement.createShadowRoot();
clone = document.importNode(template.content, true);
shadowRoot.appendChild(clone);
appendTarget.appendChild(customElement);
});
}());
改善したスタイルガイドのサンプル
GitHubに新しいサンプルをアップしました。スタイルガイドのフォントサイズは14px、モジュールの表示サンプル部分はフォントサイズがブラウザのデフォルトで、色が#333に設定されているのが確認できると思います。また、カスタム要素名から連番がなくなりました。
参考:webcomponents.jsの試用
Web ComponentsのPolyfillライブラリ「webcomponents.js」を試してみたところ、FirefoxやSafariでもカスタム要素を利用したモジュールの表示サンプル部分が表示されるようになりました。ただ、Shadow DOMはないのでCSSが干渉し合い、いまいちな結果となりました。