MENU

BLOG

Grow Groupスタッフから様々な情報発信

ホームブログ【調査】次のweb標準!?まことしやかに囁かれ続けるWeb Componentsとは?

【調査】次のweb標準!?まことしやかに囁かれ続けるWeb Componentsとは?

テクノロジー,マークアップ / 2018.01.20/ ケイジャニストやまだ

こんにちは!最近はまったくケイジャン(Cajon、打楽器カホンのこと)に触れていない、
ゴリラ転生組のフロンドエンドエンジニア、ケイジャニストやまだです!

さて、この記事を読んでいらっしゃるということは
少なからず「Web Components」という言葉に興味を持たれた方が
ほとんどだと思います。

この「Web Components」、一体どんなものなんでしょうか。
現在も多くの試みが行われているこのWebComponentsについて、
概要を調べつつ、実際にサンプルを試してみましたのでその感想をばご紹介!

「コーディングが劇的に変わる!?」
「Web標準としてHTMLの部品(コンポーネント)化!?」
「これからWeb Componentsについてちょっと深堀りしてみようと思ってる」という方は
ぜひ読んでみてください〜♪

※今回は様々な記事を参考にさせていただきました。最後にご紹介させていただきますので、
この記事以外にも
是非みなさんで読んで調べて試してみてくださいー!!!!

特にそういうつもりもない方はGrowGroupのバックナンバーからお好きな記事を検索してね♪
バックナンバーはこちらから

 

Web Componentsの概要

さて、表題の通りずいぶん昔からのようですが(初出は2012年頃?)、
まことしやかに囁かれ続け、また開発途中である「Web Components」とは
一体何者なんでしょうか?
まずはどんなものなのか、概要の把握からまいりたいと思います!
公式のイントロダクションを読んでみましょう。

WEBCOMPONENTS.ORG(イントロダクションのページ)
https://www.webcomponents.org/introduction

Web Componentとはなんですか?

Webコンポーネントは、WebページとWebアプリケーションで使用する新しいカスタム、再利用、カプセル化されたHTMLタグを作成できるWebプラットフォームAPIのセットです。
カスタムコンポーネントとウィジェットは、Web Component標準をベースに構築され、最新のブラウザで動作し、HTMLで動作するJavaScriptライブラリやフレームワークで使用できます。
Webコンポーネントは、既存のWeb標準に基づいています。Webコンポーネントをサポートする機能は現在、HTMLおよびDOM仕様に追加されており、Web開発者がカプセル化されたスタイリングとカスタム動作を備えた新しい要素でHTMLを簡単に拡張できるようにします。

※引用文はGoogle翻訳を通しています。

一度使ってみると「なるほど!」となるのですが、
紹介文だけではなかなか想像できませんね。。。

もう少し突っ込んでみてみましょうってことで
仕様について調べてみます。

Web Componentsが持つ4つの仕様

Web Componentsとは以下4つの仕様を組み合わせたものを指します。

 

Custom Elements

独自のカスタム要素をユーザーが定義できる

 

Shadow DOM

Shadow DOMという要素を提供し、HTMLにスコープ(有効範囲のこと)を形成する

 

Templates

HTMLのテンプレート機能を利用できるようになる。

 

HTML imports

分割したHTMLファイルを読み込む

 

仕様としては以上です。
「これら組み合わせて、Webサイト、WebアプリケーションのUI群を
分離された部品(コンポーネント)という単位で、作ることができる」

ということを指します。

つまりWeb Componentとはそれ自体、ひとつのライブラリといったような類のものではなく、
上記4つの仕様を使って行う構築手法、概念を指すと言えるでしょう。

ではそのWeb Componentsを使って構築するとは一体どういうことなのでしょう?
実際に上記4つの仕様について試してみましょう!

4つの仕様を使って試してみる

さて、実際に試してみるといっても、どのように使うとわかりやすいでしょうね?
というわけで、ブラウザの対応状況を確認し、
Custom Elements -> Templates -> Shadow DOM -> HTML importsの順番に
webサイトの部品(ここではボタン)を作成していきましょう!

 

ブラウザの対応状況

まずブラウザが対応していないと何もできません。

なぜなら、Web ComponentsはWeb標準での策定を目指しており、
ブラウザ上で動作するものだからです(マジすごい)。
Web Componentsの実装について各ブラウザの対応状況はどんな感じなのでしょう?
記事執筆時点での公式サイトを覗いてみます。

WEBCOMPONENTS.ORG(トップページにあります)
https://www.webcomponents.org/


※上記画像は執筆時点でのキャプチャー画像です。

緑のチェックが付いている箇所に「STABLE」とあります。
これは安定しているという意味ですので、表を見ると
Google Chromeであれば安定して使えるということのようですね!
というわけでGoogle Chromeを使って試してまいりましょう!

※Polyfillと書かれているものは「未対応ブラウザ向け実装によって可能」という意味で、
Polyfillと呼ばれるライブラリを使うことで実装可能だよという意味です。
Polyfillについてはまた時間がある時にでも加筆いたします(泣)

 

Custom Element

カスタムHTMLを追加する

まず、Custom Elementを試してみます。htmlファイルを1つ用意しましょう。こいつをここからグリグリ動かしてみます。
以下の記述を書き込みます。

JavaScritpでCustom Elementを発行するソースです。貼り付けたら、
Google Chromeのdeveloperツールで見てみましょう。

画面にはなんも表示されてませんが、developerツールのElementsタブで確認してみると
先ほど追加した「sample-test」というDOMが追加されているのが確認できます!
scriptタグ内のdocument.registerElementがミソで、これで要素を登録しています。
登録した要素を次行のcreateElementで生成し、生成したDOMをbodyの最後に追加する。

という処理になりますが、このようにCustom Elementを使うとオリジナルのカスタムHTMLタグを発行できます!

★注意点(詳しくはこちら)

名前に必ず「-(ハイフン)」が必要
これはすでに用意されているHTMLタグと区別するため必要です。

同じタグを複数登録はできない
登録しようとすると、DOMException がスローされますのでできません。

閉じタグが必要
生成したカスタムHTMLタグは普通のdivと変わりませんので閉じタグが必要です。

 

document.registerElementの第二引数

また記述したスクリプトタグ内のコード、document.registerElement('sample-test')には第二引数で
プロトタイプを設定できます。
実は先ほどのコード、の上記部分は、実際このような記述になります。

document.register()を使うことで独自のHTML要素をブラウザが認識することができるようになるんですね。つまり、document.register()が使えないブラウザではCustom elementは使えません。
戻り値はコンストラクタで、sample-testのインスタンスを生成しています。

 

もともとある既存要素の拡張

Custom Elementを使えば、既存のhtmlタグを拡張することができます。
「どゆこと?」って感じですが、例えばbuttonタグが備えている機能に不満があったとして、
今までなら我慢していたところを、Custome Elementを使えばbuttonタグに機能を追加して
拡張することができます。

 

テキストを挿入しているだけなので、このままでは普通のbuttonと変わりませんが、
例えばクリックしたらダイアログを表示して値を吐き出すみたいな一連の処理もまとめてCustom Elementとして登録することが可能です。

また時間がある時にでも、機能を持たせて拡張してみたいと思います!(時短)

 

Templates

さきほどのCustom Elementは独自タグの追加や、既存要素の拡張といったものでした。

このTemplatesですが、使い方としてはテンプレート化したい箇所を
<template id="ID名"><template>で囲うだけです。それでテンプレートを作成することができます。
作成したテンプレートを使う時にはID名で呼び出して使います。

このtemplateタグで囲った箇所は、テンプレートとして定義され、
以降、呼び出さない限りtemplateタグで囲われた箇所は何もしません。

通常htmlに記述したものはロードされた時に、javascriptで何か処理を施さない限り、
即実行されます。

ですがtemplateタグで囲われた箇所はロードされても実行されません。
JavaScriptで何を書こうが、cssで何を書こうが、htmlで何を書こうが、
呼び出されない限り表示もされなければ、反応もありません。

一体どういうことなのか、先ほど書いたファイルを少し書き換えてアップロードしてみましょう。
templateタグの中にhtmlのbuttonに関するスタイルとhtmlソースを記入し、アップロードします。

いままでのhtmlなら「これはカスタムボタンです。」というテキストとともにスタイルがあたったボタンが表示されるはずですが、表示されません。

developerツールで確認してみても記述はあります。

ではこのtemplate、どのように呼び出して使うのでしょうか。
ここでShadow DOMの登場です。呼び出しはjavascriptを使って呼び出します。
Shadow DOMの仕組みを使って、Shadow Rootというノードを新たに追加し、
Shadow Rootに登録して呼び出すのです。

 

shadow DOM

それではShadow DOMについて簡単にご紹介いたします。

Shadow DOMとは簡単にいうと、作成したパーツのカプセル化を行えるものです。
ShadowDOMはShadow Rootという新たなノードをもつことができるようになり、
そこの中で形成されるDOMツリーに対しては外部からアクセスが遮断されるようになります(要するにShadow DOMでスコープを形成できる)。

外部からアクセスが遮断されるということは、既存のスタイルやJavaScriptでも
アクセスできないようになるので、影響されることがないということになります。

ちょっとやってみましょう!

先ほどのソースをちょっと書き換えます。

templateとして「スタイル付きのカスタムボタン」を定義。
body内にはtemplateの出力先として「test-shadowdom」という空のdiv要素を用意しました。

で、そのあとのscriptタグでShadow DOMの記述をしていきます。

結果、test-shadowdomのdivの中には「#shadow-root(open)」というテキストが現れました。

このopenというテキストですが、shadow-rootにはopenモードとclosedモードがあり、
openモードはshadow-rootにアクセス可能。closedでアクセス不可という、より強固なカプセル化を行えます(アクセスはjavascriptで行います)。

でもこれではカプセル化できてるのかできてないのか判然としません。

なので試しに「test-shadowdom」というdivにテキストを入れ、通常のコーディングのように
styleタグで色を指定してみましょう。

なんだか不思議ですね。「test-shadowdom」のdiv要素の中には「テキスト」というテキストがあり、すぐ上に追加したstyleタグの指定があるのに、まったく読み込まれていません。

そして、もともとあった要素も表示されません。

もともとあった表のテキストは存在しているのに、openになっている裏のShadow Rootが表示されています。もともとある要素は汚さずにそのまま上書きされているのです。

slot要素を使えば表の要素と裏の要素、Shadow Rootのハイブリッドが作成できますが、このお話もまたお時間のある時にでも(笑)

このようにShadow DOMの仕組みを使うと、要素を変更するか否かなど、細かい調整が可能になり、かつ、よくあるstyle上書かれちゃう事故なども起きないようになります。

ではここから本番。

さきほどのtemplateの項でテンプレートとして作成したボタンをこのtest-shadowdomというShadow DOMに追加してみます。

詳しくはscriptタグのコメントをご覧ください。
見事、templateとして作成したボタンのスタイルやbutton要素が
Shadow Rootに追加され、表示されました。

このようにtemplateとして雛形を作成し、それをShadow DOMの仕組みを利用して、
Shadow Rootに追加して表示することが可能になります。

完全にカプセル化されており、templateを要素に当て込むことでhtmlはシンプルに、
デザインとコンテンツの内容を完全に分離することができるようになるんです!

 

HTML imports

最後に4つ目の仕様をご紹介します。
通常HTMLファイルは例えばphpのincludeやrequireといった別のHTMLを読み込むといったことができないのですが、HTML imoportsを使うとそれができるようになります。

それでは先ほどのhtmlの中から、Shadow DOMの部分を別のhtmlファイルに移し、
いままでのhtmlファイルを空にしてそこへimportsしてみるということをやってみましょう。

無事読み込まれました!追記したのはlink属性です。
<link rel="import" href="template.html">

headの閉じタグすぐ前に追加した部分でtemplate.htmlを読み込んでいます。
template.htmlにはさきほどのShadow DOMの記述のみ記載されており、
それが実行されてこのように表示されています。

HTML importsとは「このパーツ(例えばボタンやSNSの表示だったり)、他のページでも使うんだよねー」という時に、そのコンポーネントだけ別のhtmlファイルに分けて記述することで、よりすっきりとしたわかりやすい構築ができるようになるメリットがあります。

ここまでやってみて感想とまとめ

ここまでWEBCOMPONENTSの解説をおこなってきましたが、
なかなかこれを使ったコーディングをイメージするのは従来の方法からはなかなか想像しにくいですよね。
例えばtwitterカードのデザインなんてものを想像してみましょう。
で、いろんなページにそれを設置する時、今までのコーディング手法なら、いちいちそのソースコードをそのhtmlに埋め込まなくてはなりません。

これは面倒ですよね。

ですがWebComponentsを使うと、
templateでtwitterカードを作成しておき、Shadow DOMで登録しておく
↓↓↓
HTML importsで各ページ読み込み(linkタグの1行で済む)

なんてこともできますし、
今回紹介しきれなかったShadowDOMの表要素と影のShadowRootのハイブリッド型を使うと、
さらに柔軟なコーディングが可能になります。

「いよいよ大きな変革が近づいているな」とヒリヒリしつつ、ちょっと楽しみな感じもしますね!

今回の記事ですが、まとめきれていない部分も多々ありますし、今後大幅に加筆修正する可能性もありますが、その際はぜひもう一度ご一読ください!

それでは今回調査に当たっていろんな文献、大変大変参考にさせていただきましたのでそちらをご紹介してむすびとさせていただきます。

ちゃお!!

html5html5experts様
https://html5experts.jp/1000ch/11142/
Eiji Kitamuraさんのブログ
https://blog.agektmr.com/2014/10/template-web-components.html
html5rocks様
https://www.html5rocks.com/ja/tutorials/webcomponents/imports/
https://www.html5rocks.com/ja/tutorials/webcomponents/template/
codegrid様
https://app.codegrid.net/entry/shadow-dom-concepts
技術評論社様
http://gihyo.jp/dev/column/newyear/2017/web-components-prospect

テクノロジー,マークアップ / 2018.01.20 / ケイジャニストやまだ

この記事を書いた人
フロントエンドエンジニア ケイジャニストやまだ

こんにちは。ゴリラから人間に転職しました。
フロントエンドエンジニア、コーダー、マークアップエンジニア受け持つあたりを主な守備範囲としながら、デザイン業務も兼任(最近めっきり)しております。コミックイラストも得意です。

一覧へ戻る